2016年5月27日金曜日

Arduino空気質センサー+OLED



3年ぐらい前に作ったArduinoニオイセンサーの記事が未だにアクセスが多い。ありがたいことです。

でも、あっちの記事で使っているTGS2450は、いろいろタイミング制御やら電圧制限やらが厳しくて、気楽に使えません。

ので、先日ESP-WROOM-02でも使った空気質センサーを使って、作りなおしてみました。

なお、上の写真でグラフが急上昇しているのは、地味なので消臭スプレーを噴射してみたところです。人間の感じるいい匂いと空気質が必ずしも一致しない、という図です。でも、私が「ハー」ってやると確実に上昇します。ちなみに冬の早朝、部屋の空気を入れ替えた状態が一番低い値を示していました。

■使用部品■

Arduino nano(他のArduinoや互換機でも問題ないはず), 空気質センサー, OLED 0.96インチです。なお、安いところで買うと詳しい説明書いてないのですが、ピンの配列や対応する電源電圧などが異なる場合がありますので、十分ご注意ください。

なお、配線のためにミニブレッドボードとメス-オスのジャンプワイヤを使いました。

■配線■

Arduino nano/unoAirQuality Sensor0.96インチ OLED
A0AO(Analog out)
5VVCC
GNDGNDGND
A4SDA
A5SCK(SCL)
3v3VDD


■プログラム■

ESP-WROOM-02の記事では別のライブラリを使っていますが、ここではAdafruitさんのライブラリを使ってみました。大きなフォントが今ひとつなんですが、グラフィックスの命令が豊富なのでこのあとグラフ化も簡単でした。

コードのほとんどはOLEDへの表示です。

AirQualityセンサーからの値はアナログ値なのでanalogReadで読みます。読んだ値は64桁のバッファに格納して、これを用いてグラフを描画しています。

ソフト屋としては、「単純バッファで毎回シフトw」「グラフの描画で座標を二重に計算ww」など、ちょっと恥ずかしいのですが、わかりやすさを優先しました(真顔

あと、ドットを描画する命令がわからなかったので、drawLineで同じ座標を指定してます。ドキュメント読めば書いてあると思うんだけどw


// Arduino_AirQuality_SSD1306
// by koichi kurahashi 2016-05-27
//
// thanks:
// Adafruit SSD1306 library
// https://www.adafruit.com/products/326
//
//
// OLED
//
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//
// AirQuality Sensor
//
#define AirQuality 0
#define kMaxBuffer 64
int buffer[kMaxBuffer];
//
// Setup
//
void setup() {
Serial.begin(115200);
// OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(200);
display.clearDisplay();
display.display();
// buffer
for (int i = 0; i < kMaxBuffer; i++) {
buffer[i] = 0;
}
}
int countDown = 60;
#define kBottom 40
#define kTop 14
void loop() {
// read quality sensor
int value = analogRead(0);
for (int i = 0; i < kMaxBuffer-1; i++) {
buffer[i] = buffer[i+1];
}
buffer[kMaxBuffer-1] = value;
// display
char buf[41];
display.clearDisplay();
if (countDown > 0) {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(24, 56);
sprintf(buf, "warming up...%2d", countDown);
display.print(buf);
countDown--;
}
display.setTextSize(1);
display.setCursor(56, 0);
sprintf(buf, "Quality:%4d", value);
display.print(buf);
for (int i = 0; i < kMaxBuffer-1; i++) {
int i2 = i*2;
if (buffer[i] > 0) {
display.drawLine(i2, convert(buffer[i]), i2+2, convert(buffer[i+1]), WHITE);
}
display.drawLine(i2, kTop + kBottom, i2, kTop + kBottom, WHITE);
}
display.display();
delay(1000);
}
int convert(int inValue) {
float f = inValue;
return -f * kBottom / 1024.0 + kTop + kBottom;
}

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。