激安マイコン基板で温度・湿度センサーの値を読み取ってみた
ストロベリーリナックスで購入できるMSP430 LaunchPadと中国製らしい温度・湿度センサーDHT22を使ってみた。
- http://strawberry-linux.com/catalog/items?code=18141
- http://strawberry-linux.com/catalog/items?code=18158
DHT22からセンサーの値を読み取るには1本の信号だけを使って行う。この1本線のプロトコルは、モールス信号みたいに信号のHigh期間の長さで0/1を表現するので、カウンタで長さを数えてやればいい。
開発環境のデバッガを走らせてみると、確かにデータを受信できている。(MSP430のスピードが遅いためか、for文で回すとうまく受信できなかったのでベタ書きするようにした)
一度に受信するデータは5バイトで、上から順に
- 湿度のHigh Byte
- 湿度のLow Byte
- 温度のHigh Byte
- 温度のLow Byte
- CheckSum(1〜4を足した値)
となっている。
ちなみに、このときの湿度と温度は、
- 湿度=0x01CE=462=46.2%
- 温度=0x00DE=222=22.2℃
というそれっぽい値だった。
もちろんCheckSumもOK。
//****************************************************************************** // MSP430x2xx Demo - Software Toggle P1.0 // // Description; Toggle P1.0 by xor'ing P1.0 inside of a software loop. // ACLK = n/a, MCLK = SMCLK = default DCO // // MSP430x2xx // ----------------- // /|\| XIN|- // | | | // --|RST XOUT|- // | | // | P1.0|-->LED // // A. Dannenberg // Texas Instruments, Inc // January 2006 // Built with IAR Embedded Workbench Version: 3.40A //****************************************************************************** #include "msp430.h" int main(void) { volatile unsigned char data[5]; volatile unsigned char sum; volatile unsigned int i; char cnt0, cnt1; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR = 0x01; // Set P1.0 to output direction // 0: input, 1: output P1OUT = 0x00; for (;;) { // output start signal to P1.4 P1DIR |= 0x10; // delay i = 1000; do { i--; } while (i != 0); P1DIR &= ~0x10; while ((P1IN & 0x10) != 0); // wait DHT response while ((P1IN & 0x10) == 0); // response while ((P1IN & 0x10) != 0); // sense #define RECV(d) \ cnt0 = 0; \ do { cnt0++; } while ((P1IN & 0x10) == 0); \ cnt1 = 0; \ do { cnt1++; } while ((P1IN & 0x10) != 0); \ data[d] = data[d] << 1; \ if (cnt0 < cnt1) { \ data[d] += 1; \ } // 1st byte RECV(0); RECV(0); RECV(0); RECV(0); RECV(0); RECV(0); RECV(0); RECV(0); // 2nd byte RECV(1); RECV(1); RECV(1); RECV(1); RECV(1); RECV(1); RECV(1); RECV(1); // 3rd byte RECV(2); RECV(2); RECV(2); RECV(2); RECV(2); RECV(2); RECV(2); RECV(2); // 4th byte RECV(3); RECV(3); RECV(3); RECV(3); RECV(3); RECV(3); RECV(3); RECV(3); // 5th byte RECV(4); RECV(4); RECV(4); RECV(4); RECV(4); RECV(4); RECV(4); RECV(4); // checksum sum = 0; sum += data[0]; sum += data[1]; sum += data[2]; sum += data[3]; // compare if (sum == data[4]) P1OUT |= 0x01; // OK else P1OUT &= ~0x00; // NG } }