迫真の氷結晶

初投稿です。

  • HOME
  • 自己紹介
  • 作品集
  • ポエム系

防犯ブザーを改造してサウンドロップを自作する Part1 - EEPROMに音声を書き込む

2020-09-24(更新: 2020-10-25)
  • #技術系
  • #電子工作

注意: この連載は未完結です。忙しいのでいつ更新するかわかりません。まぁそう焦んないで

はじめに

この連載では、オリジナルのサウンドを再生できる、サウンドロップ風おもちゃを低コストで自作したいという人に向けて、その作り方を解説します。

材料費だけなら400円くらいなのですが、電子工作のための道具一式を揃えるのに4,000円から10,000円くらいの初期費用が掛かります。

ICチップ(24FC512とATtiny85)に音声とプログラムとを書き込むために、小型コンピューター Raspberry Pi を使います。多分 Arduino ボードの方がこういう用途に向いている気がしますが、私がArduinoを持っていないので、(ややニッチながら、)Raspberry Pi でのやり方を紹介します。

そういうわけで、まずRaspberry Piを持っていない・使ったことがない(加えてArduinoも知らないよ)という人にはちょっとハードルが高めかなと思います。(Raspberry Piのセットアップ方法とかまでこの記事で解説するのはいや~キツいっす(素))

この記事の構成

この記事(Part 1)は以下のような構成となっています:

  1. サウンドロップの紹介・オリジナルサウンドロップ完成イメージの説明
  2. サウンドロップ自作に必要な道具一式の紹介
  3. 64KB以下のWAV形式音声ファイルを用意する方法の解説
  4. Raspberry Pi で EEPROM 24FC512 に音声データを書き込む方法の解説

導入

サウンドロップとは

サウンドロップというシリーズのおもちゃがあります。

サウンドロップはバンダイが販売しているカプセルトイで、ボタンを押すとキャラクターボイスなど音が鳴るキーホルダーのようなおもちゃです。

参考画像:

100均の防犯ブザーを改造すれば安上がり

オリジナルのサウンドロップを自作して自分の好きな音を再生したいというのは誰しも一度は思うところでしょう。

サウンドロップを1つ犠牲にしてもまあいいとは思いますが、ちょっともったいないし、それに、サウンドロップの中には専用基板を収めるわずかなスペースしかないので改造にはあまり向いていません。

そこで目をつけたのが100円ショップの防犯ブザーです。

an alarm by DAISO

上の画像はダイソーの防犯ブザーですが、実はこれすごくて、100円ちょっとで

  • ケース(一般に電子工作プロジェクトの中ではこれが一番用意するのが難しいと思う)
  • 1.5VのLR44電池3つ(直列で4.5Vを取り出して使う)
  • 圧電サウンダ(スピーカー。圧電ブザーとかピエゾブザーともいうみたいです)
  • トランス(他の種類の防犯ブザーには代わりに昇圧コイルが入っていることが多い)
  • タクトスイッチ(LEDを点灯させるために付いている小さい押しボタンスイッチ)

のすべてが一度に揃ってしまうという願ったり叶ったりな代物です。

圧電サウンダと基板との間に、別のパーツをくっつけられるスペースが少しだけ残っていて、ここに自前のICを設置することで好きな音を再生することができるかもしれない。

目標

ダイソーの防犯ブザーを改造してこんな感じに、ボタンを押したら音が鳴るようにしたいと思います。

構成

次の画像のように、EEPROMとAVRマイコンを使って圧電サウンダ(スピーカー)から音を出そうと思います。

an attiny85 connected with 24fc512 eeprom and piezo buzzer

EEPROMは音声データを保持し、AVRマイコンはEEPROMから音声データを読み込みながら圧電サウンダを駆動します。

そして、これら一式をどうにかして防犯ブザーの中にいい感じに取り付けることで自作サウンドロップを完成させます(それが一番難しいのですが)。

また、音声データのフォーマットについては、実はこれが初めての電子工作プロジェクトということもあり、今回は簡単に、非圧縮のリニアPCM(波形そのまんま)を採用したいと思います。(今度ADPCMを実装してファイルサイズを削減するつもりです。)

EEPROM, AVRマイコンへのデータ書き込みにはRaspberry Piを使うことにします。

用意する道具・材料

私が製作に使っている・使った物のリストです。

