ポッドキャスト「#inajob の試しに録音してみた」の作り方

これは?

私は毎週1回更新のポッドキャストである「#inajob の試しに録音してみた」をかれこれ、2023年5月から始めて1年以上続けています。

ポッドキャスト、というと面倒くさそうというイメージがあるかもしれませんが、個人的にはブログ記事を書くよりも簡単・気楽に自分の言葉を紡ぎだし、公開する手段だと考えています。

この記事では、このポッドキャストの技術的な側面について紹介します。

まずは宣伝

この記事では、「#inajob の試しに録音してみた」をどうやって作っているかという技術面での紹介にフォーカスして紹介しましたが一応「#inajob の試しに録音してみた」の紹介もさせてください。

「#inajob の試しに録音してみた」は、30台後半、ものづくりが好きで、4歳の娘を子育て中のinajobが、なんでもない日々の雑談を毎週30分程度録音しているポッドキャストです。

「30代後半」、「ものづくり」、「子育て」あたりのキーワードにピピっと来た人はぜひ試しに聞いてみてください!

Spotifyで聞きたい方はこちら open.spotify.com

LISTENで文字起こしを見たい、文字起こしを見ながら聞きたい方はこちら listen.style

機材

機材と言っても、パソコンとマイクだけです。 パソコンは一般的なものなので、マイクについて紹介します。

以前も紹介しましたが、マイクはWeb会議用のインカム型のマイクを利用しています。

ポッドキャストを録音する人は、かなり良いマイクを買っているようですが、自分はまだ踏み出せていません。でもどうでしょう、自分のポッドキャスト、そこまで音声がひどいってことはないように聞こえませんか? (良いマイクはこんなところがいいよ!というプレゼンをしてほしいと思い、あえてこういう書き方をしてみる)

このヘッドセット、普通に在宅勤務時にも便利に使っています。

選ぶポイントとしては、安いこと、USB接続ではなく3.5mmオーディオジャックであること(一般的にはUSB接続の方が音質が良いなどと言われている気がしますが、接続の相性などが無い3.5mmオーディオジャックの方がつぶしがききそうだなと思って、こちらを選択しました)くらいを考慮しました。

台本

台本と言っても、何を話すかのトピックを列挙しただけのテキストです。

私は、普段自作のWikiで日記をつけているので、そのWikiの中に台本を作っています。

自分のポッドキャストでは、主にその週に起きたことをトピックとして取り上げることが多いため、台本作りというか、「先週の振り返り」をやっていると自然と台本が出来ているというような感じです。

録音ソフト

Windows標準の「ボイスレコーダー」、Macの場合は「ボイスメモ」を使っています。

私のポッドキャストは1人で録音しているものなので、録音周りで凝った機能は不要です。

しかし、この後の編集作業で、話題の切り替わりポイントに効果音を入れる処理があるので、話題の切れ目で音声ファイルを分けたいという要件があります。

OS標準のこれらのソフトは、録音ボタンで録音ができて、1つの音声を録音したのちに、さらに録音ボタンから録音すると別の音声ファイルとして録音を開始してくれます。

まぁ当たり前と言えば当たり前なのですが、この機能がトピックごとに音声ファイルを分けて録音するうえでとても便利です。

音声編集ソフト

Audacityを利用しています。 Audacityは無料で利用できる音声編集ソフトです。

また、後述するようにプログラミングで動作を定義することができるので、定型的な編集作業を自動化できます。

今回はこのプログラミングでの音声編集についてもう少し詳しく説明します。

プログラミングでの音声編集

Audacityはプログラミングで動作を定義できるということで、ポッドキャストをある程度編集していく中で、お決まりの編集作業をスクリプトとして定義しました。

後から音声の一部を切り取りたい、と言った作業をする必要が無い場合は、プログラムを実行し、少し手で作業するだけで、トピックごとのぶつ切り音声にBGMやサウンドを合成して、ポッドキャストっぽい音声を半自動的に作成できるようになっています。

ということで、この仕組みを使うと、ポッドキャスト収録にかかる時間は録音している時間と、少しスクリプトを実行する時間のみ、ということで、かなり手軽にポッドキャスト的な音声を作ることができます。

ぶつ切り音声をポッドキャスト化する手順

  • 録音した音声をすべて読み込む
  • (ここは手動)ノイズ低減
    • Audacityのノイズ低減エフェクトは、音声データの無音部分を指定することで、バックグラウンドノイズを認識して、ノイズを低減する機能です
    • 無音部分の指定がプログラムから実行できないので、この処理の手前でスクリプトが一時停止するように作っています
  • 無音の切りつめ
    • 録音データで沈黙部分が長い場合に切り詰めます
  • ラウドネスノーマライズ
    • -14LUFSに音声レベルを合わせます
  • 録音した音声を並べる
    • 最初と最後の音声は、BGMのイントロ部分と被らないように少しずらして配置します
  • 音声の切り替わり部分に効果音を入れる
  • 最初と最後の音声部分にBGMを入れる
    • BGMは最初数秒再生したのちにフェードアウトするようにエンベロープを設定します
  • 最後の音声の終了に合わせてBGMを切り詰める
  • (ここは手動) 名前を付けてプロジェクトを保存
  • (ここは手動) mp3形式でオーディオをエクスポート

自動化スクリプト

上に書いた処理を実行するスクリプトを公開しています。 もし似たようなポッドキャストを作ってみたい方は、どうぞご自由に使ってください。

github.com

配信

Spotify for Podcastersを使って配信しています。無料です。 さらに、Spotify for Podcastersの機能で、YouTubeApple Podcasts、Amazon Music、などさまざまなポッドキャストプラットフォームに配信しています。

podcasters.spotify.com

文字起こし

LISTENを使って文字起こしを作成しています。無料です。

listen.style

無料ユーザーの場合、サマリーとチャプターのの生成は10日間に1エピソードのみなので、毎週配信のポッドキャストだとたまにサマリーとチャプターが生成されない回があります。

もう一つ文字起こしサービスとしては Podexも利用しています。こちらも無料です。

podex.in

さらに最近、Podwiseというサービスでも文字起こしが作成できます。こちらは有料のサービスですが、だれか1人の課金ユーザが文字起こしを依頼すると、他の人は無料で見られるよいというような仕組みで、最近どなたかが、文字起こしを依頼してくれているようで、私は無料で(月4エピソードまでですが)文字起こしなどを見ることができています。(誰か知らないけど感謝です!)

podwise.ai

BGM

何かそれっぽい音楽が鳴ればいいや、と思いインターネットからPublic DomainのBGMを探してきて、エピソード毎にコロコロ変えています。

