RasPi  Desk

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;
}