Raspberry PiはEEPROMとマイコンへの書き込みに使いますが、Arduinoボードを持っている方はそちらで代用できるかもしれません(というかそちらのほうがメジャー?)。ただしこの記事ではArduinoボードを使った書き込みについては取り扱いません。Arduinoボード持ってないので。

先に高価なものについてお知らせすると

  • Raspberry Piが2,000円から5,000円程度
  • はんだごてセットが合計3,000円程度
  • デジタルマルチメーターが1,000円程度

となっています。

ダイソーの防犯ブザー(必須)

an alarm by DAISO
今回改造するのはこの種類の防犯ブザーです。他の種類も見ましたが、サイズ、使われている部品の種類、改造のためのスペースなどを考慮した結果この種類のものが最も適していると考えました。

24FC512 (I2C EEPROM) (必須)

I2C方式で読み書きする8ピンのEEPROMです。再生する音声データを記録しておくために使います。

512というのは記録容量のことで、512Kbit(=64KByte)保存できることを意味しています。

24LCXXXというモデルもあります。こちらでもOKです。24FCXXXとの違いは、24LCXXXの方が読み書きの速度が遅いということですが、今回のプロジェクトにおいては十分な速度なので、入手しやすいものを選びましょう。

ATtiny85/ATtiny45/ATtiny25 (必須)

8ピンのAVRマイコンです。上記の外付けEEPROMと通信して音声データを読み出し、なおかつスピーカーを鳴らします。

85/45/25の中から好きなのを1つ用意すれば良いです(秋月電子通商にはATtiny85しか売ってませんが)。

85/45/25の大きな違いはプログラムメモリ(機械語命令を保持しておくフラッシュメモリ)のサイズがそれぞれ8KB/4KB/2KBであるということくらいみたいです。

Raspberry Pi 2 Model B (必須)

古いRaspberry Pi 2しか持っていなかったのでこう書いていますが、Raspberry Pi 3でも、ZERO WHでも、(たぶん)4でも、GPIOピンが使えるものならOKです。

  • Raspberry PiのGPIOピンを経由してEEPROMに音声データを書き込むのに使います。
  • Raspberry PiのGPIOピンを経由してATtiny85にプログラムを書き込むのに使います。

Raspberry Pi ZERO WH がGPIOピンヘッダ実装済みで2,000円弱なのでおすすめです。

Raspberry Pi ZERO Wにはピンヘッダが実装されていないので、自力でピンヘッダ/ピンソケットをはんだ付けする必要があります(その分Wの方が安いですが)。

OSはRaspbianであることを前提に話をします。

ブレッドボード, ジャンパーワイヤ(メス-オスとオス-オス) (必須)

  • Raspberry PiとICを接続するために使います。このときメス-オスのジャンパーワイヤが必要です。

  • ブレッドボード上での配線にオス-オスのジャンパーワイヤが必要です。

220Ω抵抗器×1 (必須)

[2020-10-25] 220Ωじゃ抵抗値が若干足りない疑惑ありますねぇ!もうちょっと検証が必要です…

マイコンからスピーカーに電流が流れすぎるのを防ぐために使います。

はんだごて、こて台、はんだ、はんだ吸い取り器/はんだ吸い取り線 (必須)

Amazonには2,000円前後ではんだごて、こて台、はんだ、はんだ吸い取り器、ピンセットを含んだ箱付きのセットがたくさん売ってるんですが(実際私が使ってるのもほぼそれなんですが)、箱付きのセットにはちょっと問題があります。

  • はんだ(糸はんだ)が太すぎる。細い精密はんだを買うべき。
  • こて台が軽すぎて危ない。こて台のスポンジが動いて使いづらい・危ない。

なので、もしセットを買っても、 はんだとこて台については別に買いましょう。

もはやセットを買うべきかバラバラに買うべきか悩ましいところですが、まあ、

はんだごてセット箱 + 精密はんだ + こて台

を買うのがいいのではないかなあと思います。

はんだごてセット箱:

精密はんだ:

こて台:

アロンアルファ(瞬間接着剤) (必須)

ICやトランスを物理的かつ立体的に固定するために使います。

プラスチック用のもののリンクを貼っていますが、私は一般用のアロンアルファを使いました。(ICパッケージに一般用の瞬間接着剤使っていいのか分からないのよね・・・)

ポリウレタン銅線 (必須)

ICと電源やスピーカーとを接続するのに使います。

はんだごてで溶かしたところだけ被覆がはげる便利な線材です。