最近は以下のゲーム用の素材サイトからBGMでかつ、ライセンスの緩いものを検索して、良さそうなものを選んでいます。

opengameart.org

フィードバック・コミュニティ

フィードバック募集ツールとして、Google Formsを使っています。無料です。(あまり使われませんが・・)

またCosenseプロジェクト「井戸端」で、エピソードに対応したページを作り、好きに雑談できるようにしています。無料です。

ポッドキャストを始めるにあたり、何らかのコミュニティを活用することで、初期に聞いてくれる人を少しでも確保するのが、継続の秘訣かなと思いました。自分の場合は前述の「井戸端」や、Xのフォロワーさんが初期リスナーとなってくださいました。

scrapbox.io

さらに今年から、Dicordサーバ「inajob川」を作り、ポッドキャストにかかわらず私を中心としたコミュニティづくりも始めてみました。無料です。

discord.gg

まとめ

さて、ここまで紹介してきましたが、私がポッドキャストを始めるために払ったお金は、、マイク代の2000円弱だけです。

ポッドキャストって案外お金をかけずに継続できるんですね。

もちろん、マイクや編集は「沼」で、凝り始めるとかなり時間もお金もかかるとは思いますが、最小構成としてはこのくらいで始められるということがわかりました。

個人的に、在宅勤務や育児ということで、同僚や友人と顔を合わせて雑談する機会がかなり少なくなり、雑談に飢えていた中でたどり着いたのがポッドキャストです。

しばらく聞いていたのですが、そのうち自分でもやってみたくなり始めてみたところ、なんだかんだで1年以上続けることができています。

ポッドキャストを始めたことで、ほかのポッドキャストを配信する方との交流が増え、新たな刺激にもなっています。

この記事をお読みの皆さんも、私のポッドキャストに限らず、まずは聞くところから始めて、もし興味があればポッドキャスト配信を始めてみるのはいかがですか?

音の鳴る名刺基板

この記事ははJLCPCBの提供でお送りします。

またJLCPCBのブログとほぼ同じ内容です。

JLCPCBとは

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

JLCPCBとは、プリント基板製造などで有名な香港の企業です。

日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。

値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。

これは何?

基板を使った名刺を作るという活動があり、そういった基板を「名刺基板」と呼んだりします。

ということで、今回はinajobも名刺基板を作ってみようということで、挑戦してみたという話です。

要件定義としては、折角なので何か機能を持たせたいなと言うことで、ピアノのようなスイッチとボリューム・スピーカーなどを搭載し、「音が鳴る名刺基板」ということにしようと決めました。

設計

テーマは決まりましたが、細かいパーツに何を採用するかを決めていく必要があります。

色々考えて以下の構成に決定しました

  • メインICはCH32V003
    • 安いので、名刺基板に向いている?
  • 書き込み用USB端子(Type-C) + CH340G
  • 電源は単4電池2本
    • 外部電源なしで動くようにしたい
    • CH32V003は2.7V-5.5Vで動くので乾電池2本でそのまま動きます
  • オーディオアンプNS8002+ オーディオジャック + 表面実装スピーカー + ボリューム
  • 部品は片面にのみ配置
    • PCBAを見越して安く済むように
  • 12個の演奏用スイッチ
  • 12個のLED
  • 初回書き込み用のソケット

色々考えているとどんどん要件が膨らんで大変でしたが、ぎっしり部品が並んだ、見た目にも「それっぽい」基板になりそうです。

CH32V003のUSB経由での書き込みの仕組みやオーディオ周りは、ここ最近の製作で得た知識を応用することで、設計を流用しています。こういうことの積み重ねでできることがどんどん増えていくのは面白いですね。

スイッチののスキャンとLEDの点灯

12個のスイッチのスキャンと、12個のLED表示の制御を7個のGPIOで行おうと以下のような回路を設計しました(これは、あまり良い方法でないことがわかりました)

基板設計

片面に部品を寄せたので、表面はかなりごちゃごちゃした見た目になっていますが、個人的には名刺基板として「それっぽく」なっているので、良いなと思っています。

一応、表面に「Hello! inajob」と名前の紹介っぽいものが入っているのと、裏面にXのURLが記載してあるところが「名刺」的要素です。

JLCPCBに発注

今回も発注はJLCPCBです。今回の基板は青色にしてみました。

名刺基板のサイズは10cm×10cm以内なので、非常に安く作ることが出来ます(5枚で$2 + 送料)

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

実装

さて、今回も・・・トラブルがありました!!!(毎回これですね・・)

基板設計で必要な配線が出来ていない

さて、以下の画像をみれば、何が起きたか、わかる人にはわかるのですが・・

論理回路図で接続している配線が、基板上で配線できていません(白い斜めの線がそれを示しています)

今回の配線はFreeroutingというソフトを使い、自動配線したので通常このようなことは起こらないのですが、おそらく発注に向けて作業しているどこかで、操作ミスをして自動配線で作成された回路の一部を削除してしまったのでは、と考えています。

この手のミスは、以下のように見た目でもわかりますし、発注前にKiCADの「デザインルールチェッカー」を実行すればすぐに気付くことが出来るので、気づけなかったことが悔しいです。

この問題については、必要な配線を導線でジャンパすることで対応しました。(格好悪い・・)

スイッチスキャンとダイオード点灯回路に課題あり

上で紹介したこの回路。まぁ見る人が見ればすぐ気づく問題があります。

それは「スイッチを押しているときに対応するLEDが消灯してしまう」という問題です。

スイッチを押していないときは、ダイナミック点灯ですべてのLEDを個別に制御できますし、押されたスイッチもそれぞれ個別に認識できますが。

スイッチが押されているときに、そのスイッチと同じピンに接続されているLEDを点灯することが出来ません。

まぁ、LEDで何を表示したいかによりますが、スイッチから手を離せば意図した表示になるので、今回は一旦「こういう仕様」ということでこの問題は無視することにしました。

PD1のピンがそのままGPIOとして利用できない

上のスイッチとLEDの回路図でDIOとラベルの付いた配線がありますが、これはPD1と名の付いたGPIOです。

CH32V003は、初期設定ではこのピンをGPIOとして利用することが出来ません。

一応設定をすることでGPIOとして利用できるようにはなるようなのですが、そうすると書き込み機で書き込めなくなってしまうようで、ちょっと不便です。

また、今回利用したライブラリであるch32v003funで、このピンの役割を変更する方法がぱっとわからなかったということもあり、この問題のために基板の回路に修正が必要でした。

CH32V003J4M6 PD1 SWIO ピン共用問題 シリアル出力の実装とFlash eraseでの解決方法 - 宅配おもちゃ病院 %

今回はPD4が何も使わずに空いていたので、配線をカットしてPD1を使うのをやめてPD4を使うように変更することでこの問題を回避しました。

