Raspberry pi 1 Model A I2Sシステム。

課題だった電源供給とスイッチ。DCジャックつけてトグルスイッチつけただけなんだけどね。

ジャックの爪が短くて曲げてもすっぽ抜けちゃうので内側で適当なランナーつけといた。

スイッチはバカ穴作るだけなんだけど、上ブタとの境目が中心に来るので試しながら削った。

本当はもっと小さいスイッチ使えば楽だったんだけど、余剰パーツでこのタイプが一番残ってたからこれにした。

 

まぁ悪くないか。音鳴るし。

ついでにLANケーブルの張力に負けちゃうので、前中古ノートについてきた無線LANアダプタつけて設定した。

 

これで一段落とするか。特にこれから特殊なこともする気もないし。

PCM5102Aボードへの配線もっと綺麗にしろよとかあるけど、これ以上いじって下手こくのもイヤなのでこれでいいや。

まぁスピーカ内に固定のことは考えなきゃだけど。金属ケースでシールドされてるとはいえD級アンプに近づけるのもどうしたもんかなぁ。

 

でもこれでミニコンポっぽくなったw。こんなおもちゃでも考えてみたら結構中身高水準だよな。

当然Wifiで参加したスマホからの操作も出来るし。WEBラジオ色んな国の聞けるしね。

出力される音質は別にしてハイレゾFLAC再生できるし。音源ないけどw。

 

これ使ってどこか外国語の勉強でもしようかなw。

Raspberry pi 1 Model Aで無事I2S DACできたので、少し使ってみてた。

これWebRadioがいいね。国別とかで見てると世界の局がある程度登録されてた。

聞けないのもあるけど、それでも莫大な量がある。

ここでぼーっと気に入った局探すのも楽しみの一つになった。

そういやもっと生活の中に音楽を取り込もうと考えてやろうとしてたこと思い出したわw。いまさら。

まw、PCでやればいいじゃんてのは無しで。

 

気になってきたのは基板が固定されてないところ。危なっかしいのよね、配線だけでプラプラしてスピーカの向き変えるときとか。

でもどうしたらと悩んだ末、ラズパイのケースの上に下駄はかせるみたいに建てることにした。

 

無理くり透明アクリルケースの天井に穴空けてスペーサ入れて高くしてつけた。

まぁ何すると決めてもないけど、少し考えてることはあんだけどw、USBのソケットと干渉しそうなのを回避する目的で。

 

あとはー。

ジャックとかのコンポーネント群はどっちか片一方にしたいのよね。

今現在はSDカードはしょうがないとして、電源USBポートひとつだけ違うほうについてる。

それと電源ON-OFFがUSBケーブル抜き差しってのもいただけない。

普通の5VスイッチングアダプタのジャックをLANとかRCAのある後ろに設けて、出来ればSDカード側のどこかにスイッチ設けたいな。

そしたら俺スピーカの中央のD級アンプの上に格納しても良いんじゃないかとか。

どんどん欲しいものになってきて、楽しくなってきた。

マジで出来ないかと思ったー。

 

いやさ、初代Raspberry piになんかやらせないといけないとか思ってて、

ちょうどハイレゾ云々の記事を見てこれなんかちょうどいいんじゃないのとか思ったわけ。

尼で安かったしHifiberryとかいうのの互換機っぽいのあったのでポチったのがこれ。

I2S [IIS] 入力DAC PCM5102A搭載32bit 384kHz DAC完成基板なるもの。

綺麗な基板だったしこれつけるだけでハイレゾ音源に対応できるなんて!とか思ってた。そんな音源データ持ってないのに。

ネット情報でつないでこれでいいかなと思って最初はシェルで確認とやってみたが、自分の声で作ったwavが鳴らせない。

ちょっと調べればわかるでしょとか思ったけど解決できない。ぐぬぬ。

 

確かにみんなRaspberry pi 2以降でやってるけど、互換性高いしVolumioも入れられたのでいけるんじゃないのと思ってたけど出来ない。

