2012年8月14日火曜日

Arduino と GR-SAKURA I2C編2 秋月I2C LCD


 前回の秋月I2C RTCに続いて、秋月のI2C LCDモジュールを試してみました。結論から言うと、今のところ動かせてません(残念・・・)。
 といっても、Arduinoでは何事も無くというか、あっさり動いてしまいました。


 スケッチはこんなの。
#define RXDUINO

#ifdef RXDUINO
#include <rxduino.h>
#else
#include <Arduino.h>
#endif

#include <Wire.h>

#define LCD_CMD    (0x00)
#define LCD_DATA    (0x80)
#define LCD_ADDRESS (0x50)
#define LCD_CMD_CLEAR    (0x01)
#define LCD_CMD_HOME    (0x03)

// 関数プロトタイプ宣言。
void LCD_init();
void LCD_write(uint8_t rs, uint8_t data);
void LCD_clear();
void LCD_setCursor(byte col, byte row);
void LCD_putc(uint8_t c);
void LCD_puts(char *str);


void setup()
{
    // シリアルポートを9600bpsで開始。
    Serial.begin(9600);
    // 受信バッファにデータが入るまで待機。
    while (Serial.available() == 0);
    Serial.println("Initializing...");
    // 一旦、受信バッファにデータがあれば、
    if (Serial.available() > 0) {
        // 読み込んで、廃棄。
        char c = Serial.read();
    }
    
    // Bus-MasterとしてI2Cを開始。
    Wire.begin();
    
    
    // LCDの初期化。
    LCD_init();
    
    // LCDクリア。
    LCD_clear();
    
    // メッセージ表示。
    LCD_setCursor(0, 0);
    LCD_puts("Hello!!");
    LCD_setCursor(5, 1);
    LCD_puts("I2C LCD!!");

}

void loop()
{
    
}

// LCD初期化。
void LCD_init()
{
    delay(15);
    LCD_write(LCD_CMD, 0x01);
    delay(10);
    LCD_write(LCD_CMD, 0x38);
    delay(5);
    LCD_write(LCD_CMD, 0x0f);
    delay(5);
    LCD_write(LCD_CMD, 0x06);
    delay(5);
}

// LCDへデータ書き込み。
void LCD_write(uint8_t rs, uint8_t data)
{
    int rtnValue;
    
    if (rs == 0x00 || rs == 0x80)
    {
        // 0x00 ならコマンドモード。0x80 ならデータモード。
        
        // LCDへの送信準備開始。
        Wire.beginTransmission(LCD_ADDRESS);
        // モード(RS)送信。
        Wire.write(rs);
        // データ送信。
        Wire.write(data);
        // キューの送信。通信終了。
        rtnValue = Wire.endTransmission();
        Serial.print(rtnValue);
    }
    else
    {
        // rsの指定が0x00,0x80以外ならなにもしない。
    }
}

void LCD_clear()
{
    LCD_write(LCD_CMD, LCD_CMD_CLEAR);
    delay(2);
    LCD_write(LCD_CMD, LCD_CMD_HOME);
    delay(2);
}

void LCD_setCursor(byte col, byte row)
{
    byte offset[] = {0x00, 0x40};
    
    if (row > 1)    row = 1;
    if (col > 16)    col = 16;
    
    LCD_write(LCD_CMD, 0x80 | (col + offset[row]));
}

void LCD_putc(uint8_t c)
{
    LCD_write(LCD_DATA, c);
}

void LCD_puts(char *str)
{
    int i;
    for (i = 0; i < 16; i++)
    {
        if (str[i] == 0x00)
        {
            break;
        }
        else
        {
            LCD_putc((unsigned int)str[i]);
        }
    }
}

 ArduinoではWire.endTransmissino()関数はすべて正常終了して0を返してくるのに、GR-SAKURAでは一つ目は成功して0を返すものの、2つ目以降が2(アドレス送信でNACK)を返してきます。試しにロジアナで見てみると


 2つ目以降はNACK(ACK応答なし)となっています。なんで?コマンドを変えたりして試すと、やっぱり、一つ目はうまくいくけど2つ目以降が失敗します。試しに強引に、一つ目送信後、LCD をブレッドボードから(通電状態のままだけど)引っこ抜いて挿しなおして(リセットして?)やると2つ目も受信します。まあ、その場合は3つ目が受信できないんですが。GR-SAKURA側なのかI2C LCD側なのか切り分けができていないのですが、Arduinoで出来てGR-SAKURAでできないとなるとGR-SAKURAを疑いたくなりますが、LCDをリセット(引っこ抜いて挿し直し)すると次を受信するということはLCD側に問題があるようにも見えます。電源電圧はSAKURAは3.3Vですが、元々このI2C LCDは3.3V(~5V)動作なので問題ないはず。
 さて、困った。原因を調べるのに少し時間がかかりそうなので、一旦保留かな?何か他のものを先に試そうかな。