そのほか細かい気づき

  • 基板厚をもう少し薄くすればよかった
    • 基板厚はいつもと同じ1.6mmにしましたが、「名刺基板」というからにはもう少し薄くしても良かったかなと思いました
  • ICの利用していないピンを引き出しておけばよかった
    • 上で記載したPD4を含めいくつかのピンが未使用なのですが、このピンを引き出しておくと、この名刺基板を開発ボードとして活用することもできると感じました
  • スルーホールUSB-C端子は基板厚が1.6mmでもはんだ付けできる
    • 以前 UARTで書き込みできるCH32V003開発ボードを作った - inajob's blog で1mm厚ではんだ付けできることを確認しましたが、1.6mmでも問題なくはんだ付けできました。足が裏面に飛び出さないので、ちゃんと導通するか不安でしたが、表面張力ではんだがスルーホール穴に吸い込まれるため、問題なく導通しました。

ソフトウェア開発

おなじみの GitHub - cnlohr/ch32v003fun: Open source minimal stack for the ch32 line of WCH processors, including the ch32v003, a 10¢ 48 MHz RISC-V Microcontroller - as well as many other chips within the ch32v/x line. を使って開発しました。

以前以下の2つの記事で使ったプログラムを組み合わせることで、一応鍵盤を押すと音が鳴るという動作を実現できました。

inajob.hatenablog.jp

inajob.hatenablog.jp

動作デモ

ソフトウェアを作りこめば和音も鳴らせるはずですが、今のところ単音のみ実験しています。

まとめ

とりあえず当初の目的であった「名刺基板」を設計し、それっぽい動作が出来るところまでこぎつけることが出来ました。

CH32V003を使った基板も何枚か作って、知見がたまってきてスムーズに設計ができるようになってきていると感じました。

不具合もたくさんあったので、もう一度似たようなものを作ってみたいです。

自作電子楽器RakuChordをRasoberry Pi Picoで作ってみた

この記事ははJLCPCBの提供でお送りします。

またJLCPCBのブログとほぼ同じ内容です。

JLCPCBとは

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

JLCPCBとは、プリント基板製造などで有名な香港の企業です。

日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。

値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。

これは何?

もともとArduino UNOなどで用いられているATmega328をメインCPUとしたものでした。 しかし昨今半導体の高騰や新しい組み込み向けのCPUの登場により、ATmega328以外の選択肢も模索したいという気持ちが高まってきました。

以前、基板を乗っ取る形でRaspberry Pi Picoを接続して、動作確認をして、ある程度動きそうなことが確認できたので、今回はこれもとに専用の基板を作ってみました。

inajob.hatenablog.jp

基板の設計

前回記事では、RP2040-Zeroという開発ボードを利用しましたが、今回はRaspberry Pi Picoを使ういました。

RakuChordの28個あるスイッチの配線などは、従来のものと同じなのでかなりの部分で設計を流用できました。

オーディオアンプは従来はLM386だったのですが、NS8002を採用しました。

NS8002はグリッド楽器igetaを作った - inajob's blogでも紹介しましたが、この時は必要な周辺部品が実装されているモジュールを利用しましたが、今回は直接RakuChordの基板にNS8002とその周辺部品を実装する方式としました。

この方が、今後PCBAなどを考えたときにコストが下がると思います。

実はこのNS8002を直接実装する方式は、グリッド楽器igetaを作った - inajob's blogで作成した基板でテストしていました。igetaの基板はモジュール式のNS8002でも、直接NS8002を実装する方式でも、どちらでも動作するようになっているということです。

こういう細かい実験を基板の隙間で行うことで、小さな検証をしています。(実はigeta-picoのNS8002回路には誤りがあり、直接NS8002を実装すると期待通り動かなかったのですが、まさにこういうことが検証できる、ということです)

ボリュームや、オーディオジャック、電源スイッチ、OLED、タクトスイッチ、などは今までのRakuChordを作ってくる中で実績のあるものを採用しています。

このあたり、同じようなものを作り続けていると過去の経験が生かせて良いですね。

電源は単4電池を3本、基板に直接電池ケースをマウントできるようにしました。

基板は10cm * 10cmに収まるように設計しました。

基板上の部品の配置は、乾電池やRaspberry Pi Picoがかさばるので、自由度が低く、まぁこんなもんでしょ、という感じで、並べていきました。 配線はFreeroutingにお任せなので、あまりきれいではありません(動くからヨシ!)

また、RakuChordの基板は様々なリビジョンを作ってきているので、わかりやすいように、シルクに大きく「RakuChord-RP2040」と入れてみました。

JLCPCBに発注

今回も発注はJLCPCBです。今回の基板は青色にしてみました。

10cm×10cm以内なので、非常に安く作ることが出来ます(5枚で$2 + 送料)

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

実装

さて、今回もトラブルがいくつか・・

キースイッチの配線ミス!

またやってしまいました、配線ミス。 KiCADで配線を交差させるときに、意図せず飛び越したつもりの配線とくっついてしまうという、よくある凡ミスにより、今回もキースイッチ周りの配線がおかしいです。

かなり大規模におかしくなってしまったので、いっそ基板を発注しなおそうかとも思いましたが、何とかパターンカットと配線のやり直しにより、修復しました。(大変だった・・)

Raspberry Pi Picoを直接実装していたため、追加での配線がやりやすかったのは救いでした。

Raspberry Pi Picoをピンヘッダで実装すると電池ボックスに干渉する

Raspberry Pi Picoは端面スルーホールで、ペタッと表面実装的に実装することもできますし、普通にピンヘッダで実装することもできる開発ボードです。

今回はどちらの方式でも実装できるようなフットプリントを選んだのですが、スルーホールで実装する場合に、裏面にピンの足が飛び出してしまうため、電池ボックスと干渉してしまう問題がある事がわかりました。

まぁ、電池ボックスを多少浮かせて取り付けることで、回避できますが、ちょっと不格好ですし、ぐらぐらすることで、接触不良が起きそうで心配です。

基板をこのままでいくなら、電池ボックスと基板の間に3Dプリンタなどでスペーサーを作って挟み込むなどをするとよいかなと考えています。

スピーカーが小さすぎる

これは、事前の検証でもある程度分かっていたのですが、表面実装の小さなスピーカーでは、単音ならまだしも、和音を鳴らそうとすると、音が小さすぎるか、割れてしまうか、という感じで期待した音が鳴りませんでした。

今回は3.5mmのオーディオジャックや、スピーカーを接続するためのピンヘッダを付けているので、そちらを使ってもう少し大きなスピーカーやイヤホンに接続するなどして、回避することが出来ました。

