チープなI2Cデバイス

電子工作を始めた頃、I2C機能を持たないAVR ATTiny2313を、USIを用いてI2Cスレーブ機能を実装したデバイスを何点か製作した。

残念なことにArduinoでは問題なく動作したのだが、Raspberry Piでは動作しなかった。

この前、秋月で商品を購入したときにACM1602NIというI2C LCDをついでに購入していた。まだ使ってないのでネットで調べてみると、あまり評判の良いものではなく拙作のI2C LCDと同じようなトラブルを抱えるてるのを確認した。秋月のACM1602NIも、拙作のI2C LCD等もPICとAVRの違いはあれ半ソフトウェアでI2Cデバイスを実装してるようなのだ。

ネットで調べた皆さんのACM1602NIの対処方法は”I2Cのパケット毎にウェイトを入れる“というものだ。つまり問題点はチープなため通信速度に処理が追いついてないということなのだ。拙作のI2Cスレーブデバイスも同様な対処方法をとれば動くようになる可能性がある。

mbed LPC1114FN28でI2C LCDを駆動

mbedではACM1602NIを対処したソースがあったので、それに習い修正するこにとした。肝はパケットひとつ送信する毎にウェイトを入れるということだ。こんな感じだ。

int MyLCD::writeBytes(const char *data, int length, bool repeated)
{
    wait_us(i2c_bit_wait_us);
    _i2c->start();

    wait_us(i2c_bit_wait_us);
    if (_i2c->write(i2c_addr) != 1)
    {
        wait_us(i2c_bit_wait_us);
        _i2c->stop();
        return _i2cFAILURE;
    }

    for (int i = 0; i < length; i++)     
    {         
        wait_us(i2c_bit_wait_us);         
        if (_i2c->write(data[i]) != 1)
        {
            wait_us(i2c_bit_wait_us);
            _i2c->stop();
            return _i2cFAILURE;
        }
    }
    if (!repeated)
    {
        wait_us(i2c_bit_wait_us);
        _i2c->stop();
    }
    return _i2cSUCCESS;
}

この関数を用いてArduinoのライブラリィを移植して動作確認できた。それがこれである。

おさるはI2C LCDが動作してる証拠

おさるはI2C LCDが動作してる証拠

mbed LPC1114FN28でI2C 7SEGを駆動

次はI2C 7SEG(Charlieplexing 7SEG LED)だ。これもArduinoのライブラリィから移植した。

そしてこれが動作してるところだ。これは一応時間を表示してるつもり。

テストは時刻表示

テストは時刻表示

チープなI2Cデバイス

チープなI2Cデバイス秋月のACM1602NIや拙作I2C LCDはArduinoでは問題なく動く。これはArduinoのI2Cには相当ウェイトが入ってるのだろうと想像できる。
それにしても、AVR ATTiny2313で作ったI2Cスレーブデバイスは自作なのでチープなI2Cデバイスと呼んでもよいものだが、秋月のACM1602NIって一応商品なんだけどどうなんだろね。