「Arduino Mega 2560 LESSON:12 DHT11 温度湿度センサー」の版間の差分
編集の要約なし |
編集の要約なし |
||
| 132行目: | 132行目: | ||
} | } | ||
</code></pre></div><script></freescript> | </code></pre></div><script></freescript> | ||
ライブラリを使わないで自分なりのコードにすると以下のようになりました。カウント部のデバッグ値も出力しています。 | |||
<freescript></script><div class="hljs-wrap"><pre data-label="Arduino Code" class="pre-wrap"> | |||
<code class="cpp">const byte DHT_PIN = 2; | |||
void setup() { | |||
Serial.begin(9600); | |||
// 待機状態(プルアップ) | |||
pinMode(DHT_PIN, INPUT_PULLUP); | |||
delay(1000); | |||
} | |||
void loop() { | |||
byte data[5] = {0}; | |||
bool success = true; | |||
int errorBit = -1; | |||
int errorStep = 0; | |||
byte countlow[40] = {0}; | |||
byte counthigh[40] = {0}; | |||
// ここから通信開始処理 | |||
// ① Arduinoから通信開始信号を送信 | |||
pinMode(DHT_PIN, OUTPUT); | |||
digitalWrite(DHT_PIN, LOW); | |||
delay(20); // 20ms LOW | |||
// 開始信号のLOWを終了 | |||
pinMode(DHT_PIN, INPUT_PULLUP); | |||
// センサーが応答を始めるまでの待ち時間 | |||
delayMicroseconds(30); | |||
// 応答開始:LOWになるのを待つ | |||
if (!waitForLevel(LOW, 200)) { | |||
Serial.println("Error: No response"); | |||
delay(3000); | |||
return; | |||
} | |||
// 応答LOW(約80us)の終了を待つ | |||
if (!waitForLevel(HIGH, 200)) { | |||
Serial.println("Error: Response LOW"); | |||
delay(3000); | |||
return; | |||
} | |||
// 応答HIGH(約80us)の終了を待つ | |||
if (!waitForLevel(LOW, 200)) { | |||
Serial.println("Error: Response HIGH"); | |||
delay(3000); | |||
return; | |||
} | |||
// ③ 40ビットを読み取る | |||
noInterrupts(); | |||
for (int i = 0; i < 40; i++) { | |||
// LOWが続いた回数を数える | |||
unsigned int lowCount = countPulse(LOW); | |||
countlow[i] = lowCount; | |||
// HIGHが続いた回数を数える | |||
unsigned int highCount = countPulse(HIGH); | |||
counthigh[i] = highCount; | |||
if (lowCount == 0 || highCount == 0) { | |||
success = false; | |||
errorBit = i; | |||
errorStep = (lowCount == 0) ? 1 : 2; | |||
break; | |||
} | |||
// 受信データを左へ1ビットずらす | |||
data[i / 8] <<= 1; | |||
// HIGHの方が長ければ1 | |||
if (highCount > lowCount) { | |||
data[i / 8] |= 1; | |||
} | |||
} | |||
interrupts(); | |||
for(byte i = 0; i < 40; i++){ | |||
Serial.print(" "); | |||
Serial.print(countlow[i]); | |||
} | |||
Serial.println(" "); | |||
for(byte i = 0; i < 40; i++){ | |||
Serial.print(" "); | |||
Serial.print(counthigh[i]); | |||
} | |||
Serial.println(" "); | |||
if (!success) { | |||
Serial.print("Error: Reading failed, Bit="); | |||
Serial.print(errorBit); | |||
Serial.print(", Step="); | |||
Serial.println(errorStep); | |||
delay(3000); | |||
return; | |||
} | |||
// ④ 受信した40ビットを表示 | |||
Serial.print("Sample RAW Bits: "); | |||
for (int i = 0; i < 5; i++) { | |||
for (int bit = 7; bit >= 0; bit--) { | |||
Serial.print((data[i] >> bit) & 1); | |||
} | |||
if (i < 4) { | |||
Serial.print(" "); | |||
} | |||
} | |||
Serial.println(); | |||
// ⑤ チェックサムを検証 | |||
byte checksum = data[0] + data[1] + data[2] + data[3]; | |||
if (checksum == data[4]) { | |||
Serial.print("Sample OK: "); | |||
Serial.print(data[2]); | |||
Serial.print("."); | |||
Serial.print(data[3]); | |||
Serial.print(" deg. C, "); | |||
Serial.print(data[0]); | |||
Serial.println(" %"); | |||
} else { | |||
Serial.println("Checksum Error"); | |||
} | |||
delay(3000); | |||
} | |||
// 指定した電圧状態になるまで待つ | |||
// timeout はマイクロ秒単位 | |||
bool waitForLevel(byte level, unsigned long timeout) { | |||
unsigned long start = micros(); | |||
while (digitalRead(DHT_PIN) != level) { | |||
if (micros() - start >= timeout) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
unsigned int countPulse(byte level) { | |||
unsigned int count = 0; | |||
while (digitalRead(DHT_PIN) == level) { | |||
count++; | |||
if (count >= 1000) { | |||
return 0; | |||
} | |||
} | |||
return count; | |||
} | |||
</code></pre></div><script></freescript> | |||
<span style="color: darkred;"> 47/ 0/ 28/ 3/ 78</span> | |||
<span style="color: darkred;">0 0 1 0 1 1 1 1/0 0 0 0 0 0 0 0/0 0 0 1 1 1 0 0/0 0 0 0 0 0 1 1/0 1 0 0 1 1 1 0</span> | |||
7 7 7 6 6 7 6 7 6 6 6 7 7 6 6 6 6 6 7 7 6 7 6 6 6 7 7 6 6 6 6 7 6 6 7 6 6 7 6 7 | |||
2 2 9 3 9 9 9 9 3 3 2 2 2 3 3 3 3 2 2 9 9 9 3 3 2 2 2 3 3 3 9 9 3 9 2 3 9 9 9 2 | |||
Sample RAW Bits: 00101111 00000000 00011100 00000011 01001110 | |||
Sample OK: 28.3 deg. C, 47 % | |||
[[Arduino Mega 2560]]に戻る。 | [[Arduino Mega 2560]]に戻る。 | ||
2026年10月17日 (土) 00:22時点における版
概要
DHT11 温度湿度センサーを接続するレッスンです。
以下のようなコードです。
//www.elegoo.com
//2018.10.25
#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
/*
* Initialize the serial port.
*/
void setup( )
{
Serial.begin( 9600);
}
/*
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static bool measure_environment( float *temperature, float *humidity )
{
static unsigned long measurement_timestamp = millis( );
/* Measure once every four seconds. */
if( millis( ) - measurement_timestamp > 3000ul )
{
if( dht_sensor.measure( temperature, humidity ) == true )
{
dht_sensor.print_raw_data();
measurement_timestamp = millis( );
return( true );
}
}
return( false );
}
/*
* Main program loop.
*/
void loop( )
{
float temperature;
float humidity;
/* Measure temperature and humidity. If the functions returns
true, then a measurement is available. */
if( measure_environment( &temperature, &humidity ) == true )
{
Serial.print( "T = " );
Serial.print( temperature, 1 );
Serial.print( " deg. C, H = " );
Serial.print( humidity, 1 );
Serial.println( "%" );
}
}
ライブラリを使わないで自分なりのコードにすると以下のようになりました。カウント部のデバッグ値も出力しています。
const byte DHT_PIN = 2;
void setup() {
Serial.begin(9600);
// 待機状態(プルアップ)
pinMode(DHT_PIN, INPUT_PULLUP);
delay(1000);
}
void loop() {
byte data[5] = {0};
bool success = true;
int errorBit = -1;
int errorStep = 0;
byte countlow[40] = {0};
byte counthigh[40] = {0};
// ここから通信開始処理
// ① Arduinoから通信開始信号を送信
pinMode(DHT_PIN, OUTPUT);
digitalWrite(DHT_PIN, LOW);
delay(20); // 20ms LOW
// 開始信号のLOWを終了
pinMode(DHT_PIN, INPUT_PULLUP);
// センサーが応答を始めるまでの待ち時間
delayMicroseconds(30);
// 応答開始:LOWになるのを待つ
if (!waitForLevel(LOW, 200)) {
Serial.println("Error: No response");
delay(3000);
return;
}
// 応答LOW(約80us)の終了を待つ
if (!waitForLevel(HIGH, 200)) {
Serial.println("Error: Response LOW");
delay(3000);
return;
}
// 応答HIGH(約80us)の終了を待つ
if (!waitForLevel(LOW, 200)) {
Serial.println("Error: Response HIGH");
delay(3000);
return;
}
// ③ 40ビットを読み取る
noInterrupts();
for (int i = 0; i < 40; i++) {
// LOWが続いた回数を数える
unsigned int lowCount = countPulse(LOW);
countlow[i] = lowCount;
// HIGHが続いた回数を数える
unsigned int highCount = countPulse(HIGH);
counthigh[i] = highCount;
if (lowCount == 0 || highCount == 0) {
success = false;
errorBit = i;
errorStep = (lowCount == 0) ? 1 : 2;
break;
}
// 受信データを左へ1ビットずらす
data[i / 8] <<= 1;
// HIGHの方が長ければ1
if (highCount > lowCount) {
data[i / 8] |= 1;
}
}
interrupts();
for(byte i = 0; i < 40; i++){
Serial.print(" ");
Serial.print(countlow[i]);
}
Serial.println(" ");
for(byte i = 0; i < 40; i++){
Serial.print(" ");
Serial.print(counthigh[i]);
}
Serial.println(" ");
if (!success) {
Serial.print("Error: Reading failed, Bit=");
Serial.print(errorBit);
Serial.print(", Step=");
Serial.println(errorStep);
delay(3000);
return;
}
// ④ 受信した40ビットを表示
Serial.print("Sample RAW Bits: ");
for (int i = 0; i < 5; i++) {
for (int bit = 7; bit >= 0; bit--) {
Serial.print((data[i] >> bit) & 1);
}
if (i < 4) {
Serial.print(" ");
}
}
Serial.println();
// ⑤ チェックサムを検証
byte checksum = data[0] + data[1] + data[2] + data[3];
if (checksum == data[4]) {
Serial.print("Sample OK: ");
Serial.print(data[2]);
Serial.print(".");
Serial.print(data[3]);
Serial.print(" deg. C, ");
Serial.print(data[0]);
Serial.println(" %");
} else {
Serial.println("Checksum Error");
}
delay(3000);
}
// 指定した電圧状態になるまで待つ
// timeout はマイクロ秒単位
bool waitForLevel(byte level, unsigned long timeout) {
unsigned long start = micros();
while (digitalRead(DHT_PIN) != level) {
if (micros() - start >= timeout) {
return false;
}
}
return true;
}
unsigned int countPulse(byte level) {
unsigned int count = 0;
while (digitalRead(DHT_PIN) == level) {
count++;
if (count >= 1000) {
return 0;
}
}
return count;
}
47/ 0/ 28/ 3/ 78 0 0 1 0 1 1 1 1/0 0 0 0 0 0 0 0/0 0 0 1 1 1 0 0/0 0 0 0 0 0 1 1/0 1 0 0 1 1 1 0 7 7 7 6 6 7 6 7 6 6 6 7 7 6 6 6 6 6 7 7 6 7 6 6 6 7 7 6 6 6 6 7 6 6 7 6 6 7 6 7 2 2 9 3 9 9 9 9 3 3 2 2 2 3 3 3 3 2 2 9 9 9 3 3 2 2 2 3 3 3 9 9 3 9 2 3 9 9 9 2 Sample RAW Bits: 00101111 00000000 00011100 00000011 01001110 Sample OK: 28.3 deg. C, 47 %