半泣きで一旦離れて少し時間たってから冷静に見返してみると、俺は本当にバカだということを悟った。

2や3はP1が40ピンだけど、俺の初代26ピンだわこれ。下から数えて挿したりしてたので、BCK LRCK DATAそれぞれ合ってるはずも無い。

これに気づいたのが結構後。26ピンと40ピンとか本当に気づかなかったの?とか言われそうだけど、

すまない、本当にそうだったんだ。

 

じゃあ正しいピンはどれなのということになるのだけど、古いRaspberry piでやってるところ見てみると、Model BからはP5なるヘッダ群があって、そこに挿せと。俺のにはP5なんて無かった。本気でダメか!これ、と思わずにはいられない。

でも最初期からやってる人がいるはずなのでと藁をもすがるつもりでModel Aでググッてたらやってるところあった。

 

でもそこではピン出てない初代の解決方法として、そのポート延びてると思しき表面実装チップ抵抗の片一方に直接半田付けせいとw。

もうなんで俺だけこんな艱難辛苦なのといじけたものだったけど、やってみたら意外と良好に出来たw。

 

左から青:DATA、緑:LRCK、赤:BCKだったはず。

これらの線をそのままPCM5102AボードにつないでVolumio起動してみた。

そしたら100%音量で鳴り出した!あまりの音の大きさにびっくりして手が震えて手早く操作できなかったりとか、うれしくて何も考えが及ばないとか、久しぶりだなこの感覚w。

 

でもやったー。一時はこのボードおかしいか、壊しちゃったのかなとか思ったけど、

おかしいのは俺の頭だけだったことがわかってほっとした。

現実音はどうなのということなんだけど、例によって俺のぼんくら耳にはあまり違いがわからなかった。

いや、ハイレゾ音源ないかなと探してたら、音響機器メーカとかにわりと聞き比べてくださいとサンプルデータ置いてあってそれで試してた。

でも俺には全部とても綺麗な音にしか聞こえないw。

学生から社会人数年までコンポなんて買ったこと無かったし。ずっとラジカセかCDラジカセ。しかもたいていイヤホンで聞いてたもんな。

あ、それと俺の作ったスピーカだったてのも大きな要因のひとつかも。専門家が根拠のある作り方をして作ったものじゃないし。

 

でも、うれしいんだ。

自分が苦心して作ったスピーカユニットが頑張って綺麗な音を聞かせてくれるなんて、これ以上贅沢言わないよ。

さて、とりあえず持ってるCDから移してみるかな。

 

気が付くと1月たってる。

少し落ち着いたので、簡単な作業からやってみるかと。

 

OP6とOP4の差異はどうしようも出来ないけど、1つ1つの波形は表現できるようになっても良いんじゃないかと、

手習いなRuby/Tkを使って簡単な換算表みたいな物を作ってみようかな、と。

これまでパラメータの意味を少し勉強してたので、手計算ならそれっぽい値出せるかなとなったので、

表のタタキ台作ってみてた。

当然ながらこれだけじゃ何にもならんけど、打ち込むエリアと換算値を表示するエリアを。

むぅ、計算イベント発生させるなんかボタンもいるよな、こりゃ。

しかし思ったよりこういったフォームをソースで書くのって大変だな。

VSなどのエディタならすぐ出来そうなものなんだけど、こんだけなのにすごい苦労した気がする。

 

でも、こういうの欲しかったといったところまでできたので少し満足。

中身実装できるかな?

別の音を聞いてみたいなとやり方をWEBで探してるんだけど、なかなか探し当てられないYMF825基板情報。

具体的なパラメータ入れてみたいんだけど自分ではわからんし。

DX-7のVOICE DATA集あるけど、OP数も違うしどうしたらいいかわからん。

 

するときょうのかんぱぱさんのところでピアノのtoneデータらしきものが。

入れてみた。でも最初サイトのコピペを貼ったんだけど、それだとHTMLのインデントとIDEのが相性悪いのかエラー吐かれた。