基板完成

さて、色々問題もありましたが、何とか解決して、動作するようになりました。

まぁ事前に従来のRakuChord基板+RP2040-Zeroで検証していたので、ソフトウェア面では、困ることはほとんどなかったです。

3Dプリンタによるケースの作戦

RakuChordは楽器なので、演奏しやすい形である必要があるのですが、基板むき出しでは、どうにも演奏しづらい、というか裏面のとげとげした配線が危険すぎて、演奏どころではありません。

ということで、裏面を雑に覆うような簡単なつくりのケースを3Dプリンタで作ることにしました。

今回のケース作成手法は表面実装部品版RakuChordの改良版を作った - inajob's blogと同じく、KiCADのユーザーレイヤーでケースの凸凹をデザインし、プログラムで3Dデータを作る方式です。

以前の記事ではOpenSCADを利用していましたが、今回はCadQueryを使うことにします。

CadQueryはPythonを使って3Dデータを作ることが出来るライブラリで、OpenSCADと比べるとフィレットや面取りを定義しやすいことが好きで、最近よく使っています。

個人的には、記述のシンプルさや直観性ではOpenSCAD、自由度の高さはCadQueryかなと感じています。

とはいっても、今回は凝ったことはせず、KiCADからexportしたDXFファイルを基に、押し出しや削り取りを行い、非常にシンプルなケースを作成しました。

演奏デモ

www.youtube.com

まとめ

Raspberry Pi Picoを用いて、自作電子楽器RakuChordを実装してみました。

過去の様々な取り組みのおかげで、比較的スムーズに設計することが出来ましたが、それでも細かいミスが多数あり、いきなり完璧なものを作るのは難しいなと感じています。

3Dプリンタによる簡易的なケースづくりのノウハウも安定してきて、この程度であれば、さっと作ることが出来るようになりました。

RakuChordについては、今後も試行錯誤を続けていくつもりです。今回発見した課題を解決し、持ちやすさや演奏しやすさをさらに改良していきたいと考えています。

乾電池一本で動く画面付き電流計を自作した

この記事ははJLCPCBの提供でお送りします。

またJLCPCBのブログとほぼ同じ内容です。

JLCPCBとは

jlcpcb.com (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

JLCPCBとは、プリント基板製造などで有名な香港の企業です。

日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。

値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。

この記事の作例もJLCPCBに基板を発注して実現しました。

どういうもの?

以前JLCPCBに発注して作った「Arduino Nanoを単4電池で動かすボード」を活用して、便利な電流計を作ってみました。

inajob.hatenablog.jp

自分が持っているテスターにも電流を測定する機能はあるのですが、その瞬間に流れている電流を数値として表示するだけのシンプルなものでした。

今回作成したのは、グラフィカルな画面を持つ電流計で、ここしばらくの電流の変動を時系列のグラフで表示するというものです。

Arduino Nanoを単4電池で動かすボード」は名前の通り乾電池1本で動かすことが出来るので、USBケーブルの接続などなしで、普通のテスターと同じような使い勝手で利用できる便利な電流計を実現しています。

パーツ紹介

Arduino Nanoを単4電池で動かすボード」を本体として、それにINA219という電流計のICを搭載したモジュールを搭載しました。

制御はI2Cとなっており、Arduinoから簡単に利用できるライブラリも公開されているのでソフトウェアの開発も簡単でした。

ソースコード

すごく素朴に電流の時系列グラフを表示するプログラムです。 これを基に様々な機能を持った電流計を作ることが出来そうです。

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
int index = 0;

void setup() {
  Serial.begin(9600);
  u8g2.begin();
  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { delay(10); }
  }
  u8g2.clearBuffer();
}

void loop() {
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);

  index = (index + 1)%128;
  char bbuf[8];
  dtostrf(current_mA, 5,2, bbuf);
  char currentbuf[16];
  sprintf(currentbuf, "%smA", bbuf);

  dtostrf(loadvoltage, 5,2, bbuf);
  char loadbuf[16];
  sprintf(loadbuf, "%sV", bbuf);
  
  u8g2.setFont(u8g2_font_ncenB08_tr);   // choose a suitable font

  u8g2.setDrawColor(0);
  u8g2.drawBox(0,0,128,10);
  u8g2.drawBox(index,0,1,64);
  u8g2.setDrawColor(1);
  u8g2.drawBox((index + 128 + 1)%128,10,1,63-10);
  u8g2.drawPixel(index, 63 - (int)(current_mA * 64/10)); // max 10mA
  Serial.println(63 - (int)(current_mA * 64/10));
  u8g2.drawStr(0,10,currentbuf);
  u8g2.drawStr(64,10,loadbuf);
  u8g2.sendBuffer();
  delay(10);
}

OLEDの制御には同じみu8g2を利用しました github.com INA219モジュールの制御には以下のライブラリを利用しました github.com

感想

以前作った、「Arduino Nanoを単4電池で動かすボード」の活用例として画面付きの電流計を自作しました。

電流計のプログラムを自分で作ることが出来るというのは、自分の使う道具の痒い所に手が届く感じでなかなか便利なことだと感じました。普段使っている既製品を、自分でプログラミングできるものとしてとらえなおすというのはとてもワクワクします。

電流計の機能的にはArduino NanoそのものやArduino UNOを使っても同じことが出来ますが、乾電池1本で画面付きで・・となってくるとこの「Arduino Nanoを単4電池で動かすボード」が非常に便利であることが実感できました。

安価で、バッテリー駆動ができ、画面もついている開発ボード、これが1つあるとちょっとしたガジェットのプロトタイピングが簡単にできると感じており、この方向でもう少しブラッシュアップした開発ボードを作っていきたいなと感じました。

Raspberry Pi PicoとCircuitPythonで和音楽器を作る

この記事ははJLCPCBの提供でお送りします。

JLCPCBとは

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

JLCPCBとは、プリント基板製造などで有名な香港の企業です。

日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。

値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。

この記事の作例はJLCPCBに基板を発注して作成した、以前の基板を更に活用した内容です。

inajob.hatenablog.jp

これは何?

私が作っているRakuChordは、もともとArduino UNOなどで用いられているATmega328をメインCPUとしたものでした。 しかし昨今半導体の高騰や新しい組み込み向けのCPUの登場により、ATmega328以外の選択肢も模索したいという気持ちが高まってきました。

ということでこの記事ではRaspberry Pi Picoに搭載されていることでおなじみのRP2040を使って和音楽器を作る方法について紹介します。

Raspberry Pi Picoでのプログラミング

今回利用するのはRP2040-Zeroという開発ボードで、厳密にはRaspberry Pi Picoとは異なります。 しかし回路の構成はほぼRaspberry Pi Picoと同じなので、Raspberry Pi Picoでもほぼ同じように和音楽器を作ることができるはずです。

