ArduinoIDE2.3.2で、DHT20センサーから温度湿度データを取得し、SSD1306有機ディスプレイに表示するプログラムを作り動かしてみましたので解説します。
必要なパーツ
- SSD1306有機ディスプレイ
- DHT20センサー
- Arduino 今回は自作品互換機ですが UNO NANO 他
実行環境
- Arduino IDE2.3.2
- Windows11
ハードウェアの接続方法
接続図
今回の接続ではSCLとSDAラインにプルアップ抵抗をつけないと正常に動きませんでした、よって接続図は下記のようになります。
プルアップ抵抗は今回10KΩにしました。
今回も自作のアルディーノ互換機を使用しましたが、アルディーノUNO、NANOでも同じように接続すれば大丈夫です。
DHT20使い方
DHT 20の使いかたを簡単に説明します。
SSD1306の使いかたに関しては私のこちらのページでご確認ください。
まず電源投入後に初期チェックを行ないます。
DHT20に電力供給して0.1秒後、DH20に「0x71」を送信します。
DHT20から「0x18」が返信されたら初期チェック完了です。
下記スケッチ
Wire.beginTransmission(DHT_ADRS );
Wire.write( 0x71 );
Wire.endTransmission( false );
Wire.requestFrom(DHT_ADRS, 1 );
int sts = Wire.read();
if( (sts & 0x18) != 0x18 ) {
Serial.println("Sensor needs initialize.");
while(1) ;
}
次に測定開始コマンド3バイト(0xac)(0x33)(0x00)送信し、80mセカンド後に7バイトのデータを取得します。
// Trigger 測定開始コマンド
Wire.beginTransmission( DHT_ADRS );
Wire.write(0xac);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission();
// get data DHT
for (int k =0; k < 4 ;k++) {
delay(80);
Wire.requestFrom(DHT_ADRS, 7);
for( int i = 0; i < 7; i++ ) {
data[i] = Wire.read();
}
if( (data[0] & 0x80) == 0 ) break; // 正常に取得するとbreak正常でないとき今回最大4回取得しに行きます
}
最後にデータの物理変換をします。
また今回はCRCチェックは省きました。
// データ変換
float humidity = (double)((uint32_t)data[1] << 12 | (uint32_t)data[2 << 4] | data[3] >> 4) / 1048576 * 100;
float temperature = (double)((uint32_t)(data[3] & 0x0f) << 16 | (uint32_t)data[4] << 8 | data[5]) / 1048576 * 200 - 50;
テストプログラム1
テストプログラム1
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Adafruit_GFX.h> //Adarfuitのライブラリーを読み込む
#include <Adafruit_SSD1306.h> //AdarfuitのSSD1306用ライブラリーを読み込む
const int i2c_ADDRESS1306 = 0x3C; //ssd1306のI2Cのアドレス指定
Adafruit_SSD1306 display( 128, 64, &Wire); //ディスプレイ制御用のインスタンスを作成。
const int DHT_ADRS = 0x38;
byte data[7];
void setup() {
Wire.begin();
Serial.begin(9600);
// SSD1306 set
display.begin(SSD1306_SWITCHCAPVCC, i2c_ADDRESS1306 ); //ディスプレイを初期化。
display.clearDisplay(); //画面描写をクリアー
delay(1000);
// DHT20 set
Wire.beginTransmission(DHT_ADRS );
Wire.write( 0x71 );
Wire.endTransmission( false );
Wire.requestFrom(DHT_ADRS, 1 );
int sts = Wire.read();
if( (sts & 0x18) != 0x18 ) {
Serial.println("Sensor needs initialize.");
while(1) ;
}
}
void loop() {
// Trigger 測定開始コマンド
Wire.beginTransmission( DHT_ADRS );
Wire.write(0xac);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission();
// get data DHT
for (int k =0; k < 4 ;k++) {
delay(80);
Wire.requestFrom(DHT_ADRS, 7);
for( int i = 0; i < 7; i++ ) {
data[i] = Wire.read();
}
if( (data[0] & 0x80) == 0 ) break; // 正常に取得するとbreak正常でないとき今回最大4回取得しに行きます
}
// データ変換
float humidity = (double)((uint32_t)data[1] << 12 | (uint32_t)data[2 << 4] | data[3] >> 4) / 1048576 * 100;
float temperature = (double)((uint32_t)(data[3] & 0x0f) << 16 | (uint32_t)data[4] << 8 | data[5]) / 1048576 * 200 - 50;
display.clearDisplay(); //画面クリアー
display.setTextColor( WHITE, BLACK ); //文字を白、背景黒
display.setTextSize( 1 ); //文字サイズ
display.setCursor( 0, 0 ); //表示位置
display.print( " Hello World ");
display.setCursor( 0, 10 );
display.print("humidity: ");
display.print(humidity);
display.setCursor( 0, 20 );
display.print("temperature: ");
display.print(temperature);
display.display();
delay(1000);
}
テストプログラム2
内容は上と同じですが、こちらの方がデータ取得を関数にしましたので、プログラムの見通しが良くなると思います。
#include <Wire.h>
#include <Adafruit_GFX.h> //Adarfuitのライブラリーを読み込む
#include <Adafruit_SSD1306.h> //AdarfuitのSSD1306用ライブラリーを読み込む
const int i2c_ADDRESS1306 = 0x3C; //ssd1306のI2Cのアドレス指定
Adafruit_SSD1306 display( 128, 64, &Wire); //ディスプレイ制御用のインスタンスを作成。
int aa1;
const int DHT_ADRS = 0x38; //dht20アドレス
byte data[7];
float humidity; //変数グローバル宣言
float temperature; //変数グローバル宣言
void setup() {
Wire.begin();
Serial.begin(9600);
// SSD1306 set
display.begin(SSD1306_SWITCHCAPVCC, i2c_ADDRESS1306 ); //ディスプレイを初期化。
display.clearDisplay(); //画面描写をクリアー
delay(1000);
// DHT20 set
Wire.beginTransmission(DHT_ADRS );
Wire.write( 0x71 );
Wire.endTransmission( false );
Wire.requestFrom(DHT_ADRS, 1 );
int sts = Wire.read();
if( (sts & 0x18) != 0x18 ) {
Serial.println("Sensor needs initialize.");
while(1) ;
}
}
void loop() {
display.clearDisplay(); //画面クリア
display.setTextColor( WHITE, BLACK ); //文字を白、背景黒
display.setTextSize( 1 ); //文字サイズ
display.setCursor( 0, 0 ); //表示位置
display.print( " Hello World ");
data_dht20(); //データゲット
display.setCursor( 0, 10 );
display.print("humidity: ");
display.print(humidity);
display.setCursor( 0, 20 );
display.print("temperature: ");
display.print(temperature);
display.display(); //画面記画
delay(1000);
}
void data_dht20(){
// Trigger 測定開始コマンド
Wire.beginTransmission( DHT_ADRS );
Wire.write(0xac);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission();
// get data DHT
for (int k =0; k < 4 ;k++) {
delay(80);
Wire.requestFrom(DHT_ADRS, 7);
for( int i = 0; i < 7; i++ ) {
data[i] = Wire.read();
}
if( (data[0] & 0x80) == 0 ) break; // 正常に取得するとbreak正常でないとき今回最大4回取得しに行きます
}
// データ変換
humidity = (double)((uint32_t)data[1] << 12 | (uint32_t)data[2 << 4] | data[3] >> 4) / 1048576 * 100;
temperature = (double)((uint32_t)(data[3] & 0x0f) << 16 | (uint32_t)data[4] << 8 | data[5]) / 1048576 * 200 - 50;
}
表示画像です