ここ3回で以下の記事を書いてきた。
今回は、これをまとめて、二酸化炭素、温度、湿度、気圧をまとめて表示できるようにしてみた。
今までは、次図の左のブレッドボードを使い、ジャンパー線で結んでいた。
プロトタイプではよくやる方法だが、どうしてもジャンパー線は外れやすい。
それで、今回は、中央のArduino用の拡張ボードを用いた。Arduinoのピン位置に合わせて穴が空いているので、これを用いると二階建て構造にして、ブレッドボードの代わりにこの拡張ボードに部品を取り付けることができるようになる。
ということで、ハンダ付けが必要になるのだが、ハンダ付けの個所もできるだけ減らしたい。とくに、配線は最小限にしたい。
それで用いたのが、右端の超薄型ユニバーサル基板である。よく見ると、ブレッドボードとプリントパターンがよく似ていることが分かるであろう。
とても薄く、カッターで簡単に切り分けることができ、穴を合わせてユニバーサル基板の上に置いて配線すると、とても便利であった。
3つの部品の配線であるが、電源系は当然共通になる。
それ以外の部品とArduinoを結ぶ信号線などは、異なるピンになるように最初から話を進めてきたので、そのまま3つの回路を拡張基板上に実現すれば動く。
そして組み立てて動かすと、こんな感じになった。
1行目に気温と湿度、2行目に二酸化炭素濃度と気圧を表示している。
Arduino, 拡張基板、センサーとディスプレイの3階建てになってしまった。
ディスプレイはとても見やすいのだが、ディスプレイの幅が拡張基板と同じだけあり、このディスプレイは大き過ぎた気がする。でも、安かったから我慢しよう。
さて、プログラムである。
プログラムも、いままで3回で示したものを寄せ集めただけのものなので、リストだけ載せ、説明は省略する。
// Room Environment
// CO2-MH-Z19
// Temperature, Humidity, Pressure
//
#include <LiquidCrystal.h>
#include <Wire.h>
#include <cactus_io_BME280_I2C.h>
#define pwmPin 7
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int prevVal = LOW;
long th, tl, h, l, ppm;
BME280_I2C bme(0x76); // I2C using address 0x76
void setup() {
Serial.begin(115200);
pinMode(pwmPin, INPUT);
lcd.begin(16, 2);
if (!bme.begin()) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
bme.setTempCal(-1);// Temp was reading high so subtract 1 degree
Serial.println("setup() end");
}
void loop() {
int ppm = readCO2(pwmPin);
bme.readSensor();
int mb = bme.getPressure_MB();
float tmp = bme.getTemperature_C();
float hum = bme.getHumidity();
Serial.print(convf(tmp)); Serial.print(" C ");
Serial.print(convf(hum)); Serial.print(" % ");
if( ppm < 1000 )
Serial.print(" ");
Serial.print(ppm);Serial.print("ppm ");
if( mb < 1000 )
Serial.print(" ");
Serial.print(mb); Serial.println("mb");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(convf(tmp)); lcd.print(" C ");
lcd.print(convf(hum)); lcd.print(" %");
lcd.setCursor(0, 1);
if( ppm < 1000 )
lcd.print(" ");
lcd.print(ppm); lcd.print("ppm ");
if( mb < 1000 )
lcd.print(" ");
lcd.print(mb); lcd.println("mb ");
// Add a 2 second delay.
delay(5000); //just here to slow down the output.
}
int readCO2(int pin) {
waituntil(pin,LOW);
waituntil(pin,HIGH);
long t0 = millis();
waituntil(pin,LOW);
long t1 = millis();
waituntil(pin,HIGH);
long t2 = millis();
long th = t1 - t0;
long tl = t2 - t1;
Serial.println(t0);
Serial.println(t1);
Serial.println(t2);
return (int)(5000 * (th - 2) / (th + tl - 4));
}
void waituntil( int pin, int hl ) {
while( digitalRead(pwmPin) != hl )
;
}
String convf( float val ) {
String str = String(val);
return str.substring(0,str.length()-1);
}