他の種類の線材でもダメではないですが、被覆をむくのが面倒だったり、線同士が交差したときにショートしてしまうなどといった煩わしい問題を避けるためにポリウレタン銅線がおすすめです。

明確にポリウレタン被覆であるという表記はないものの、以下もポリウレタン銅線であるらしいので、より安い下の商品を買うのでもよさそうです。

ニッパー (必須)

ポリウレタン銅線やICの足をちょん切るのに使います。

↓こういうのです。100均で買いましょう。

デジタルマルチメーター(テスター)

電圧・電流・抵抗を調べる装置です。

接触不良やプログラムのミスがないか調べるときに使います。

ポリウレタン銅線の被覆がしっかりはがせていないと接触不良になりますが、見た目では分からないので、こういうのがないとちょっと怖いですよ。

プラスドライバー

防犯ブザーのフタを開けられるやつならOKです。たぶんおうちにあるやつでOKですが、100円で売ってる精密ドライバーセットを買えば間違いありません。

ラジオペンチ/ピンセット

はんだ付けの際にパーツをつまむのに使います。素手でつまんだらやけどします。ただしニッパーでも一応代用はできます(やりにくいけど)。

また、銅線を折り曲げたりするときも使えます。

基板・パーツの固定台

クリップ付きの腕が生えた固定台です。

はんだ付けの際に基板やパーツが動いてしまい、もう一本腕がほしいと思ったときにあると便利です。

が、無くてもぶっちゃけ気合でなんとかできます。それか、ミニ三脚にクリップを挟んでみたりと工夫次第で似たようなことはできます。

〈下準備〉 書き込む音声ファイルの用意

まずは防犯ブザーで再生したい音声を用意します。一般的なファイルフォーマット(mp3, aac, wavなど)なら何でも構いません。(Audacityで開ければよい)

しかし、今回使うEEPROMの容量が512Kbit(64KB)なので、当然ファイルサイズは64KB以下に抑えなければなりません。

非圧縮の状態で64KBに収めなければならないのでカツカツになるでしょう

ファイルサイズを小さくするには

チャンネル数を1(モノラル), ビット深度を8bitとすると、ファイルサイズは

( サンプリング周波数[Hz] × 再生時間[s] )[Byte]

で計算されます。

(圧縮アルゴリズムを適用すると半分くらいにできるんですが、それはまた今度)

サンプリング周波数が小さいほど、また、再生時間が短いほどファイルサイズは小さくなります。

ただ、サンプリング周波数はあまり積極的に下げたいものではありません。サンプリング周波数を下げると、その分高い周波数成分が失われていくので、下げれば下げるほどモゴモゴした音になっていきます。

64KBに収まるデータの、サンプリング周波数と再生時間の組の目安は以下の通りです。

  • サンプリング周波数 24kHz: 2.7秒
  • サンプリング周波数 16kHz: 4秒
  • サンプリング周波数 13.5kHz: 4.7秒
  • サンプリング周波数 8kHz: 8秒

再生する音にもよりますが、多分5秒くらいまでのデータが、許せる音質の限度だと思われます。

Audacityで音声ファイルのサイズを削減しておこう

フリーの音声編集ソフトとして名高いAudacity先輩をダウンロードしておけば間違いない。WindowsでもMacでもLinuxでも動きます。

Audacity と検索してAudacityをインストールしたらまたこの記事に戻ってきてください(手抜き)

  1. 再生したい音源をAudacityで開きます。

  2. トラック>ミックス>ステレオからモノラルへ を選びます

  3. モノラル(1チャンネル)になりました

  4. プロジェクトのサンプリング周波数をいじります

  5. ファイル>書き出し>音声の書き出し を選びます

  6. ファイルの種類は「その他の非圧縮ファイル」、ヘッダは「WAV(Microsoft)」、エンコーディングは「Unsigned 8-bit PCM」として「保存」を押します

  7. メタデータタグのダイアログが出たら「消去」を押してから「保存」を押します

  8. 書き出されたwavファイルが64KBを超えていないことを確認します。

64KBを超えてしまった場合は再生する箇所を削ったり、サンプリング周波数を下げたりしてください。

作った音声データをRaspberry Piに転送しておく

Raspberry PiにEEPROMへの書き込みを担わせるので、作った音声データを何らかの方法でRaspberry Piに転送しておいてください。

