自作電子楽器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も整備されてきているようなので、次何か作る時の候補に入れておくことにします。

2023まとめ

今年もいろいろなことがありました。

毎年恒例ですがまとめていきます。

ピックアップニュース

ポッドキャストを始めた

5月ごろから#inajob の試しに録音してみた を始めました。なんだかんだでほぼ毎週配信できています。

open.spotify.com

ポッドキャスト仲間とのコミュニケーションが出来たり、音声編集のテクニックが身についたり得るものが多くありました。

また、ポッドキャストをよく聞くようにもなり、お気に入りのポッドキャストもたくさんできました。 副次的な効果として、日記をしっかり書くようになり、日々をより噛み締めて生活できるようになり、人生を濃くすることが出来ていると感じます。

ChatGPTを活用し始めた

このブログではあまり紹介していませんでしたが、自分の日記をChatGPTに分析させたり、omoikaneに参加して、ChatGPTを使ったSFプロトタイピングを体験したりしました。

このあたりの話は以下のポッドキャストのエピソードでも話しています。

open.spotify.com

PASMOがバズる

誤ってPASMOを洗濯機に投入してしまい、破片しか残らなかったエピソードがバズりいくつかのメディアで記事にしてもらいました。 平和な内容でバズるのはまぁインターネットと言う感じで面白かったです。

nlab.itmedia.co.jp

ステータス

  • 今の家に引っ越してから7年目
  • 会社に入ってから14年目
  • 結婚して7年ちょっと
  • 娘が生まれて3年目

子供がいる生活にもだんだんと慣れてきて、そういった環境でもできる新たな挑戦などにも取り組めていると思います。引き続きやっていこう!

今年学んだスキル

今年は技術的なところというよりは、家族周りのスキルアップも多かった年でした。 親の介護なんていう次なる課題も見えてきて、色々と考える機会となりました。

今年買ったもの

ハンドソープディスペンサー(娘の手洗いがずいぶん楽になりました)

ヘッドセット(ポッドキャストの録音はこれで行っています。リーズナブル!)

電気圧力鍋(料理で大活躍)

ロボットペット(親の方が欲しかった、クリスマスプレゼント)

レゴ(親も楽しい、誕生日プレゼント)

ScanSnap S1500(全然使える、中古で買った)

コンパクトなキーボード

感想

昨年から模索している非同期コミュニケーション手段の1つとしてScrapboxに加えてポッドキャストの配信を始めたというのが一番大きな変化です。

最新の技術であるChatGPTを触ることが出来ているのも良かったです。

朝ジョギングを始めるなど、健康維持についても行動できているので、継続していきたいです。

娘も3歳となり、一緒に技術展示のイベントに参加したり、宿泊を伴う旅行に連れて行けるようになったりと、行動の幅が広がったのも良かったです。引き続き、英才教育・・という名の親の趣味に付き合わせていきたいなと思っています。

月別生データ

1月

  • 親子2人で電車でお出かけ
  • 動画で子守するのを解禁
  • 凧揚げ
  • 内窓を設置
  • 前半は風邪、後半は胃腸炎

ひらがなおもちゃを作る

RakuChordのSMD版を作る inajob.hatenablog.jp

2月

  • 節分
  • 水族館にいく
  • 成田空港にいく

おしたくボード改

MakePython Audio Expansionレビュー inajob.github.io

HandiPiを作る inajob.hatenablog.jp

事前に議事録を作る方式について qiita.com

3月

なぜなぜ分析

おもちゃの分解

Web Assembly qiita.com

ChatGPTに英語記事の要約を頼む実験

OLEDの不良品を激安のロジックアナライザーで分析 scrapbox.io

オーディオコメンタリーメーカーを作る github.com

inajob.hatenablog.jp

3Dプリンタの寸法チェック用モデル

蛇口延長用アダプタ

ESPHomeを試す(が結局プログラミングすることに・・)

4月

レタスの発芽(失敗)

PASMOがバズる

電子メモパッドのレビュー inajob.github.io

小型のフルカラーLEDのテスト基板 inajob.hatenablog.jp

モノクロ液晶の試食

ESP32で動く日本語入力対応Wiki的なもの

5月

枝豆・トマトを植える

埼玉県近代美術館

電気圧力釜を買った

DIYこいのぼり

粘土に夢中

自動ハンドソープディスペンサー購入

トイレの最中

ケースづくり

ESP32搭載のDIY時計ガジェットキットレビュー inajob.github.io

ペン型マルチメーターレビュー inajob.github.io

乾電池駆動のArduino Nanoボード inajob.hatenablog.jp

Vision Five2試食

ダイソーで買ったおもちゃ

6月

  • 長靴を買った
  • 七五三の前撮り
  • KEY PALETTOを購入
  • omoikane参加
  • blueskyを始める

ノートパソコンのバッテリーが膨らむ

ジャガイモを収穫

スカイツリーを見に行く

Raspberry Pi Picoを使った携帯ゲーム機 inajob.hatenablog.jp

7月

  • 地域のソーメン流し参加
  • ブルーベリー狩り
  • 打ち上げ花火を見る
  • Threadsに参加
  • (今更)Twitter API V2を試す
  • ヘッドセット、ロジクールH111rを買った
  • SNSを同期する仕組みの作成

トマト、枝豆の収穫

絵を描いて教える

お金やさん

8月

Raspberry Pi Pico搭載のマクロパッド inajob.hatenablog.jp

バタフライピー

ビリヤニ

ポップコーン

市販キーボード用のマウンタ

ログ機能付きの電流計自作

フレキシブルHDMIケーブル