なので消したりして入れなおしたらうまく動いた。聞いてみる。

 

スゲェー。これホントのピアノしてるじゃんと相当感動した。

面白いね、これもうちょっとなんか聞いてみたいなぁ。

うまくDX-7系のデータをこっち系に変える方法を調べてみんといかんかな。

なんかあるかなー。

DevKit C買うついでに買ってみましたYMF825ボード。

本家のGitHubでArduinoのサンプルコードあるみたいなので、

ちょうど出来上がったトラ技のボードで出来ないかなとやってみてた。

ちょっと不安要素だったのが、3.3Vにするときのジャンパつなぎの半田付け。

うまくつながらなくて熱加えまくってたらランドはげて来た。

リードの切れッ端でパターンここだろってところまでつないで見たんだけど自信がなかった。

ピンアサインは互換ボードってことでその通りにつなぐことにした。

 

とりあえず配線してArduinoIDEでサンプルスケッチをコンパイルしたらエラー。

む。なんかよくわからんけどCSとリセットのところが良くないらしい。

スケッチ見てみるとPORTBとか書いてある。

これはAVRとかの記述で、ESP32とかじゃ通用しないんじゃないかなぁ。

まぁUNO専用とか書いてあるし。

 

読んでるとなんかブールっぽい値(HIGH,LOW)の引数でCSとRSTのピンをオンオフするだけみたい。

なのでESP32につないでる本来のピン番号を調べて、

あんましよくない書き方かも知れんけど単純にオンオフさせる風に書き換えてみた。

// only for Arduino UNO
void set_ss_pin(int val) {
//    if(val ==HIGH) PORTB |= (4);
//    else PORTB &= ~(4);
    digitalWrite(25,val);
}

// only for Arduino UNO
void set_rst_pin(int val) {
//    if(val ==HIGH) PORTB |= (2);
//    else PORTB &= ~(2);
    digitalWrite(26,val);
}

自作スピーカ&中華D級アンプにつないで書き込んでリセット。

鳴ったわw。最初音が大きくてびっくりしたw。

 

昔のゲームの音みたいなのが音階上がっていく。

やったこれでまた少し遊べそうだ。

付録基板つきトランジスタ技術2017/11月号。

雑誌は結構前に買ったんだけど、aitendoの部品セットが品切れが続いてて、なかなか手に入らなくて。

さて久しぶりに工作を。

 

さすが待たせることもあって部品不足なのか、基板上では4ピンなのに付いてきたUSBシリアルは6ピン。きちっと収まらないけど、逆に考えれば汎用に使えるという選択肢が増えて自分的には満足。

 

作ってるときに積セラをチェックしてたんだけど、本誌の部品表とaitendoのセットにあるものと違う。むむ、どっちが正しいのかを考えたけど、言っちゃ悪いけどこの時点ではどっちも信用ならないw。

 

くそーとか思って本誌の回路図のほうの部品を見てるとaitendoの部品群と整合性があった。

こりゃ本誌の部品表が間違ってるなと判断して、回路図の通りに部品を配した。

あと、ついてきた電解コンデンサの10uFと47uFが聞いたことないところのだったので、手持ちにルビコンのやつがあったのでそれに代えて配した。OS-CONはそのまま使ったけど。

 

こんな通りに慎重に作ってたつもりだったけど、俺の配慮が足らず間違えてるところが何点かあった。人のこと信用できないとか言えないなw。

LEDに配する色間違えてたみたいなのと、変更した電解コンデンサ寝かせるの忘れてたり。

LEDは別にそう問題でもないけど、電解コンの背が立ってるのは、もはやシールドを装着できないことを意味しているw。

まぁいいや、どうせシールドなんて買わないし作らないし付けたくないし。

 

さてこれで部品付け終わったみたいなので通電してみようと。

LEDは光ったけど何も起こらない。TeraTerm立ち上げるとデフォが9600bpsなので、本誌の言われるように115200に直しても何も起こらない。繋げるとターミナルに反応があれば成功とあるんだけど、ボーレート合わせても何も返事がなく屍のようである。

 