scpコマンドを使うとかブラウザ/クラウド経由とか。そのほかだと、Raspberry PiにAudacityをインストールしてそこで作業してしまうというのも考えられなくはないですね。

〈本題〉 EEPROMに音声データを書き込む

いよいよここからが本題です。

Raspberry Pi のGPIOピン(SDAピン, SCKピン)を使って、用意しておいた音声データをEEPROMに書き込みたいと思います。

さて、このEEPROMという8つ足が生えた黒い物体はどうやって使うんでしょうか。

書き込み操作に入る前に少しI2Cと24FC512についての説明を挟むことにします。早く進みたい方は下の方の「24FC512とRaspberry Piを接続」のセクションまで飛ばしても平気です。

I2C EEPROM 24FC512の使い方

まずI2Cとは

まず簡単にI2Cとは何かという話をすると、クロック線(SCL)とデータ線(SDA)の2本のみを使って1bitずつ通信する通信方式です。

I2CはInter-Integrated Circuitの略で、正しい読み方は I-squared-C (アイ・スクエアード・シー) らしいです。IICと書いたり、また、上付き文字が表示できない場合は I2C と書いたりもします。

I2Cではマスターとスレーブは明確に区別され、常にマスターとなるデバイスが制御の主導権を握り、クロック信号を上げ下げします。

今回、24FC512はスレーブで、ATtiny85はマスターです。

いちばん詳しい使い方はデータシートに載ってる

24FC512の使い方を知るために、まずは24FC512のデータシートを読みます。幸いなことに秋月電子通商のページで日本語データシートが提供されています。ありがてえ。

データシートによると次のようなピン配置になっています。

24fc512-pin.png
  • VCC: 電源の陽(+)極を接続します。
  • VSS: 電源の陰(-)極を接続します。
  • A0, A1, A2: チップセレクトを設定するための端子です。
  • WP: 書き込みプロテクトです。
  • SCL: Serial CLock. I2Cで定められているクロック信号線です。
  • SDA: Serial DAta. I2Cで定められているデータ信号線です。

チップセレクトについて

24fc512-chip-select.png

24FC512は、バスに流れてきた 1 0 1 0 A2 A1 A0 x という8bitのビット列(コントロールバイト)を見て制御が自分宛てかそうでないか判断します。

データシートによると24FC512においてコントロールバイトの上位4bitは1010で固定されており、これをコントロールコードと呼んでいます。そして次の3bitのA2, A1, A0をチップセレクトビットと呼んでいます。

24FC512のA2ピン, A1ピン, A0ピンに電圧を印加したりしなかったりすることでデバイスのへのチップセレクトビットの割り当てを変更することができます。

簡単に言えば24FC512は自分の番号に反応するように作られていて、その番号というのを、A2-A0ピンをいじって、 000 から 111 までの間で好きに割り当てられるということです。

ピンに電圧を印加してHIGHの状態にすると1、ピンをGND(0V)に接続してLOWの状態にすると0が入力されます(こういうH=1,L=0の世界を正論理と言います)

たとえば、

  • A2 = 1(HIGH)
  • A1 = 1(HIGH)
  • A0 = 0(LOW)

と設定してやると、このデバイスは1010110Xというコントロールバイトにしか反応しません。

チップセレクトの設定は複数のI2Cデバイスをバスに接続する場合に有用ですが、今回はEEPROM1つしか使わないので、すべて0(LOW)に設定しておきます。つまり何にも接続しません(誤動作を避けるために本当は0Vに繋いでおくべき)。

24FC512は1010000Xというコントロールバイトに反応するはずです。このビット列はまた後で登場します。

WP(書き込みプロテクト)について

WPピンにHIGHを印加している間はEEPROMへの書き込みができなくなります。誤ってデータを上書きしてしまう事故を防ぐことができます。

ちなみに、WPは読み出しポインタの設定(書き込み)には影響しないはずです。

24FC512とRaspberry Piを接続

24FC512を以下のようにブレッドボードに差し込み、Raspberry PiのGPIOピンと24FC512を以下のように接続します。(画像には24LC512と書いてありますが…)

24FC512のVDD, VSS, SCL, SDAの端子をそれぞれRaspberry Piの3.3V, GND, SCL, SDAピンに接続します。

Raspberry Piのどのピンが何のピンなのかを調べるには https://pinout.xyz を使います。

