以前買い置きしていたI2CのROM 24C512 が手元にあり、これを使おうと思ったのだけど、データを書き込むのがめんどくさい。そのためにAruduinoとかPICとかで書き込んでも良いのだけど、PCで作ったデータファイルをROMに書き込むとなると、PCでデータ作って、書き込み用のプログラム作って、シリアルでArduinoに送り、Arduino側でシリアルとI2Cのプログラム作って・・・って、あー、もう、めんどくせー! となるので、なんか、良い方法はないかいな? と、考えてたら、
おー!ラズパイがあった!
ラズパイだと、I2Cもいけるし、ファイルも簡単に読み書きできる!
と、いうわけで、ラズベリーパイで24C512 を読み書きするための、ROM Reader/Writer を試してみた。
と、言っても、ハードウェアは、ブレッドボードにROMを置いて、ラズパイとジャンパー線4本でつなぐだけ。
I2Cのプルアップも、なぜか、必要なかった。・・・ラズパイ側でプルアップされているのかな???
あとは、Pythonでチョコチョコッと・・・。
使ったラズパイは、RasPi3で、OSはRaspbian with Pixcelってやつ。 比較的新しい方だと思う。I2Cのバスも”1”になってました。
古いやつだと、I2Cを使うのに、i2c-tools とか、smbus とかのPythonのライブラリをインストールする必要があったようだけど、僕の場合、何もしなくてもすでに入っていたみたい。ラズパイの設定でインターフェースのタブでI2Cを有効にしておけば、それだけで問題なく使えました。
このあたりは、検索するといろいろ詳しく説明されたサイト(I2C表示器が多いけど同じです。)があるので、省略するとして、こちらでは、いきなりROMをつないで読むところからです。
例えば、このあたりのサイトで、丁寧に説明されています。
Raspberry Pi で I2C を使用する準備 – 或る阿呆の記
ROMは、ATMELの24C512 です。ですので、他のROMで同じようにいくわけではないと思います。秋月電子通商のサイトで見ると、300円(http://akizukidenshi.com/catalog/g/gI-00561/)だけど、同様の24LC512って言うのもある。こちらは、価格もほぼ半額(http://akizukidenshi.com/catalog/g/gI-02524/)だし、同じように使えるのではないかと思うのだけど、現物を持っていないので、試しておらず、わからないので、あしからず・・・。
ラズパイとの接続は、以下のようにつないだ。
RaspberryPi 24C512 Pin 01 3V --- Pin 8 Pin 03 SDA --- Pin 5 Pin 05 SCL --- Pin 6 Pin 09 GND --- Pin 4
Frizingの図は、電源部分、勘違いしやすいので、V+とGND、間違わないように十分注意してね。 ・・・自己責任でよろしく!
上記以外のROMのピンはそのまま(float)ですが、デバイスアドレスを指定するような場合には、アドレスに応じてプルアップすると良いようです。7ピンは、ライトプロテクトなので、書き込みする場合には、そのままか、GNDに落とします。
接続できたら、ラズパイで確認します。
$ i2cdetect -y 1
と、やると、特にアドレスピンを設定していなければ、50 と表示されるはずです。
表示されなければ、ROMが認識されていないかもしれません。
あとは、以下のPythonプログラムを走らせるとROMが読めると思います。
プログラム中の"bus=smbus.SMBus(1)" のところ、もし、バスが0の場合には、添え字を"(0)"にしてくださいね。
ポイントは、24C512は、アドレスが、2バイトなので、smbusのライブラリでは、本来の使い方では、1バイトしか書けないみたいで、"write_i2c_block_data でデータ部分の最初のデータに2バイト目のアドレスを書くことによって、2バイト分のアドレスを指定しているみたいです。
#!/usr/bin/env python # -*- coding: UTF-8 -*- import smbus import sys bus = smbus.SMBus(1) addr = 0 adr1=0 adr2=0 startaddr = 0 endaddr = 0 def read_ROM(): l1=[] print('%4s : %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X ' %('Adr',0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) ) print('-'*54) for i in range(startaddr/256,endaddr/256+1): for j in range(16): for k in range(16): bus.write_i2c_block_data(addr,i,[16*j+k]) l1.append(bus.read_byte(addr)) print('%4X : %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ' %(256*i+16*j,l1[0],l1[1],l1[2],l1[3],l1[4],l1[5],l1[6],l1[7],l1[8],l1[9],l1[10],l1[11],l1[12],l1[13],l1[14],l1[15]) ) l1=[] if __name__ == '__main__': args = sys.argv if len(args) < 4 : print('usage: python {} <Device Address(HEX)> <Start Address(HEX)> <End Address(HEX)>'.format(__file__)) exit(0) addr = int(args[1],16) startaddr = int(args[2],16) endaddr = int(args[3],16) read_ROM()
使い方は、
このスクリプトのファイル名に続いて、デバイスアドレス(50) 読み込みの開始アドレス 読み込み終了アドレス となります。
例えば、"i2cromread.py" という名前で保存し、デバイスは、0x50、読み込み開始アドレスは、0x200、終了アドレス0x21F とすると、以下のようになります。 ただし、表示は、256バイトごとのブロックで表示されるので、要らない部分も表示されるかと思いますが、そこんとこ、よろしく・・・。
$ python i2cromread.py 50 200 21F
と、言うわけで、Writer編は、次回に・・・。