inajob.hatenablog.jp

9月

  • 写真データをGoogle Photosから自宅のNASに移行
  • synthioを試す
  • Raspberry Pi Picoで遊ぶ
  • MSX0で遊ぶ
  • NS8002オーディオアンプ実験
  • CH32V003で和音実験
  • 遊園地に行く

自作キーボード inajob.hatenablog.jp

10月

  • 上野動物園、ジャグリング鑑賞
  • 地元の秋祭り
  • 自転車が壊れる
  • コテンラジオを聞き始める
  • 安い骨伝導イヤホンを買った(いまいち)
  • LISTENトーク(仮)に参加
  • パパ友とバーベキュー会主催
  • 七五三撮影

RP2040実装練習

inajob.hatenablog.jp

11月

  • 幼稚園の入園面談
  • 国立科学博物館に行く
  • ChatGPT with Voiceで子守してみる
  • サーキュレーターを買った
  • 加湿器を買った
  • 喰い切りニッパーを買った
  • Milk-V Duo試食
  • CadQueryを学ぶ

娘を連れてNT東京2023を見に行った

不良品と思われるATmega328の調査

inajob.hatenablog.jp

12月

コストコ入会

クリスマスオーナメントを作る

クリスマスツリーを作る

Loona購入

inajob.hatenablog.jp

CH32V003を使った和音の鳴るピアノ基板

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

JLCPCBとは

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

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

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

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

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

これは何?

CH32V003という最近流行りのRISC-Vの激安マイコンモジュールを使って楽器を作ってみました。

仕様

  • 128*64 モノクロOLED
  • CH32V003
  • NS8002オーディオアンプモジュール
  • 鍵盤を含む20個のタクトスイッチ
  • スピーカ
  • オーディオジャック
  • ボリューム

パーツ紹介-CH32V003F4P6

最近流行りのWCH社製のRISC-Vマイコンです。 CH32VのシリーズはほかにもありますがCH32V003はその中でも最も廉価なシリーズです。

秋月電子でも販売しており、記事執筆時点では1つ50円です

akizukidenshi.com

プログラムメモリ16KB, RAM 2KB、GPIO18個というシンプルなスペックですが、ちょっとした電子工作のロジックを作るには十分です。

パーツ紹介-CH32V003モジュール

今回のピアノ基板はCH32V003F4P6を基板に直接取り付けることもできますが、よくあるCH32V003を搭載した開発ボードを使うこともできます。

今回はまずはこのCH32V003モジュールを利用する方法で組み立てました。

CH32V003はUSBデバイスの機能を持っていないので当然ですが、このモジュールのUSB端子は電源用で、書き込みを行うことは出来ません。

書き込みのためには専用の書き込み装置であるWCH-Linkが必要となります。(セット販売しているものを買いました)

基板の設計

今まで私は、この手のちょっとした音が鳴るガジェットを作ったことは結構あるので、ここまでのブログ記事などでも紹介しているような「鉄板」の構成で設計しました。

20個のタクトスイッチは 4*5のマトリクス配線とし、同時押しをサポートするためにダイオードを実装しています。

オーディオ周りはいつものスイッチ付きのオーディオジャックや、NS8002オーディオアンプ、ボリューム、表面実装スピーカなどを採用しました。

JLCPCBに発注

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

この基板も10cm×10cmに収まるように設計したので5枚だと $2 + 送料です。

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

実装

今回はそこまで複雑な回路ではないので、サクッと実装できました。

ソフトウェアの実装

今回のチャレンジはソフトウェアです。CH32V003は比較的新しいマイコンなので、参考となるソースコードが少ないのが現状です。

CH32V003公式の開発環境としてはMounRiver Studio IDEというGUIIDEと公式のSDKを使う手があるのですが、どうも大げさな開発環境で、肌になじまなかったので、シンプルなch32v003funを使うことにしました。

github.com

ch32v003funはシンプルな実装ですが、このくらいの規模のCH32V003の開発には必要十分で、サンプルも豊富です。 いくつかのサンプルを組み合わせることで目的のプログラムを作ることが出来ました。

  • blink
    • まずはLEDをチカチカします
    • これで最低限の雰囲気をつかみました
  • tim2_pwm
    • 音を鳴らすために利用するPWMの機能
    • LEDをフェードイン・フェードアウトするような使い方にも利用できます
  • systick_irq
    • 音源のオシレータを一定時間ごとに進めるためにタイマ割込みの機能
  • i2c_oled
    • I2C接続のOLEDの制御
    • ホビー電子工作でよく利用するSSD1306向けの描画ロジックが便利です

ch32v003funを使うにあたっては以下のブログ記事が非常に参考になりました。

74th.hateblo.jp

つぎはぎですがソースコードはこんな感じです (ch32v003funのi2c_oledのexampleを以下のように書き換えて、ビルドしました)

gist.github.com

まとめ

安価なRISC-VマイコンであるCH32V003を使って、和音の鳴るピアノ的な楽器を作ることが出来ました。

ch32v003funという軽量なライブラリを利用して、比較的簡単に楽器的なロジックを作れることがわかりました。

自分が今までよく利用していたArduino UNOのメインマイコンであるATmega328は半導体不足で価格が高騰し、今ではだいぶ落ち着きましたが、それでもまだ価格が高止まっています。また、ATmega328は昔からあるマイコンであることもあってテキトーに買うと偽物が混ざっているようなこともあり困っていました。

CH32V003は非常に安く、新しいマイコンであるため今のところ偽物の情報も聞きません。

ちょっとここらで、メインで使うマイコンをCH32シリーズに移行してみても良いかも・・と感じました。