I2Cバスには本当は数kΩ程の抵抗器を通して+の電圧を印加しておく(プルアップ抵抗)必要があるのですが、Raspberry Piには内部プルアップ抵抗が実装されているらしく、このあとのステップで特に問題にならなかったのでプルアップ抵抗は省略してしまいました。ま、多少はね?

I2Cの有効化とi2c-toolsのインストール

素のRaspberry Piは確かI2Cが有効ではないので、I2Cカーネルモジュールを読み込ませる必要があったはずです。

$ sudo raspi-config

コマンドから簡単にI2Cの有効化ができたはずなので、それができたらこの記事に戻ってきてください。(他力本願)

この記事なんか良いと思います:

i2c-tools パッケージが必要なので、なければインストールしておいてください。

接続検出

次のサイトを参考にしました: https://www.richud.com/wiki/Rasberry_Pi_I2C_EEPROM_Program

i2cdetect コマンドを使うとRaspberry PiのI2Cバスに接続されているI2Cデバイスを検出することができます。

まず i2cdetect -l コマンドでRaspberry Pi 上に存在するI2Cバスを調べます。

root@raspberrypi:~# i2cdetect -l
i2c-1	i2c       	bcm2835 I2C adapter             	I2C adapter

(いまrootユーザーでログインしちゃってますが、piなど普通のユーザーの場合は必要に応じて sudo をつけて実行してくださいね)

i2c-1 とあるので、I2Cバス1番が存在することが分かりました。この1番バスが先のRaspberry Piの図の中でワイヤーを接続したSDA, SCLピンと対応しています。

i2cdetect -y 1 コマンドで、1番バス上の、0x03から0x77までのアドレスに対するデバイスの応答を調べます。

root@raspberrypi:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

この表の意味するところは、1番バス上でアドレス0x03, 0x04, 0x05, ..., 0x77 に対する書き込み要求(実際に何かデータを書き込んだりはしない)を送信し、返事がなかったら --、返事があったらそのアドレスを表示するというものになっているようです。(これ表示する値はYとかNとかでもいいんじゃないのと思ったり)

(UU の表示がある場合は、そのアドレスにデバイスが存在するが他のドライバーがそのアドレスを使用中であることを意味するらしいです。)

実行結果より、1番バス上において、アドレス0x50のデバイスからの反応がありました。

これは、先に設定したコントロールバイトの上位7bitそのものです。7bitのスレーブアドレス 1010000 が16進数表現で 0x50 となって表れたのです。

これで、1番バス上の アドレス 0x50 に24FC512がいることが分かりました。

eeprogのダウンロード・コンパイル

Raspberry PiのGPIOピンで24FC512を読み書きできるライターソフトウェアeeprogを導入します。EEPROMのprogrammer(書き込み器)だからeeprogという名前なのでしょうね。

wikiページ https://www.richud.com/wiki/Rasberry_Pi_I2C_EEPROM_Program#eeprog によると、

http://darkswarm.org/eeprog-0.7.6-tear5.tar.gz

をダウンロードしてeeprogを導入するらしいです。このwikiで紹介されているeeprog-0.7.6はオリジナルのものに改変を加えているそうです

(eeprog-0.7.6-tear5をダウンロードするとeeprog-0.7.6-tear12がダウンロードされますが問題ありません。)

eeprog-0.7.6-tear5 のリンクからダウンロードしたtear12の .tar.gz ファイルを次のコマンドで展開します。

root@raspberrypi:~# tar -xzfv eeprog-0.7.6-tear12.tar.gz

展開したら eeprog-0.7.6-tear12 というディレクトリができたはずなので、

root@raspberrypi:~# cd eeprog-0.7.6-tear12

でそこに移動してください。

ディレクトリ eeprog-0.7.6-tear12 に移動したら、そこで make コマンドを実行して eeprog をコンパイルします。

root@raspberrypi:~/eeprog-0.7.6-tear12# make
cc -g -Wall -O2   -c -o eeprog.o eeprog.c
cc -g -Wall -O2   -c -o 24cXX.o 24cXX.c
cc   eeprog.o 24cXX.o   -o eeprog

問題なくコンパイルできました。ディレクトリには eeprog という実行ファイルが生成されました。

EEPROMの読み出し・書き込みのテスト

wikiの通りにEEPROMを読み出したいと思います。コマンドの説明をします。