Raspberry Pi Picoに搭載されているRP2040は、ATmega328などの8bit CPUと比べるとかなりパワフルなマイコンです。 C/C++での開発はもちろんできますがMicroPythonやCircuitPythonなどのインタプリタ言語も動作します。

今回は和音楽器の作成にあたり、CircuitPythonを使うことを選択しました。

C/C++と違い、インタプリタ型のCircuitPythonでの開発は、少し変更して実行してみるというトライ&エラーがやりやすく、高速に開発することができると感じました。 最終的にパフォーマンスの要件などでC/C++を使うとしても、プロトタイプとしてCircuitPythonを使って動作検証を行うのはかなりアリだと思います。

CircuitPythonで和音を鳴らす

CircuitPythonはインタプリタ方式のプログラミング言語で、C/C++と比べると明らかに実行速度が遅いです。 そのため、音の生成、特に和音の生成などをCircuitPythonの層で実装することは現実的ではありません。

しかしCircuitPythonには標準の組み込みのモジュールとしてsynthioという和音をサポートして音源ライブラリが搭載されており、これを利用することで、気軽なインタプリタ方式のプログラミング言語で、高速動作が要求される和音の生成を実現することができます。

synthio

RP2040で動作するPythonの実装としては有名なのはMicroPythonとCircuitPythonがあります。これらはそれぞれ微妙に違った特性を持っていますが、今回CircuitPythonを選択したのは、CircuitPythonには組み込みライブラリとしてsynthioがあったからです。

このライブラリは音を鳴らすためのもので、今回やりたい和音の生成もサポートしています。

docs.circuitpython.org

配線

synthioはDAC出力とPWM出力をサポートしています。今回は追加部品が不要なPWM出力を利用します。 このために出力ピンは適切なRCフィルタを構成のが定石のようですが、ちょっと試す分には、深く考えずスピーカやオーディオアンプを直接繋いでも動作を確認できます。 参考元の資料では1kΩの抵抗と100nFのコンデンサでRCフィルタを作成していました。

単音を鳴らしてみる

以下のようなシンプルなソースコードでファの音を0.5秒毎にON/OFFできます。

import board, time
import synthio

import audiopwmio
audio = audiopwmio.PWMAudioOut(board.GP10)

synth = synthio.Synthesizer(sample_rate=22050)
audio.play(synth)

while True:
    synth.press(65) # midi note 65 = F4
    time.sleep(0.5)
    synth.release(65)
    time.sleep(0.5)

from GitHub - todbot/circuitpython-synthio-tricks: tips, tricks, and examples of using CircuitPython synthio

和音を鳴らしてみる

和音を鳴らすのも単音と同じようにできます。

import board, time
import audiopwmio
import synthio

audio = audiopwmio.PWMAudioOut(board.GP10)
synth = synthio.Synthesizer(sample_rate=22050)
audio.play(synth)

while True:
  synth.press( (65,69,72) ) # midi notes 65,69,72  = F4, A4, C5
  time.sleep(0.5)
  synth.release( (65,69,72) )
  time.sleep(0.5)

from github.com

キー操作に対応して音を鳴らしてみる

ここまでの例は無限ループでsleepさせて音を鳴らしていましたが、ここをキーの入力判定に書き換えればキー操作に対応して音を鳴らすことが出来る、いわゆる「楽器」を作ることが出来ます

この例ではRaspberry Pi PicoのGPIO2番にタクトスイッチつながっており、スイッチを押下することでGNDとショートするような回路を想定しています。

import board, time
import audiopwmio
import synthio

audio = audiopwmio.PWMAudioOut(board.GP10)
synth = synthio.Synthesizer(sample_rate=22050)
audio.play(synth)

p1 = digitalio.DigitalInOut(board.GP2)
p1.direction = digitalio.Direction.INPUT
p1.pull = digitalio.Pull.UP
isPlaying= False

while True:
  if p1.value == False and isPlaying== False:
    synth.press( (65,69,72) ) # midi notes 65,69,72  = F4, A4, C5
    isPlaying= True
  else:
    if isPlaying== True:
      synth.release( (65,69,72) )
      isPlaying= False

和音を鳴らす以外の処理が複雑になると音が途切れてしまう問題の対処

さて、ここまでで電子楽器を作るための準備が整いました。 しかし、楽器を作りこんでいくにしたがって、音を鳴らす以外の処理が増えてきます。前述のキーの入力検出に始まり、画面の制御なども実装していくと、だんだん生成される音にノイズが混じるようになってきます。

これはsynthioの音波の生成がほかの処理により遅れてしまい、音の再生スピードに追い付かなくなることから発生するようです。

根本的には、音波の生成以外の処理を減らせば、この問題は起きませんが、もっと処理を詰め込むことは出来ないでしょうか?

こんな時に役立つのがsynthioのバッファリング機能です。

synthioでは、生成する音波をバッファにためておく機能があり、これを使うことで、少しほかの処理が複雑になっても、バッファにためておいたデータの分だけ時間に余裕が出来ます。

ただ、バッファを大きくすればするほど、音の生成にラグが生じるので、バッファの大きさには注意が必要です。楽器として使いやすくするうえではバッファをなるべく小さくして、キーを入力したらなるべく早く音が鳴ってくれる方がが扱いやすいので、ここは操作性とのトレードオフとなります。

import board, time
import audiopwmio
import audiomixer
import synthio

audio = audiopwmio.PWMAudioOut(board.GP10)

# ここからがバッファリングの処理
mixer = audiomixer.Mixer(sample_rate=22050, buffer_size=2048) # ここの2048を大きくするとバッファを大きくできる
synth = synthio.Synthesizer(sample_rate=22050)
mixer.voice[0].play(synth)
mixer.voice[0].level = 0.25 # 音量の調整もできる
# ここまでバッファリングの処理

p1 = digitalio.DigitalInOut(board.GP2)
p1.direction = digitalio.Direction.INPUT
p1.pull = digitalio.Pull.UP
isPlaying= False

while True:
  if p1.value == False and isPlaying== False:
    synth.press( (65,69,72) ) # midi notes 65,69,72  = F4, A4, C5
    isPlaying= True
  else:
    if isPlaying== True:
      synth.release( (65,69,72) )
      isPlaying= False

OLEDの制御

さて、ここまでで和音楽器として実用的なものが作れるようになりましたが、私の作ろうとしている楽器には128x64のI2C接続のOLEDが搭載されており、キーの入力に合わせてOLEDの表示も変更する必要がありました。

