記事  TOPに戻る

AQMシリーズのI2C接続LCDキャラクタ・ディスプレイを使う(3)レベル変換とリピータ

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)

<神崎康宏>

◆AQMシリーズのI2C接続LCDキャラクタ・ディスプレイを使う

(1) 微妙なSCLクロック

(2) 拡張命令でコントラストの設定

(3) レベル変換とリピータ

(4) モデルの違い