$ ./eeprog -xf /dev/i2c-1 0x50 -16 -r 0x00:0x100
  • -x オプションをつけると出力が16進数の表で見やすく表示されるようになります。
  • -f オプションは、毎回必ず出てくる注意書きを黙らせるオプションです。
  • /dev/i2c-1 0x50 は先に特定した、1番バス上のデバイスアドレス0x50を指定するパラメータです。
  • -16 は 16bitアドレッシングモードを意味するオプションです。まあ2048bitより容量の大きいEEPROMなら -16 必須でしょうねきっと。
  • -r は読み出し操作を意味するオプションです。
  • 0x00:0x100開始アドレス:読み出すバイト数 を意味するパラメータです。先頭から 0x100 個つまり 256個 読み出す指定です。 開始アドレス:終了アドレス ではないので注意。

このコマンドの実行結果は以下の通り:

root@raspberrypi:~/eeprog-0.7.6-tear12# ./eeprog -xf /dev/i2c-1 0x50 -16 -r 0x00:0x100
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: read 256 bytes from offset 0, Output file: <stdout>
  Reading 256 bytes from 0x0

 0000|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0010|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0020|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0030|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0040|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0050|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0060|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0070|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0080|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0090|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00a0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00b0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00c0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00d0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00e0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00f0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 

ffで埋まっています。

今度は先頭にちょっと何か書き込むテストをしてみたいと思います。

date コマンドの結果をパイプで eeprog に渡して書き込みをします。

$ date | ./eeprog -f -16 -w 0 -t 5 /dev/i2c-1 0x50
  • -f, -16 オプションは先ほどと同じ。
  • -w で書き込み開始アドレスを指定します。
  • -t で書き込み時間の間隔をms単位で指定します。確かデータシートには、書き込みと書き込みの間は4msちょっと待つように書かれていたような気がするので -t 5 でちょうどいいはずです。

このコマンドの実行結果は以下の通りです:

root@raspberrypi:~/eeprog-0.7.6-tear12# date | ./eeprog -f -16 -w 0 -t 5 /dev/i2c-1 0x50
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: write at offset 0, Input file: <stdin>
  Write cycle time: 5 milliseconds
  Writing <stdin> starting at address 0x0
.............................

ちゃんと書き込めたでしょうか。

読み出しを行って確認したいと思います。

root@raspberrypi:~/eeprog-0.7.6-tear12# ./eeprog -xf /dev/i2c-1 0x50 -16 -r 0x00:0x100
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: read 256 bytes from offset 0, Output file: <stdout>
  Reading 256 bytes from 0x0

 0000|  53 61 74 20 32 38 20 4d   61 72 20 30 39 3a 33 32 
 0010|  3a 30 34 20 4a 53 54 20   32 30 32 30 0a ff ff ff 
 0020|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0030|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0040|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0050|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0060|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0070|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0080|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 0090|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00a0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00b0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00c0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00d0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00e0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 
 00f0|  ff ff ff ff ff ff ff ff   ff ff ff ff ff ff ff ff 

先程読み出したときと違い、先頭にff以外の数値が現れました。

これをASCIIコードに当てはめると

Sat 28 Mar 09:32:04 JST 2020

となることから、きちんと date コマンドの結果が書き込めています。

本命のwavファイル書き込み

きちんと読み書きできたので、こんどは本命のファイルをEEPROMに書き込んでみたいと思います。

先ほどの書き込みコマンドで使ったパイプ | の代わりに -i オプションで入力ファイル名を指定すれば、指定したファイルからの書き込みができます。

今回書き込みたい音源 /home/pi/ixgy.wav をEEPROMに書き込みます:

root@raspberrypi:~/eeprog-0.7.6-tear12# ./eeprog -f -16 -w 0 -t 5 /dev/i2c-1 0x50 -i /home/pi/ixgy.wav 
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: write at offset 0, Input file: /home/pi/ixgy.wav
  Write cycle time: 5 milliseconds
  Writing /home/pi/ixgy.wav starting at address 0x0
..........................................................

ファイルサイズにもよりますが数分〜十数分くらい待たされます。

このeeprogくんは書き込みが遅い。リポジトリを https://github.com/jsarenik/eeprog に発見したので読んでみると、1バイト書き込むために毎回アドレスを指定をしている。つまり1バイトにつき3バイトのオーバーヘッドが発生していることに。24XX EEPROMにはページ書き込み機能がついていて、本来なら数十から数百バイトを一度に書き込めるので、この機能を利用するようにすればeeprogの書き込み速度は大幅に上がるんだけど…。誰かそう書き換えてください…

