販促品のLEDファンのデータを書き換えてみた

とあるカンファレンスのIntelブースで、販促品(?)のLEDつきファンを貰いました。
スイッチを入れるとファンが回転し、羽根に入っている7つのLEDが空中に文字を描き出すというもの。
もともとは求人広告として、「We're Hiring!」の文字とURLをアニメーション表示するようになっていました。


さて、このファンですが、よく見るとピンソケットが付いています。きっとマイコンか何かのプログラミング用だろうと思い、気になったので分解してみました。



なにやらピンソケットの近くにチップがあります。型番はT24C04A。検索してみると512 x 8bitのEEPROMでした。きっとこれにデータが入ってるのだろうと想像がつきます。


裏面見たらご親切にもシルクが入ってました。左からPAD, GND, CLK, VDD, DATAの5本。CLK, DATAはI²Cの信号ですから、ここからデータ書き換えできそうですね。



まずはArduinoを接続してデータを読み出してみます。
データシートを参考に、データを読み出すプログラムを書きます。I²C通信はArduinoならWireライブラリを使えば簡単。また、そのまんまEEROMを読み書きするサンプルスケッチがIDEに付属していますから、参考になるでしょう。
I²Cのアドレスは0x50。256byteから先を読むときはPADで1に切り替え、I2Cアドレスを0x51にするようです。*1


とりあえず256byte分を読み出した結果は

0x2, 0xD, 0x7F, 0x7F, 0x2, 0x7F, 0x7F, 0x41, 0x5A, 0x5A, 0x5A, 0x67, 0x70, 0x6F, 0x6F, 0x77, 
0x60, 0x7F, 0x7E, 0x20, 0x6E, 0x7F, 0x77, 0x6F, 0x6F, 0x77, 0x60, 0x7F, 0x7E, 0x20, 0x6E, 0x7F, 
0x70, 0x6F, 0x6F, 0x77, 0x0, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x73, 0x6A, 0x6A, 0x6A, 0x71, 0x77, 
0x6F, 0x6F, 0x77, 0x60, 0x7F, 0xF, 0x17, 0x7F, 0x7F, 0x73, 0x6A, 0x6A, 0x6A, 0x71, 0x1, 0x7E, 
0x71, 0x7E, 0x1, 0xB, 0x7D, 0x6A, 0x6A, 0x6A, 0x77, 0x71, 0x6E, 0x6E, 0x77, 0x0, 0x71, 0x6E, 
0x6E, 0x6E, 0x71, 0x7F, 0x21, 0x6E, 0x7E, 0x7D, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x41, 0x5A, 0x5A, 
0x5A, 0x67, 0x77, 0x6F, 0x6F, 0x77, 0x60, 0x71, 0x6E, 0x6E, 0x6E, 0x71, 0x7F, 0x7F, 0x7C, 0x7C, 
0x7F, 0x7F, 0x7E, 0x0, 0x5E, 0x7F, 0x7F, 0x41, 0x3E, 0x3E, 0x41, 0x7F, 0x3E, 0x0, 0x3E, 0x7F, 
0x7E, 0x7E, 0x7E, 0x7E, 0x0, 0xA, 0x7E, 0x7E, 0x7E, 0x7E, 0x0, 0x41, 0x3E, 0x3E, 0x3E, 0x41, 
0x41, 0x3E, 0x3E, 0x3E, 0x41, 0x4F, 0x37, 0x37, 0x37, 0x0, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x39, 
0x36, 0x36, 0x36, 0x4E, 0x0, 0x5F, 0x67, 0x5F, 0x0, 0x7E, 0x7E, 0x7E, 0x7E, 0x0, 0x40, 0x37, 
0x37, 0x37, 0x40, 0x4F, 0x37, 0x37, 0x37, 0x0, 0x9, 0x39, 0x36, 0x36, 0x36, 0x4E, 0x40, 0x37, 
0x37, 0x37, 0x40, 0x50, 0x35, 0x36, 0x3E, 0x41, 0x3E, 0x36, 0x36, 0x36, 0x0, 0x7, 0x79, 0x7E, 
0x79, 0x7, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x39, 0x36, 0x36, 0x36, 0x4E, 0x40, 0x37, 0x37, 0x37, 
0x40, 0x7E, 0x7E, 0x7E, 0x7E, 0x0, 0xE, 0x49, 0x36, 0x36, 0x36, 0x5D, 0x7F, 0x7E, 0x0, 0x5E, 
0x7F, 0x7F, 0x41, 0x3E, 0x3E, 0x41, 0x4E, 0x36, 0x3A, 0x3C, 0x5E, 0x7F, 0x71, 0x72, 0x7F, 0x7F, 

となっていました。データを眺めてみると、8bit目が全部0で、7つのLEDのそれぞれが0〜6bit目に対応していそうだなあと気づきます。


適当に可視化してみたのがこちら
最初の1byteは、恐らく2画面を切り替えて表示という意味。その後は1byteで文字数が来て、1文字あたり5byteでビットパターンが続いています。いろいろ試してみた結果、0-6bit目がそれぞれのLEDに対応、0だったらLED点灯、1だったらLED消灯と判明しました。なんか後ろの方に使われてないデータが残ってますが、デフォルトのデータかテストパターンか何かかな、きっと。


さて、仕様が分かったら、今度は適当にデータを書き換えてみます。
"HAPPY HACKING!"、"by NeoCat"の二つのパターンを作成し、上記のフォーマットでバイナリにしたデータがこちら。これをArudinoのプログラムに埋め込んで、EEPROMに書き込みます。


そしてファンを回してみると…*2


結論:リバースエンジニアリング楽しい。*3

*1:最初アドレスを勘違いしていて、なんで全く反応がないんだ〜!?とハマっていました。

*2:振動でファンがだんだんずれていってるけどご愛嬌。

*3:というほど大げさなものでもないですが。