■TMP102で温度を測定する
Arduino UnoでI2C接続LCDキャラクタ・ディスプレイを接続し、コントラストの設定なども初期化の中でできました。今回はTMP102を接続して測定した温度をI2C接続LCDキャラクタ・ディスプレイに表示します。
接続にあたって次の点が課題となりました。
(1) 今回使用するArduino Unoは電源電圧5V、温度センサTMP102モジュールは電源電圧が3.3Vでそのまま接続できない。 (2) I2C接続LCDキャラクタのI2Cバスのドライブ能力が小さく10kΩ以上のプルアップ抵抗が必要。TMP102モジュールは1kΩのプルアップ抵抗を内蔵している。 (3) I2Cバス・リピータPCA9515は電圧レベルの変換機能はもたない。 (4) PCA9306のモジュールは1kΩのプルアップ抵抗を内蔵していて、そのままではI2C接続LCDキャラクタ・ディスプレイを接続できない |
●対応
3.3V駆動のTMP102を利用するために、PCA9306のモジュールのAE-PCA9306を次のように接続します。この図はモジュール内のプルアップ抵抗、AQM1602に必要な高抵抗のプルアップ抵抗が重複して記載されています。
このままだと、ArduinoからのデータをAQM1602が受信したときに、AQM1602のSDA出力のドライブ能力が小さいためデータを受信したことを示すACKを正しい信号として送出できません。そのためArduinoは通信データを受け取ることができません。
●内蔵プルアップ抵抗を外す
AQM1602がACKを正しくLOWレベルまで出力できるように、各モジュールの内蔵の1kΩのプルアップ抵抗を外します。外すのは、次の二つです。
- AE-PCA9306の3.3V側のSDAのプルアップ抵抗R3の1kΩ
- TMP102モジュールのSDAのプルアップ抵抗R1
SCLバスのプルアップ抵抗はそのままで問題ありません。SCL信号は原則サーバが出力するので、AQM1602のSCLは通常受信のみとなりドライブ能力は問題になりません。
●抵抗を外す
下図では、ほかの実験をするためにAE-PCA9306のモジュールの上部の四つ抵抗をすべて外してあります。AQM1602を5V電源で操作するために5V側のプルアップ抵抗もはずしてありますが、上図に示した回路では3.3V側のSCLのプルアップ抵抗を外すだけで済みます。
四つ並んだプルアップ抵抗の外側二つがSCLバスで内側がSDAバスに接続されています。抵抗の端子とバスの端子の間の抵抗を測ると、どの抵抗がどの端子に接続されているか確認できます。
はんだゴテでチップ抵抗の両端を同時に温めて、はんだが溶けたらチップ抵抗を取り外します。
●TMP102のモジュールの場合
次に示すように、GNDとSDAの表示の間にSDAバス用のプルアップ抵抗が取り付けられています。このチップ抵抗のみ取り外してあります。
AE-PCA9306とTMP102の3.3VのI2Cバスのプルアップ抵抗を外しテストしました。次に示すように1.5秒ごとにカウントアップした値と温度が表示されています。
1日以上に渡って異常なく動作しています。引き続き安定かどうか確認するため測定を続けます。
initlcd()は3.3V電源にAQM1602を接続したときの初期化プログラムで、5V電源に接続したときはinitlcd2()を使用します。
#include <Wire.h> #include <SPI.h> unsigned char lcd_address = 0x3E; byte CMD = 0x00; byte D_DATA = 0x40; int VCC = 8, GND = 9; int rdata; int n = 0; float tmp; int i2cwritecmd(byte cmd) { Wire.beginTransmission(lcd_address); Wire.write(0x00); Wire.write(cmd); return Wire.endTransmission(); }
int i2cwritedata(byte data) { Wire.beginTransmission(lcd_address); Wire.write(0x40); Wire.write(data); return Wire.endTransmission(); }
int i2cwritedsd(byte cltd, byte data) { Wire.beginTransmission(lcd_address); Wire.write(cltd); Wire.write(data); return Wire.endTransmission(); }
void lcdcu_set(int x, int y) { byte ca = (x + y * 0x40) | (0x80); i2cwritecmd(ca); } void lcdclear() { i2cwritecmd(0x01); delay(1); } void lcdhome() { i2cwritecmd(0x02); delay(1); } void dsift_l() { i2cwritecmd(0x1C); } void dsift_r() { i2cwritecmd(0x18); } void init_lcd() { delay(145); i2cwritecmd(0x38); delay(1); i2cwritecmd(0x39); delay(1); i2cwritecmd(0x14); delay(1); i2cwritecmd(0x73); delay(1); i2cwritecmd(0x56); delay(2); i2cwritecmd(0x6C); delay(300); i2cwritecmd(0x38); delay(1); i2cwritecmd(0x01); delay(2); i2cwritecmd(0x0C); delay(2); } void init_lcd2() { delay(145); i2cwritedsd(CMD, 0x38); delay(1); i2cwritedsd(CMD, 0x39); delay(1); i2cwritedsd(CMD, 0x14); delay(1); i2cwritedsd(CMD, 0x73); delay(1); i2cwritedsd(CMD, 0x51); delay(2); i2cwritedsd(CMD, 0x6C); delay(300); i2cwritedsd(CMD, 0x38); delay(1); i2cwritedsd(CMD, 0x01); delay(2); i2cwritedsd(CMD, 0x0C); delay(2); } void i2cprint( String pdata) { int n = pdata.length(); for (int i = 0; i < n; i = i + 1) { i2cwritedsd(D_DATA, pdata.charAt(i)); delay(1); } } float get_temp() { Wire.requestFrom(0x48, 2); while (Wire.available() < 2) {} int tmpin = (Wire.read() << 4); tmpin = tmpin + (Wire.read() >> 4); return 0.0625 * tmpin; } void setup() { Serial.begin(9600); Wire.begin(); Serial.println("start"); init_lcd(); Serial.println("start2"); } void loop() { lcdclear(); Serial.println("start3"); n = n + 1; i2cprint(String(n)); Serial.println("start4"); i2cprint(":"); //tmp=23.56; tmp=get_temp(); // Serial.print(get_temp()); Serial.println(n); i2cprint(String(tmp)); Serial.println(tmp); delay(1500); }
|
Arduino UnoとAQM1602、TMP102を利用したときは、この接続にした時安定に動作しています。
(2016/11/29 V1.0)
<神崎康宏>