書き込みが終わりました。

先頭256バイトを読み出してみます。

root@raspberrypi:~/eeprog-0.7.6-tear12# ./eeprog -xf /dev/i2c-1 0x50 -16 -r 0x00:0x100
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: read 256 bytes from offset 0, Output file: <stdout>
  Reading 256 bytes from 0x0

 0000|  52 49 46 46 9a f7 00 00   57 41 56 45 66 6d 74 20 
 0010|  10 00 00 00 01 00 01 00   b0 36 00 00 b0 36 00 00 
 0020|  01 00 08 00 64 61 74 61   76 f7 00 00 8b 96 98 9f 
 0030|  9e 8c a0 ac b0 bc 9d 8a   8c 9f bb b9 b1 a9 9b 99 
 0040|  a9 b6 b0 ab 9f a2 ab 95   a3 a3 88 8e 8b 7e 8a 82 
 0050|  93 9e 8f 90 77 84 87 94   9a a0 9d 95 99 7f 90 90 
 0060|  8e 94 8d 85 85 96 90 94   99 9c 8d 94 ac a7 b2 a7 
 0070|  a6 a4 9d ad bc ad ad a8   a5 a1 92 ab aa 9b a1 9b 
 0080|  9d a4 8e 81 8d 94 7f a1   8b 8f b1 96 97 a1 a1 89 
 0090|  95 8d a5 9d 9d 91 84 8b   6d 8a 75 76 85 7d 8f 8d 
 00a0|  a4 9a 92 97 b7 c5 b0 c0   b9 b8 c5 db df cd ae ae 
 00b0|  b4 aa a1 a8 8d 6e 5f 5d   48 44 60 62 6a 40 46 45 
 00c0|  73 8e 98 b6 9c d0 ed e1   fb ff ff ff ff ff ef be 
 00d0|  c2 9c 6d 4c 2b 1c 00 19   28 25 11 00 3a 62 72 91 
 00e0|  b3 b9 b8 bc bf eb ff ff   ff ff ff ff ff ff ff ff 
 00f0|  ff b7 89 82 72 39 0c 00   00 00 00 00 00 00 0d 19 

root@raspberrypi:~/eeprog-0.7.6-tear12# ./eeprog -f /dev/i2c-1 0x50 -16 -r 0x00:0x100
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: read 256 bytes from offset 0, Output file: <stdout>
  Reading 256 bytes from 0x0
RIFF??WAVEfmt ?6?datav??????????????????????????????????~??????w?????????????????????????????????????????????????????????????????m?uv?}???????Ű??????ͮ??????n_]HD`bj@FEs??????????????œmL+(%:br?????????????????????r9

WAVファイルのヘッダを意味する RIFF??WAVE で始まっているのでどうやらうまく書き込みできていそうです。

書き込みの完全性の確認

きちんと1bitの誤りもなく書き込めているでしょうか。

まずはもとのファイルサイズを wc コマンドで確認してみます。

root@raspberrypi:~/eeprog-0.7.6-tear12# wc /home/pi/ixgy.wav 
   52   298 63394 /home/pi/ixgy.wav

ixgy.wav は63394バイトです。

続いてEEPROMから0xf7a2(63394)バイト読み出して、 114514.txt というファイル名で保存してみます。 出力ファイル名の指定は -o オプションで行います。

root@raspberrypi:~/eeprog-0.7.6-tear12# ./eeprog -f /dev/i2c-1 0x50 -16 -r 0x00:0xf7a2 -o 114514.txt
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit
  Operation: read 63394 bytes from offset 0, Output file: 114514.txt
  Reading 63394 bytes from 0x0

最後に、ixgy.wav と EEPROMの中身を読み出したファイル 114514.txt との差分を diff コマンドで確認したいと思います。

何も出力されなければ完全一致を意味します。

root@raspberrypi:~/eeprog-0.7.6-tear12# diff 114514.txt /home/pi/ixgy.wav
root@raspberrypi:~/eeprog-0.7.6-tear12#

完全一致でした。

やったぜ。

まとめ

64KB以下のサイズに削減した音声ファイルをEEPROMに書き込み、確かに間違いなく読み出せることを確認しました。

次回はAVRマイコンをプログラムする準備をする予定です。

防犯ブザーを改造してサウンドロップを自作する Part2 につづく

迫真の氷結晶 © 2020