C言語温湿度LCD表示サンプルプログラム
*サンプルプログラムです。RasPi5の環境の差で動かないこともありますので自己責任で
行ってください。
DHT11、LCDに関してネットを検索して爺さんが編集したもので爺さんのRasPi5で動作した
プログラムです
(I2C設定を enable にする)
デバッグのために 無駄な printf文が入っています
*wiringPiライブラリが必要
コンパイル、リンク:wiringPi.h wiringPiI2C.h wiringPiライブラリ
*コンパイル例(Cソースファイル名をtest.cの例)
gcc -Wall -c test.c-o test -lwiringPi
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
// LCD コマンド定義
#define LCD_CHR 1 // データモード
#define LCD_CMD 0 // コマンドモード
#define LCD_LINE_1 0x80 // 1行目
#define LCD_LINE_2 0xC0 // 2行目
#define LCD_BACKLIGHT 0x08 // バックライト ON
#define ENABLE 0b00000100 // Enable ビット
// LCD の I2C アドレス(モジュールによって異なる)
#define I2C_ADDR 0x27
#define MAX_TIMINGS 85
//#define DHT_PIN 8 // GPIO14
#define DHT_PIN 7 // GPIO4
int data[5] = {0, 0, 0, 0, 0};
char TempStr[40];
char HumiStr[40];
int fd; // I2C ファイルディスクリプタ
// 関数プロトタイプ
void lcd_init(void);
void lcd_byte(int bits, int mode);
void lcd_toggle_enable(int bits);
void lcd_loc(int line);
void lcd_text(const char *s);
int read_dht11_data() ;
/* ******************* */
int main(void) {
int res ;
char dispBuf[40];
int FlgLcdMark=0;
// wiringPi 初期化
if (wiringPiSetup() == -1) {
fprintf(stderr, "wiringPi の初期化に失敗しました\n");
return 1;
}
/* ********************** */
/* ----- LCD setup ----- */
// I2C デバイスオープン
fd = wiringPiI2CSetup(I2C_ADDR);
//printf("I2C device:%x\n",fd);
if (fd < 0) {
fprintf(stderr, "I2C デバイスが見つかりません (アドレス 0x%X)\n", I2C_ADDR);
return 1;
}
lcd_init(); // LCD 初期化
// 表示
lcd_loc(LCD_LINE_1);
lcd_text("Hello Raspberry");
lcd_loc(LCD_LINE_2);
lcd_text("Pi 5 LCD Test");
/* ********************** */
delay(2000); // time for LCD Opening Message
/* ----- DHT11 access ----- */
FlgLcdMark=0;
while (1) {
res=read_dht11_data();
if (res > 0) {
//printf("DHT Temp:%s °C : Humi:%s %%\n",TempStr,HumiStr);
// 表示
lcd_loc(LCD_LINE_1);
sprintf(dispBuf,"Temp: %s C %s ",TempStr,(FlgLcdMark==0 ? " " : "*"));
lcd_text(dispBuf);
lcd_loc(LCD_LINE_2);
sprintf(dispBuf,"Humi: %s %% %s ",HumiStr,(FlgLcdMark==0 ? "*" : ""));
lcd_text(dispBuf);
if (FlgLcdMark==0) FlgLcdMark=1;
else FlgLcdMark=0;
} else {
lcd_loc(LCD_LINE_1);
lcd_text("Temp:------------");
lcd_loc(LCD_LINE_2);
lcd_text("Humi:------------");
}
delay(2000); // データ取得間隔(2秒)
}
return 0;
}
// LCD 初期化
void lcd_init(void) {
lcd_byte(0x33, LCD_CMD); // 初期化シーケンス
lcd_byte(0x32, LCD_CMD);
lcd_byte(0x06, LCD_CMD); // カーソル移動方向
lcd_byte(0x0C, LCD_CMD); // ディスプレイ ON, カーソル OFF
lcd_byte(0x28, LCD_CMD); // 2行モード, 5x8フォント
lcd_byte(0x01, LCD_CMD); // 画面クリア
delay(5);
}
// LCD に1バイト送信
void lcd_byte(int bits, int mode) {
int bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT;
int bits_low = mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT;
wiringPiI2CWrite(fd, bits_high);
lcd_toggle_enable(bits_high);
wiringPiI2CWrite(fd, bits_low);
lcd_toggle_enable(bits_low);
}
// Enable パルス
void lcd_toggle_enable(int bits) {
delayMicroseconds(500);
wiringPiI2CWrite(fd, (bits | ENABLE));
delayMicroseconds(500);
wiringPiI2CWrite(fd, (bits & ~ENABLE));
delayMicroseconds(500);
}
// カーソル位置設定
void lcd_loc(int line) {
lcd_byte(line, LCD_CMD);
}
// 文字列表示
void lcd_text(const char *s) {
while (*s) lcd_byte(*s++, LCD_CHR);
}
/* DHT11温湿度センサー 1ビット通信 GPIOの入出力ピンを使用すること */
int read_dht11_data() {
int laststate = HIGH;
int counter = 0;
int i=0, j = 0;
int iBitChgCnt = 0; // for Debug printf...
int res = -1;
TempStr[0]=HumiStr[0]='\0';
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
pinMode(DHT_PIN, OUTPUT);
digitalWrite(DHT_PIN, LOW);
delay(18);
digitalWrite(DHT_PIN, HIGH);
delayMicroseconds(40);
pinMode(DHT_PIN, INPUT);
for (i = 0; i < MAX_TIMINGS; i++) {
counter = 0;
while (digitalRead(DHT_PIN) == laststate) {
counter++;
delayMicroseconds(1);
if (counter == 255) break;
}
laststate = digitalRead(DHT_PIN);
if (counter == 255) break;
if ((i >= 4) && (i % 2 == 0)) {
data[j / 8] <<= 1;
if (counter > 16) data[j / 8] |= 1;
j++;
iBitChgCnt=counter;
}
}
/* ***** for DEBUG *****
//printf("i=%d j=%d counter=%d laststate:%d iBitChgCnt:%d\n", i, j, counter,laststate,iBitChgCnt);
//printf("DATA0-4:%d %d %d %d %d == %d(%x) \n", data[0],data[1],data[2],data[3],data[4],((data[0] + data[1] + data[2] + data[3]) & 0xFF),(data[0] + data[1] + data[2] +data[3]));
* **********************/
if ((j >= 40) &&
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))) {
sprintf(HumiStr,"%d.%d", data[0], data[1]);
sprintf(TempStr,"%d.%d", data[2], data[3]);
res = 1;
} else {
HumiStr[0]='\0';
TempStr[0]='\0';
printf("Data not good, skip data4=%d sum=%d\n",data[4],((data[0] + data[1]+ data[2] + data[3]) & 0xFF));
res=-1;
}
return res;
}