えーと思って接続断そのままで、ボタン押してみるかとどっちリセットだっけということを確かめる前に目に入ったボタン押したらビロビロ何かしら理解できないメッセージが流れてきた。

あ、これのことかな?

にゃんだよリセット押せって書いといてくれてもいいじゃーん。てっきり失敗したかと思ったよ。

 

裏の冷却のホールにはんだ流し込むのが難しかったかな。そのほかの罠もなんとか回避できた。

実は部品が届く前に秋月で画像左のESP32 DevKit Cを購入済み。部品来るまでこれで少し遊んでた。

 

でもaitendoの部品セットは安いなあれ。個々に別の店で揃えようとしても邪魔くさいし高くつく。ESP WROOM 32とUSBシリアル、三端子レギュレータやOS-CONとかMicroSDスロットで2000円切ってるとか他じゃ真似できないんじゃないかなぁ。

しかし、この秋月で買ったDevKit C完成品で1480円で買えるんだけどw。

 

比較して思ったことは、トラ技のボードはMicroSDついてるとかかな。でもDevKit Cのように自動で書き込みモードにならず手動で変えないといけないらしい。

まぁお好みレベルかな。金額は上にも書いたけど断然DevKit Cのほうが安くつくけどw。

まぁ楽しかったw。

さて絵の動かし方というか現時点ずらし方と言うか、ができたのでキー認識のコードと合体させてみよう。

まず初期の設定から。

 

require 'tk'

mine_x=320
mine_y=240
mine_xv=0
mine_yv=0

英語苦手なので変数の名前を決めるのも下手。まぁ理解して区別できれば良いということで、これ以上言い訳はしないw。
自機のx,y座標と、moveに渡すx,y増減分を示す変数を作った。
今の時点ではx,y座標の変数は最初に描かせる時にしか使わないけど、後々必要になる記述だ。

で、あとはキー認識のコードをそのまま貼り付ける。

key_state=[0,0,0,0,0,0]
$buffer = TkVariable.new('')
a = TkLabel.new(textvariable: $buffer).pack
a.focus

a.bind('KeyPress', proc {|k| 
    if ("#{k}")=="Up" then
        key_state[0]=1
    elsif ("#{k}")=="Right" then
        key_state[1]=1
    elsif ("#{k}")=="Down" then
        key_state[2]=1
    elsif ("#{k}")=="Left" then
        key_state[3]=1
    elsif ("#{k}")=="z" or ("#{k}")=="Z" then
        key_state[4]=1
    elsif ("#{k}")=="x" or ("#{k}")=="X" then
        key_state[5]=1
    end
    $buffer.value = key_state},'%K')

a.bind('KeyRelease', proc {|l| 
    if ("#{l}")=="Up" then
        key_state[0]=0
    elsif ("#{l}")=="Right" then
        key_state[1]=0
    elsif ("#{l}")=="Down" then
        key_state[2]=0
    elsif ("#{l}")=="Left" then
        key_state[3]=0
    elsif ("#{l}")=="z" or ("#{l}")=="Z" then
        key_state[4]=0
    elsif ("#{l}")=="x" or ("#{l}")=="X" then
        key_state[5]=0
    end
    $buffer.value = key_state},'%K')

次にウインドウを用意してくろさんの画像を出すやつに、わざわざ上で設定した座標の変数に書き直して、最後にmainloop。

image1 = TkPhotoImage.new(file: 'rock_jmp_r.gif')
win = TkCanvas.new(width: 640, height: 480).pack
c0 = TkcImage.new(win, mine_x, mine_y){
  image image1
}

Tk.mainloop()

ここまでほとんど以前作ったコードのコピペしただけ。
これで実行してみてキー認識と画像表示の共存は出来てることがわかった。

これどうやって動かす?

このままだと絵は動かないし、キー認識もキーを押した離したの瞬間しか動かない。

