今回は、LCDディスプレイLCD1601と温度・湿度計DHT11を使用して、室温と湿度を定期的にディスプレイに表示するプログラムを作成したいと思う。
#include <lcd.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#define MAXTIMINGS 85
#define DHTPIN 29
int dht11_dat[5] = {0, 0, 0, 0, 0};
void read_dht11_dat(int clcd) {
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0, i;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
pinMode(DHTPIN, OUTPUT);
digitalWrite(DHTPIN, LOW);
delay(18);
digitalWrite(DHTPIN, HIGH);
delayMicroseconds(40);
pinMode(DHTPIN, INPUT);
for (i = 0; i < MAXTIMINGS; i++) {
counter = 0;
while (digitalRead(DHTPIN) == laststate) {
counter++;
delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = digitalRead(DHTPIN);
if (counter == 255)
break;
if ((i >= 3) && (i % 2 == 0)) {
dht11_dat[j / 8] <<= 1;
if (counter > 28)
dht11_dat[j / 8] |= 1;
j++;
}
}
// 温度と湿度のデータが正しいとき
if ((j >= 40) && (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF))) {
// LCDのカーソルを1行目に設定
lcdPosition(clcd, 0, 0);
// 湿度を表示
lcdPrintf(clcd, "RH: %d.%d %% ", dht11_dat[0], dht11_dat[1]);
// LCDのカーソルを2行目に設定
lcdPosition(clcd, 0, 1);
// 温度を表示
lcdPrintf(clcd, "Temp: %d.%d%cC", dht11_dat[2], dht11_dat[3], 0xdf);
// 1秒停止
delay(10000);
}
// 正しくないとき
else {
// LCDのカーソルを1行目に設定
lcdPosition(clcd, 0, 0);
lcdPrintf(clcd, "Data not good");
// LCDのカーソルを2行目に設定
lcdPosition(clcd, 0, 1);
lcdPrintf(clcd, "skip");
// 2秒停止
delay(2000);
}
}
int main(void) {
int clcd;
wiringPiSetup();
clcd = lcdInit(2, 16, 4, 2, 3, 21, 22, 23, 24, 0, 0, 0, 0);
while (1) {
read_dht11_dat(clcd);
lcdClear(clcd);
lcdHome(clcd);
}
return 0;
}
※ プログラムは今までのものとほぼ同じものなので、必要なところのみ説明する。
46行目~温度と湿度が正しい場合は、LCDの1行目に湿度、2行目に温度の順番で表示する。
55行目のlcdPrintf()では、「℃」の表示ができないため、丸印(文字コードで直接指定し、%cで表示)とCを組み合わせて「℃」のに近い表示になるようにしている。
60行目以降では、正しく取得できなかったときの処理を記述しており、エラーメッセージが表示されるようになっている。
79行目と80行目で、LCDの表示をすべてクリアし、カーソルを行頭に戻している。