迫真の氷結晶

初投稿です。

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

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

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

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

はじめに

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

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

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

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

目次

ordered: true

導入

サウンドロップとは

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

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

参考画像:

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

Raspberry Pi 2 Model B (必須)

古い Raspberry Pi 2 Model B Rev 1.1 しか持っていなかったのでこう書いていますが、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 10 (buster) です。(Raspberry Pi OS という名前に変わる少し前の OS)

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 と 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 に書き込みたいと思います。

ここからの説明の流れは次のようになっています:

  1. EEPROM の使い方の説明
  2. Raspberry Pi と EEPROM とを配線する
  3. Raspberry Pi で EEPROM の接続を検出する
  4. Raspberry Pi で EEPROM に読み書きテストをしてみる
  5. Raspberry Pi で EEPROM にファイルを書き込む

早く進みたい方は配線方法のセクション「24FC512 と Raspberry Pi を接続」まで飛ばしても OK です。

I2C EEPROM 24FC512 の使い方

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

まず I2C とは

まず簡単に 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 と書いてありますが…)

this is a fallback text

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

として、 3. Interface Options > P5 I2C を選びます。(Raspbian 10 (buster) の場合)

buzzer-part1-raspi-config.png

buzzer-part1-p5-i2c.png

Would you like the SPI interface to be enabled?

と聞かれるので Yes を選んで Enter を押します。すると

The SPI interface is enabled

と表示され、I2C が有効になります。

接続検出

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

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

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

pi@raspberrypi:~ $ i2cdetect -l
i2c-1	i2c       	bcm2835 (i2c@7e804000)          	I2C adapter

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 がいることが分かりました。

表がすべて -- の場合は配線を確認してください。特に SDA , SCL が逆になっていないか確認してください。

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 のダウンロード

pi@raspberrypi:~ $ wget http://darkswarm.org/eeprog-0.7.6-tear5.tar.gz

展開

ダウンロードした eeprog-0.7.6-tear5.tar.gz を次のコマンドで展開します。

pi@raspberrypi:~ $ tar -xvf eeprog-0.7.6-tear5.tar.gz

展開すると eeprog-0.7.6-tear12 というディレクトリができます。(tear5 ではない)

pi@raspberrypi:~ $ cd eeprog-0.7.6-tear12/

で、そのディレクトリに移動してください。

コンパイル

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

pi@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 という実行ファイルが生成されました。これが 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](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 - Raspberry Pi の GPIO で AVR マイコンにプログラムを書き込む


ほかの記事

迫真の氷結晶 © 2024