moveの命令の出番をどうやって作るのか。

 

キー認識のレジスタが変化したときにイベントを起こす?それちょっとちがうな。

調べてたら良いの見つけた。

TkAfter.startってやつ。例えば

TkAfter.start(10, -1)

ってやると、10ms毎に無限回イベント起こすというタイマ。これ使おう。
キー認識で出てきたkey_state値は1か0なので、このまま増分を算出してみよう。

TkAfter.start(10, -1) {
    mine_xv=key_state[1]+key_state[3]*(-1)
    mine_yv=key_state[2]+key_state[0]*(-1)
    win.move(c0,mine_xv,mine_yv)
}

key_stateの配列は、上[0],右[1],下[2]左[3]なので、x方向は右と、左に-1を掛けたものの和とした。上下も同様に。で、でた増減量で絵を動かすと。これで同時押しも0だし、どっちか押されたほうが残るし、上下と左右で斜めも出来るはずだ。

これをmainloopの前に置いた。


まぁこんな実行画面のキャプしても静止画じゃ今まで上げた画像と変わりないので出さないけど、うまくいった。思ったより結構滑らかに動く気がした。ぎこちなくもないし、移動分は少ないけど機敏に反応してる。比較できるもんがないけどw。

 

でも、これでPythonのときに悩んでたキーのオートリピート対策が出来たような気がする!

Tkinterでも理屈が似たように書けば同じように動かせると思う。

うむ、ちょっと気分良い。

gif画像が出せたので、今度はこれをどうやって動かすかを。

まぁPythonでやったやつを真似るだけなんだけど。

 

前のコードで初期値が縦横ちょうど半分のところに出した。

その後ろの記述に

win.move(c,0,100)

と入れた。
大体想像付くと思うけどwin上でcで設定したものをx軸方向は0、y軸方向は100ドット分移動するってことだ。実行すると

なんとなく下がってるのわかるよね。
比較したいならもう1個書いて動かすやつと動かさないやつで見てみよう。
cをc0とc1の2つ用意して、c0だけ動かしてみる。

require 'tk'

image1 = TkPhotoImage.new(file: 'rock_jmp_r.gif')
win = TkCanvas.new(width: 640, height: 480).pack
c0 = TkcImage.new(win, 320, 240){
  image image1
}
c1 = TkcImage.new(win, 320, 240){
  image image1
}

    win.move(c0,0,100)

Tk.mainloop()

全部書くとこんな感じ。で、実行。

 

だから、moveの3つの引数のうち、動かしたい絵を指定して後ろ2つで移動量を設定するという仕組みを利用しようというわけだ。
ま、こんなに画像とかてんこ盛りしたわりに、たいしたことしてないw。

あとはこれと、最初に作ったキー入力を合体してみれば、俺のやったことが無駄だったかそうでないかがわかるはずだw。

色んなことを忘れてしまっている未来の俺に対してはじまってる感w。

Ruby/Tkを使って遊んでみようシリーズというか。

前はTkinterで経験したキー認識のオートリピートを解決してみよう?というところだったかな。

まぁ結果が出てないから解決できてるかわからないしww。

 

じゃあ、ってんで絵を動かす前に、俺に絵が出せるのかをやってみる。

Tkinterの時に動かし方やってるので、それに準じて、GIF画像用意した。まぁHSPの時の加工したものを流用って感じで。

例のやつです。あのままだとやはりまずいかなと思って黒く塗ってみた。

くろさん、とでも呼ぼうか。

 

require 'tk'

image1 = TkPhotoImage.new(file: 'rock_jmp_r.gif')
win = TkCanvas.new(width: 640, height: 480).pack
c = TkcImage.new(win, 320, 240){
  image image1
}

Tk.mainloop()

image1に画像ファイルを登録して、winというウインドウを準備して、中央にimage1を置いた。

 

Tkのクラスや詳しいことは、お気楽Ruby/Tk超入門さんのところにGoだ!

次はmoveを使ってみよう。