CircuitPythonは組み込みのライブラリではOLED制御をするためのものが含まれていないのでOLEDを制御するためのライブラリを導入します。

OLED制御のライブラリはCircuitPython Library Bundleという標準的なライブラリ集に含まれているので、これをダウンロードします。

Libraries

この中に含まれるファイルをRaspberry Pi Picoのファイルシステムにコピーします。 adafruit_framebuf.mpy, adafruit_ssd1306.mpylib以下に、font5x8.binをルートに配置します。

ここまで準備すれば、以下のようなプログラムでOLEDに文字を表示できます。

import board
import busio
import adafruit_ssd1306

i2c = busio.I2C(board.GP11, board.GP10)
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
oled.text("Hello World!",20,5,1)
oled.show()

OLEDの表示と和音生成の両立

しかし上記の方法でOLEDを制御しつつ音を鳴らそうとすると、画面表示にCPU処理を使いすぎてしまい、かなり大きなバッファを設けないとノイズが発生してしまう問題が起きました。

しかし、バッファを大きくすると前述のようにラグが大きくなり、実用に耐えない楽器となってしまうという問題があります。

色々調べているうちに、OLEDの画面転送のオプションを変更し、1つの画面をいくつかに分割して更新することで、バッファを小さく保ったままノイズのない音を生成することが出来ました。

これは、OLEDの画面転送を分割することで、その隙間にsynthioの音波生成の処理を実行することが出来るようになるからだと考えています。

副作用として画面の更新が少し遅くなりますが、楽器を操作するうえで気になるほどではありませんでした。

import board
import busio
import adafruit_ssd1306

i2c = busio.I2C(board.GP11, board.GP10)

# page_addressing=True により画面更新を分割する
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, page_addressing=True)
# なぜか手元のOLEDだと表示位置がずれるので微調整
oled.page_column_start[1] = oled.page_column_start[1] -4
oled.text("Hello World!",20,5,1)

# page_addressingの設定を変更したのでこのshowの中身の動作が変わり、画面更新を分割して実行する
oled.show()

ATmega328用の基板を流用してRP2040の動作の確認をする

ここまでで、ソフトウェア的にRakuChord的なものをRP2040で実行できる目途が立ちました。

ここからは、ハードウェア的にRakuChord的な構成を作り、動作検証をしていきたいので、このために新たに基板を作る必要がありそうです、、、が、、

そういえば以前表面実装部品版RakuChordの改良版を作った - inajob's blogの記事で作成したRakuChordは、キー入力のためのピンを引き出して設計していたので、この基板を流用して、RP2040の開発ボードと無理やりくっつけることで、ハードウェア的な動作確認もできるのでは?と考えました。

その結果がこちら!

動画はこちら

www.youtube.com

21個のキーの入力を受け付けるために3*7のマトリクスで処理しているので、全部で10本の信号線と電源の線をつなげる必要があり、こんな風にモジャモジャになりました。アンプやスピーカーもつなげました。

これで、RP2040をコアとしたRakuChordの試作機が完成しました。

こんなこともあろうかと、キー入力のパッドを引き出しておいてよかったです。

で、実際にRakuChord的なソフトウェアをCircuitPythonで作って、触ってみたところ、、特に問題なく動作しそうでした。

さて、次はこの構成を踏まえてRP2040をコアとしたRakuChordの基板を発注するぞ!という気持ちです。(それはまた別の話と言うことで・・)

まとめ

今までATmega328を使っていたRakuChordのCPUをRP2040かつCircuitPythonに変更できるかを色々検証しました。

C/C++に比べるとパフォーマンスの低いCircuitPythonでも、工夫すれば音の生成とOLEDの描画が出来そうなことがわかりました。

CircuitPythonでの開発は非常に手軽なので、簡単な電子楽器を作ろうと考えている方にはとてもお勧めの手法です。

また、過去に作成したATmega328用のボードの「こんなこともあろうかと」用意しておいた拡張端子をうまく利用することで、新たに基板を設計する前に、動作確認することが出来ました。

参考

Synthioの活用法については以下のリポジトリが参考になりました

github.com

UARTで書き込みできるCH32V003開発ボードを作った

この記事ははJLCPCBの提供でお送りします。

JLCPCBとは

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

JLCPCBとは、プリント基板製造などで有名な香港の企業です。

日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。

値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。

この記事の作例もJLCPCBに基板を発注して実現しました。

これは何?

以前CH32V003を使った基板を作って遊びました。今回はその時の知見を活かして、UARTで書き込みできるCH32V003開発ボードを作成してみました。

inajob.hatenablog.jp inajob.hatenablog.jp

仕様

この基板は何か専用の機能を持つものではなく、汎用的な開発基板です。

  • CH32V003F4P6
  • USBコネクタ(フットプリントのテストのため3種)
  • USBシリアル変換IC CH340G
  • RSTスイッチ、BOOTスイッチ
  • 自動リセット回路(ESP32などの回路をまねたもの)
  • WCH-LinkE接続用端子

基板の設計

今回の基板は以前作ったCH32V003の基板とよく似たものですが、USBシリアル変換ICとRSTスイッチ、BOOTスイッチが搭載されているのが特徴です。 また、Arduinoではおなじみの自動リセットの仕組みを実現するための回路も搭載しています。

今回利用するファームウェアは、起動時にPC0の状態を読み取り、LOWであれば書き込みモードに入るという動作をするものです。 これを実現するためにBOOTスイッチを搭載しています。つまり、BOOTスイッチを押しながらRSTスイッチを押すことで書き込みモードに入るということです。

CH32V003のUART書き込みのサンプルは、PC0がHIGHであれば書き込みモードに入るような作りになっていますが、ここではESP32などで良く用いられる自動リセット回路をまねて作る関係でこの動作を変更してLOWであれば書き込みモードに入るという作りに変更しました。

さらにこの基板で特徴的なのは3つのUSBポートです。 これは何か3つに特別な機能がある、というわけではなく、手元にある3種類のUSBソケットの実装練習のためのものです。

3つのうち2つがUSB Type-Cのソケットなので、CC1、CC2ピンのための抵抗も配置します。(この抵抗が無いとType-C -> Type-Cケーブルを使った時に給電されないことが起きるようです)

JLCPCBに発注

今回も発注はJLCPCBです。基板は赤色にしました。また基板の厚さを1mmにしています。

