引き続きセンサー付きDSPラジオを作っていこうと思う。
構成はざっくり、こんな感じ
今回は液晶モジュールと、バックライト、LED回りの確認をしていきたい。
まず先に、LEDなのだが、CO2濃度に合わせて3色のLEDを個別に光らせようと思ったのだが、
こういうの↓が有るので、試してみたい。
RGBの3色LEDと制御回路が内蔵されたLEDなのである。
これを使えばLED1個でいろんな色で光らせることが出来るらしい。
CO2濃度を微妙な色で表現したいのである。
回路図ではこんな感じ。
この後で使う液晶も追加してある。
しかもこちらの記事によれば、arduinoのライブラリが有って、それを使えば簡単に光らせることが出来そうなのである。
まずライブラリのAdafruit NeoPixelをインストール
記事に従って簡単なコードを組んで動かしてみると、実に簡単に動作した。
ただ同じ数値で各色を光らせてみると、青の輝度が低く、緑が明るい。
とてもバランスが悪いのである。
他の製品でのデータだが以下のような感じだったので、これを参考に補正してみる。
赤…450mcd 緑…600mcd 青…200mcd
試してみて、だいたいどの色も同じような明るさになるように値を補正した。
試した動作確認用のコードはこちら↓
#include <Adafruit_NeoPixel.h>
// RGBLEDに出力するピン番号
#define RGBLED_OUTPIN 8
// Arduinoにぶら下がっているRGBLEDの個数
#define NUMRGBLED 1
#define R_max 112
#define R_mid 56
#define G_max 84
#define G_mid 42
#define B_max 252
#define B_mid 126
uint8_t Red[] = {R_max,R_mid,0 ,0 ,0 ,R_mid};
uint8_t Green[] = {0 ,G_mid,G_max,G_mid,0 ,0 };
uint8_t Blue[] = {0 ,0 ,0 ,B_mid,B_max,B_mid};
// RGBLEDのライブラリを生成する
//(色指定はRGBの並びで行う、LEDの速度は800KHzとする)
Adafruit_NeoPixel RGBLED = Adafruit_NeoPixel(NUMRGBLED, RGBLED_OUTPIN,
NEO_RGB + NEO_KHZ800);
void setup(){
RGBLED.begin() ; // RGBLEDのライブラリを初期化する
RGBLED.setBrightness(150) ; // 明るさの指定(0-255)を行う
RGBLED.setPixelColor(0, 0,150,0) ; // 初期値。(R=0,G=150,B=0)
RGBLED.show() ; // LEDにデータを送り出す
}
void loop(){
uint8_t R,G,B,i;
for (i = 0; i <= 5; i++) {
R=Red[i];
G=Green[i];
B=Blue[i];
RGBLED.setPixelColor(0, R,G,B) ; // 色設定
RGBLED.show() ; // LEDにデータを送り出す
delay(1500);
}
}
確認用コードで6色を順に光らせることが出来た。(写真はその内の4色のみ)
ちなみに、このLEDは電源は5V指定なのだが、結果的に3.3Vでも動作したので3.3Vとした。
電源を5Vにすると、より明るく光るような気がする。
(電源5V時でも、データ線が3.3Vで問題なく動作した)
次にLCDの動作確認。
基本的には、前回使ったAQM0802の16桁版なのでライブラリそのままに設定のみ変更で使えるはず。ちょっと動かしてみると、これはあっさり動作した。
今回は、LCDバックライトの明るさをPWMで調整するのである。
PWMと言っても、このように書くだけでなので、おじさんにも簡単に使える。
analogWrite(back_light,100); //LCDバックライトを中くらいにon
ここで、温湿度、CO2濃度を測ってLCDに表示させるプログラムを作ってみる。
バックライトと、LEDの明るさも照度に合わせて変わるように組んでみた。
例によってプログラミングが苦手なおじさんは、なかなか思ったように動かなくて大変苦労したのだが、なんとなく動くものが出来た。
CO2センサーに息を吹きかけて、状態を確認
CO2が600ppm以下の時、LEDは青
CO2が800ppm以下の時、LEDは青+緑の薄い青色
CO2が1100ppm以下の時、LEDは緑
CO2が1400ppm以下の時、LEDは緑+赤で黄色
CO2が1400ppm以上で、LEDは赤
周囲の明るさに応じて、LCDバックライトのPWMの比率が変化して、なんとなくバックライトの明るさが変化しているのも確認できた。
CO2センサーの値が低めのような気がするが、どうもエージングがかなり必要なようなので、しばらく様子を見てみる。
参考までに、この時のスケッチはこちら↓
#include <Wire.h>
#include <Adafruit_CCS811.h>
#include <I2CLiquidCrystal.h>
#include <Adafruit_NeoPixel.h>
#define DHT20_ADR 0x38
#define back_light 9 // port d9
#define illuminance 0 // port A0
// RGBLEDに出力するピン番号
#define RGBLED_OUTPIN 8 // port d8
// Arduinoにぶら下がっているRGBLEDの個数
#define NUMRGBLED 1
#define R_max 112
#define R_mid 56
#define G_max 84
#define G_mid 42
#define B_max 252
#define B_mid 126
uint8_t Red[] = {0 ,0 ,0 ,R_mid,R_max};
uint8_t Green[] = {0 ,G_mid,G_max,G_mid,0 };
uint8_t Blue[] = {B_max,B_mid,0 ,0 ,0 };
float humidity, temp;
int CO2_data, TVOC_data;
Adafruit_CCS811 ccs;
I2CLiquidCrystal lcd(40, false); //3.3V
// RGBLEDのライブラリを生成する
//(色指定はRGBの並びで行う、LEDの速度は800KHzとする)
Adafruit_NeoPixel RGBLED =
Adafruit_NeoPixel(NUMRGBLED, RGBLED_OUTPIN,NEO_RGB + NEO_KHZ800);
//
// set up
//
void setup() {
Wire.begin();
lcd.begin(16,2);
Serial.begin(115200);
RGBLED.begin() ; // RGBLEDのライブラリを初期化する
RGBLED.setBrightness(100) ; // 明るさの指定(0-255)を行う
RGBLED.setPixelColor(0, 0,G_max,0) ; // 初期値。LED Off
RGBLED.show() ; // LEDにデータを送り出す
analogWrite(back_light,100); //LCDバックライトを中くらいにon
lcd.setCursor(0,0);
lcd.print("Please wait");
ccs.begin(); //CCS811を起動
// センサーのウォームアップ
while (!ccs.available())
;
}
//
// Main
//
void loop() {
Temp_humidity_read(); //温湿度のセンサー読み取り
CO2_read(); //CO2,TVOCのセンサー読み取り
SET_LCD_environmental_data(); //LCDに表示
SET_LCD_Brightness(); //LCDバックライト調整
SET_LED_Color(); //CO2濃度に応じたLEDの色設定
delay(1000);
}
//
// 温湿度の読み取り
//
void Temp_humidity_read(){
uint8_t buf[8];
long a;
int flg;
Wire.beginTransmission(DHT20_ADR);
Wire.write(0xac);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission();
delay(100);
Wire.requestFrom(DHT20_ADR, 6);
for (uint8_t i = 0; i < 6; i++) buf[i] = Wire.read();
a = buf[1];
a <<= 8;
a |= buf[2];
a <<= 4;
a |= ((buf[3] >> 4) & 0x0f);
humidity = a / 10485.76;
a = (buf[3] & 0xf);
a <<= 8;
a |= buf[4];
a <<= 8;
a |= buf[5];
temp = a / 5242.88 - 50;
}
//
// CO2、TVOCを取得
//
void CO2_read(){
if (!ccs.readData()) {
CO2_data=ccs.geteCO2();
TVOC_data=ccs.getTVOC();
}
}
//
// LCDに温湿度 CO2 TVOCを表示
//
void SET_LCD_environmental_data(){
lcd.setCursor(0,0); //温湿度
lcd.print("Tmp:");
lcd.print(temp,1);
lcd.print(" Hum:");
lcd.print(humidity,0);
lcd.print("%");
lcd.setCursor(0,1); //表示クリア
lcd.print(" ");
lcd.setCursor(0,1); //CO2 TVOC
lcd.print("CO2:");
lcd.print(CO2_data);
lcd.print(" VOC:");
lcd.print(TVOC_data);
}
//
// LCDバックライト/カラーLEDの明るさ調整
//
void SET_LCD_Brightness(){
int64_t work;
uint8_t WB;
int il = analogRead(illuminance);
if (il > 775){ // 2.5V 以上?
WB = 255; // 全on
}
else if (il <= 186){ // 0.6VV以下?
WB = 26; // 10% duty
}
else{
work = il-186;
WB = work*204/589+26; // 10-90% duty
}
if (WB<26){WB=26;}
analogWrite(back_light,WB); // LCDバックライト
RGBLED.setBrightness(WB) ; // LED明るさの指定(0-255)を行う
Serial.println("illuminance=" + String(il));
Serial.println("duty=" + String(WB));
}
//
// CO2 濃度に合わせてLEDの色を変更
// 青⇒緑⇒黄⇒赤
//
void SET_LED_Color(){
uint8_t R,G,B,i;
if (CO2_data < 600){
i=0;
}
else if(CO2_data < 800){
i=1;
}
else if(CO2_data < 1100){
i=2;
}
else if(CO2_data < 1400){
i=3;
}
else{ //CO2 > 1400ppm
i=4;
}
R=Red[i];
G=Green[i];
B=Blue[i];
RGBLED.setPixelColor(0, R,G,B) ; // 色設定
RGBLED.show() ; // LEDにデータを送り出す
}
今のところ、それっぽく動作している。
CO2センサーの値は今ひとつ実態と合っていない感じだが・・・
なんかこのままでも良いような気がしてきた。
「ちゃんと最後まで作るんやで・・」