jlcpcb.jp (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

動作確認のための実装

CH340GはArduino Nanoのクローンなどでよく利用されているICで、自分もそのような基板を自作したことがあるので、難なく実装できました。 CH32V003F4P6も前回の挑戦ではんだ付けしたことがあったので、こちらも簡単。

MicroUSBコネクタはよく使うのですが、なかなか実装のコツがつかめず、よく接続不良を起こしてしてしまいます。ホットエアーガンを使い今回は(たまたま)一発で動作しました。

ということで、あっという間に実装できました。

自動書き込み回路や、あと2つのUSBコネクタの実装は後回しです。

ブートローダーの準備と、書き込みテスト

CH32V003でさらに遊んでみた - inajob's blogで紹介した74thさんのファームウェアを少し改造して利用しました。 74thさんのものは書き込みモードに入る際にPC0をHIGHにする必要がありましたが、今回はPC0がLOWのときに書き込みモードに変更したものを用意しました。

このファームウェアをWCH-LinkEを使いブートローダー領域に書き込めば準備は完了です。

基板上のMicro USB端子をパソコンとつなげ、BOOTスイッチを押しながら、RSTスイッチを押して書き込みモードにしたのちに、74thさん作のCLIツールを使い適当なプログラムを書き込み、最後にRSTスイッチを押して、実行モードにすれば、書き込んだプログラムが動き始めます。

USBソケットの実験

前述したようにこの基板には3つのUSBソケットのフットプリントがあります。

Micro USB

いつものソケットです。ここまでの実験ではこのソケットを使い接続しています。 このソケット、実装の難易度はそこそこ高く、個人的にははんだごてではうまく実装できず、ホットエアーで実装しています。

いつも使っているのですが、Micro USBということで、稀にコネクタが「もげ」るという事故が起きます。 ということで、そろそろ自分もUSB Type-Cのコネクタを試してみたいなと考えていました。

そこで出てきたのが次の2つのUSB Type-Cソケットです

USB Type-C(スルーホール)

スルーホール型のソケットです。後述の表面実装のものと比べると価格が高いのですが、実装しやすそうだなと思い、今回試してみることにしました。

スルーホール型ではあるのですが、足がそこまで長くないため、一般的な厚さ1.6mmの基板では足が下まで届かないので、はんだ付けが難しいようで、今回は厚さ1mmの基板としました。

スルーホールとはいえ、かなりピンが近くにあるので、はんだ付けは気を遣いましたが、何とかはんだごてで実装し、動作することを確認しました。

USB Type-C(表面実装)

よく見かけるソケットです。ピンの幅が狭く、実装の難易度が高そうに見えます。 はんだごてで実装するとすぐにブリッジ思想だったので、ホットエアーを使って実装しました。

フットプリントは以下の記事を参考にして、いくつかのパッドを長くすることで、はんだ付けしやすいようにしました。

inajob.github.io

心配しましたが、こちらも動作することを確認しました。

自動書き込み回路の動作確認

最後に、ESP32などの開発ボードでよくみられる、トランジスタを2つ使った、自動書き込み回路の動作を確認しました。 この回路は抵抗付きのトランジスタが2つ内蔵されたUMH3Nという部品により実現されます。(この部品は以前ESPboyというオープンソースの携帯ゲーム機を日本用に再設計してみた - inajob's blogで利用したことがありました)

ちょっと小さな部品ですが、これを実装します。

このトランジスタ2つをうまく組み合わせて、USBシリアル変換ICの~DTR, ~RTS信号を、CH32V003のリセット信号と、書き換えモード切替信号(PC0)への入力に変換します。

ESP32などでは書き込みツールがDTR、RTS信号をうまい具合に制御してくれるのですが、今回はそういうツールが無いので、Pythonスクリプトを用意して、書き込みモードへの切り替えの動作を実現しました。

具体的には以下のようなコードで書き込みモードに入ります

import serial
ser = serial.Serial()
ser.port = "COM14" # 利用するポートの番号
ser.baudrate = 115200

# Write mode
ser.setDTR(True)
ser.setRTS(False)
ser.open()
ser.close()

そして以下のようなコードで実行モードに入ります

import serial
ser = serial.Serial()
ser.port = "COM14" # 利用するポートの番号
ser.baudrate = 115200

# Run mode
ser.setDTR(False)
ser.setRTS(True)
ser.open()
ser.close()

これと74thさん作のCLIツールを組み合わせると、Arduino風の書き込み環境となります。

まとめ

ということで、一度ブートローダーを用意してしまえば、後は開発基板のみで書き換えができる基板が完成しました。

まぁ、CH32V003でやるならこの方法ですが、もう一つ上のスペックのCH32V203などではIC単体でUSB書き込み機能を備えているので、あえてCH32V003でここまでする意味はないかもしれませんが、構成例の一つとして、誰かの役に立てば幸いです。

また、自動リセット回路について、CH32V003でも期待通り動くことが確認できました。

おまけとして、3種類のUSBソケットの実装実験が出来ました。ホットエアーガンがあればどのソケットもそこまで難しくなく実装できることが確認できました。

参考

自動リセット回路の動作原理について詳しく説明されています days-of-programming.blogspot.com

前回記事に続き 74th.hateblo.jp

CH32V003でさらに遊んでみた

この記事ははJLCPCBの提供でお送りします。

JLCPCBとは

jlcpcb.com (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)

JLCPCBとは、プリント基板製造などで有名な上海の企業です。

日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。

値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。

この記事の作例もJLCPCBに基板を発注して実現しました。

前回までのあらすじ

以前作った基板を流用して CH32V003 で遊んでみることにしました。

inajob.hatenablog.jp

CH32V003F4P6を自分ではんだ付けしてみる

前回の記事では、CH32V003の開発ボードを使ったため、CH32V003F4P6を直接はんだ付けすることはしませんでした。

しかし、この基板は開発ボードでも、ICを直接実装するでも、どちらでも動作するように作っていたので、今回は直接のはんだ付けを試してみました。

表面実装でピンの間は0.65mmでこれが10*2=20か所はんだ付けします。

うまくはんだ付けできるか心配でしたが、意外と簡単にはんだ付けできました。

過去の実績としてはATmega328が0.8㎜ピッチで32か所というのがありましたが、これと比べると今回のはんだ付けは簡単でした。

比較するとこんな感じ

というのも、ATmega328はICの4辺すべてに足が出ているQFPと呼ばれるパッケージで、今回の物は2辺に足が出ているTSSOPと呼ばれるパッケージだったというのが大きいです。

分析するに、QFPの方はICの向きが少しずれるとどこかの辺のピンがパッドからずれてしまうのに対し、TSSOPの方はピンのある辺に水平にずれる分には問題ないというのが原因だと感じました。

ピッチは今回のICの方が細かかったですが、その点はあまり気になりませんでした。

温調付きのはんだごてと、フラックスがあれば比較的簡単だと思いますので、挑戦する方はこれらの機材をそろえると良いと思います。

最低限動作に必要な部品

改めて回路を見直してみると、このICは周辺の部品は、ほぼ何もなくても動くことがわかりました。 開発ボードには水晶発振子が付いていましたが、ICの内部にも発振機能があるようで、精度が多少悪くなりますがこちらを使うようにすれば、水晶発振子は不要でした。

いわゆる「おまじないコンデンサ」と言ったりするパスコン(バイパスコンデンサ)を一応1つ取り付けました。

ここに写っている部品のみでOK

書き込み

書き込みは開発ボードを使った時と同様にWCH-LinkEという専用の書き込み機を使いました。 ソフトウェアは前回の記事で紹介したch32v003funを利用しました。

専用書き込み機を使わずに書き換える方法

WCH-LinkEを使わないと書き換えられないのが少し気になって、調べてみると、WCH社が公式のサンプルとしてUART経由でプログラムを書き換えることが出来るサンプルプログラムを公開していることを知りました。

github.com

UARTを使って書き換えるといえば、よく知られている例だとArduino UNOなどの方式です。

この方式は、素朴ですが、ボード上にUSBシリアル変換ICを搭載することで、そのボード単体で開発が完結するという点で魅力的です。 (もちろん一番初めにこのプログラムを書き込むためにWCH-LinkEが必要なのですが、一度書き込んでしまえば以降はUARTで書き換えることが出来ます。)

さらに、このWCH社が提供しているサンプルの細かい問題点を解消したものを74thさんが作っているのを発見したので、今回はこちらを利用しました。

github.com

WCH-LinkEにはUSBシリアル変換の機能も搭載されているので、この書き換えの仕組みもWCH-LinkEで動作確認できました。また念のため手元にあったCH340G搭載のUSBシリアル変換モジュールを使っても書き換えが出来ました。

書き込みのためにはPC側で動作する書き込みソフトが必要となります。WCH社公式のWindows専用ツール74thさん作のCLIツールの2つがありますがどちらでも書き込みできました。

RSTスイッチでリセットされない問題

74thさんが改良したプログラムでは以下の2つの変更が加わっていました

  • UART通信の精度を上げるため書き込み速度を115200に低下させる
  • 書き換えモードに入るためのピンをプルダウンし、ピンに何もつながっていないときは、実行モードとする

これで随分使いやすくなっていたのですが、74thさんのブログでも言及されているのですが、RSTスイッチの挙動が少し期待と異なるという問題が残っていました。

RSTスイッチは私の利用している開発ボードではタクトスイッチと接続されており、このスイッチを押すことでマイコンボードを「リセット」しプログラムをはじめから実行しなおすことができます。

UARTで書き込みを実現するプログラムは、起動時に特定のピンの状態を確認し、それがHIGHであれば書き込みモードに入り、LOWであれば実行モードに入るというロジックとなっています。

こういう書き込みロジックはESP32などでも採用されており、このようなボードにはBOOTスイッチとRESETスイッチが搭載されていることが一般的です。

BOOTスイッチを押しながらRESETスイッチを押すことで書き込みモードで起動し、BOOTスイッチを押さずにRESETスイッチを押すと、実行モードで起動するというのが期待する動作です。

もちろん手でスイッチを操作する以外にも、USBシリアル変換ICのDTRやRTSの信号をうまく使って、自動的に書き込みモードに入るというようなことも行われたりします。

さて、今回のUARTで書き込みを実現するプログラムを利用する際、このRSTスイッチはどのようにふるまうかというと・・

  • 書き込みモードで起動中
    • RSTスイッチを押すと、実行モードで起動する
    • 書き込みピンをHIGHにしてRSTスイッチを押すと、書き込みモードで起動する
  • 実行モードで起動中
    • RSTスイッチを押すと、再び実行モードで起動する
    • 書き込みピンをHIGHにしてRSTスイッチを押しても、再び実行モードで起動する(ここがおかしい!!)

実行モードで起動中に、書き込みピンをHIGHにしたときに、書き込みモードに移行せず、実行モードとなってしまうことが期待と違うと感じました。

この原因を調べるためにソースコードを見てみると、UARTで書き込みを実現するプログラムは以下のように実装されているようでした

  • UARTで書き込みを実現するロジックはFlashメモリのBOOT領域に書き込まれている
  • BOOT領域の処理の一番初めに書き込みピンの状態を確認するロジックがある
    • ここでLOWが検出されると、User領域から実行するフラグを立ててソフトウェアリセットをする
  • User領域を実行中にRSTスイッチによるリセットが起きても、User領域から再実行される

というような動きをしているようでした。(データシートで細かい裏付けをしているわけではなく、あくまで挙動から推測した動きです)

ということで、以下のような処理をUser領域に書くことで、User領域を実行中にRSTスイッチによりリセットされたときにBOOT領域の処理が実行されるようにしてみたところ、期待通りに実行モードで起動中にRSTスイッチを押した際に、書き込みモードで起動することが確認できました。

   if(RCC->RSTSCKR & RCC_PINRSTF){ // リセットボタンを押されて起動した場合に真となる
     FLASH->BOOT_MODEKEYR = FLASH_KEY1;
     FLASH->BOOT_MODEKEYR = FLASH_KEY2;
     FLASH->STATR |= (1<<14);
     NVIC_SystemReset();
   }

要は、UARTで書き込みする対象のプログラムに、おまじない的に、このロジックを入れておけば良いということです。

さて、今回はここまでの調査で打ち切りましたが、この先はUSBシリアル変換ICを搭載した基板を作ったり、RSTやDTRで自動プログラム機能を作りこんだ書き込み用のプログラムを作ったりすると、Arduinoっぽく書き込みできる仕組みが作れそうです。

そこまでしてUARTで書き込みしたい?

ここで調査を打ち切ったのは、CH32V003をどこまで頑張って使い倒すか?ということを考えたからです。

実はCH32VシリーズのCH32V203は、CH32V003よりは高いですが、その分スペックも良く、USB経由でのファームウェア書き込みもサポートしています。

ここまでCH32V003をArduino的に書き換える方法を探ってきましたが、そんなに頑張らなくともCH32V203を使えばよいのでは・・?という気がしてきました。

ということで、近いうちにCH32V203を購入して、その使い勝手を確かめてみることとします。

日本で買うなら RISC-V MCU CH32V203 ProMicro Like 開発ボードキット(¥1,500) [74th-034] - 74th Books & Gadgets - BOOTH、AliExpressでもいくつかの開発ボードを見つけることが出来ます。

まとめ

前回記事では、開発ボードを利用していましたが、ICを直接基板に実装する方法も試すことが出来ました。

これにより開発ボードに頼らずに、スタンドアローンなガジェットを作れるようになりました。

Arduino互換のSDKも整備されてきているようなので、次何か作る時の候補に入れておくことにします。