QMK FirmwareとRP2040でAudio機能を使えるようにする方法

このブログエントリは、 キーボード #2 Advent Calendar 2022 の7日目の記事となります。昨日は bbrfkr さんの自作キーボード民に贈る - 3Dプリンタ利活用事例 でした。僕も 3D プリンタを買ってキーボードケースを作ろうかなぁと考えていたときに bbrfkr さんからアドバイスをもらっていまして、キーボードケースを家で作って販売までするようになったのは bbrfkr さんのおかげでもあると感謝しています。

さて、7日目のこの記事として何を書こうかなぁと悩んでいましたが、あまり情報が出ていなくて僕も対応するのにちょっと苦労した話を書こうと思います。それは、

「QMK Firmware と RP2040 で Audio 機能を使えるようにする方法」

です。

2022年は QMK Firmware & RP2040 元年

RP2040 で QMK Firmware を動かす試みは、実は昨年に せきごん さんによって達成されていました。

RP2040のQMK対応

しかし、2022年、つまり今年の8月に、QMK Firmware が正式に RP2040 をサポートするに至りました。多くの自作キーボードで使われてきた ProMicro の供給減によって、安定した供給が見込めそうな RP2040 がフォーカスされ、Raspberry Pi Pico の登場もあり、2021年に一気に RP2040 の採用が増えた感があります。

QMK Firmware の RP2040 サポート状況は、以下のページで確認することができます。ほとんどの機能が現在つかえるようになっていますね。

qmk_firmware/platformdev_rp2040.md at master · qmk/qmk_firmware

Raspberry Pi Pico の登場から僕も注目していて、昨年は Raspberry Pi Pico で動作可能な左右分割型の 40% キーボードを設計して販売するに至りました。

rp2040-audio-1.webp

Lunakey Pico - Yoichiro’s Garage - BOOTH

この Lunakey Pico は、今では僕のメインキーボードになりました。この記事も、Lunakey Pico を使って書いています。

Audio サポートは最初はなかった

ProMicro を使った Lunakey Mini と、Raspberry Pi Pico を使った Lunakey Pico ですが、どちらも圧電スピーカーを搭載することができます。販売しているキットにも、最初から圧電スピーカーを同梱しています。

rp2040-audio-2.webp

キーボードから音を鳴らす必要があるのか?と聞かれると「うーん、わかんない、ないかな」と答えたくなるとは思いますが、わからないってことは、あるかもしれないわけです。僕は、キーボードの電源が供給されたときに、昔の PC9801 のような「ぴこっ」って音をどうしても鳴らしたくて、Lunakey シリーズには圧電スピーカーを標準搭載しよう!と決めました。

QMK Firmware では、もちろん圧電スピーカー対応のプログラムが入っていて、キーの打鍵に合わせて音を鳴らしたりできる「Audio」機能が搭載されています。これを使って、ProMicro 対応の Lunakey Mini では、圧電スピーカーから音を鳴らすことができます。

でも、QMK Firmware の RP2040 対応では、最初は Audio 機能が入っていなかったんです。

そのため、Raspberry Pi Pico を使った Lunakey Pico にて圧電スピーカーを使うためには、 発売当初は KMK Firmware を使うしかありませんでした。2022年の8月末に picoruby/prk_firmware: A keyboard firmware platform in PicoRuby でも圧電スピーカーから音を出す機能が追加されましたので、KMK もしくは PRK を使うことで、Lunakey Pico で音を楽しむことができました。

QMK Firmware + RP2040 に Audio 機能が来た

しばらくは Lunakey Pico で音はお預けかなぁ、と思っていましたが、RP2040 でも Audio 機能を使うためのコードが提供されようとしていることに気がつきました。

[Core] Adjust PWM hardware audio driver for RP2040 by KarlK90 · Pull Request #17723 · qmk/qmk_firmware

上記の Pull Request はすでに閉じられていますが、僕が最初に見たときはまだ Open 状態でした。想像していたよりも RP2040 で Audio 機能を早く使えるかもしれない、と思い、ワクワクしたのを記憶しています。

これを見たからには、コントリビュートしないといけません。オープンソースソフトウェアにとって、コードを提供することだけが貢献ではありません。提供されたコードが正しく動くかどうかという検証も、立派な貢献だと僕は考えています。「ちゃんと動いたよ」とフィードバックすることで、コードの提供者も安心するはずです。

というわけで、Raspberry Pi Pico を使った Lunakey Pico にて、この Audio 機能が動作するかどうか、検証を始めました。結局は僕の RP2040 への知識不足で簡単には動作させられず、いろいろな方々から助言をいただきました。以下は、Discord にてアドバイスを聞いていたときの会話です。

How to use Audio feature for Raspberry Pi Pico

無事、Lunakey Pico + Raspberry Pi Pico + QMK Firmware + 上記の Pull Request にて圧電スピーカーから音がちゃんと鳴ることを確認できました。そのことを Pull Request にコメントして、その後数日で develop ブランチに取り込まれました。そして、今では master ブランチに入り、誰でも RP2040 にて Audio 機能が使えるようになりました。

まあ、僕が検証したことで何か変わったわけじゃないとは思いますが、開発にちょっとでも参加できて良かったな、と勝手に思ってます。

QMK Firmware + RP2040 での Audio 機能の使い方

前置きがとても長くなってしまいましたが、RP2040 を採用した圧電スピーカーを持つキーボードで QMK Firmware の Audio 機能をどう使えるようにするか、その方法を紹介いたします。僕は Raspberry Pi Pico でしか実績がないので Raspberry Pi Pico での話をしますが、たぶん RP2040 を採用しているのであれば、同じかと思います。

まず、回路図を見ます。そして、圧電スピーカーが GPIO の何番に接続されているかを見ます。

rp2040-audio-3.webp

Lunakey Pico の場合、圧電スピーカーは、GP8 に接続しています。

次に、RP2040 のデータシートの PDF を開きます。

RP2040 Datasheet

このデータシートの 13 ページ目に「GPIO Functions」という表があります。

rp2040-audio-4.webp

さっき回路図から得た GPIO の番号の行を見ます。Lunakey Pico の場合は 8 番です。そして、圧電スピーカーで重要なのは、F4 の列です。ここに、PWM(Pulse Width Modulation - パルス幅変調)の番号とチャンネルが書かれています。GPIO の 8 番であれば、PWM4 でチャンネル A です。

ここまでわかれば、あとは QMK Firmware 向けにプログラムを書いていくことができます。以下は 2022 年 10 月後半時点で機能した内容なので、最新の QMK Firmware のコードセットでは動作しない可能性がありますことをご了承ください。

まず、rules.mk ファイルに、以下を追記します。

AUDIO_ENABLE = yes
AUDIO_DRIVER = pwm_hardware

次に、mcuconf.h ファイルを以下のように作成します。

#pragma once

#include_next <mcuconf.h>

#undef RP_PWM_USE_PWM4
#define RP_PWM_USE_PWM4 TRUE

...

ここで、さっき調べた PWM 番号を使います。Lunakey Pico では PWM4 だったので、RP_PWM_USE_PWM4 を有効にします。

次に、halconf.h ファイルを以下のように作成します。

#pragma once

#define HAL_USE_PWM TRUE
...

#include_next <halconf.h>

PWM を有効にしています。

そして、config.h ファイルに、以下を追記します。

/* Audio support */
#ifdef AUDIO_ENABLE
  #define AUDIO_PIN GP8
  #define AUDIO_PWM_DRIVER PWMD4
  #define AUDIO_PWM_CHANNEL RP2040_PWM_CHANNEL_A
  #define AUDIO_INIT_DELAY
  #define STARTUP_SONG SONG(M__NOTE(_C7, 30), M__NOTE(_C6, 30))
#endif

それぞれの意味は、以下となります。

  • AUDIO_PIN - 圧電スピーカーが接続されたピンの場所
  • AUDIO_PWM_DRIVER - ドライバーを有効にする PWM の番号
  • AUDIO_PWM_CHANNEL - PWM のチャンネル
  • AUDIO_INIT_DELAY - キーボードの初期化処理の後に Audio 機能の初期化を行う
  • STARTUP_SONG - キーボードの初期化後に鳴らす音

これらのファイルを作成&編集してビルドして、RP2040 に書き込めば、めでたく圧電スピーカーから音が鳴ります。

ちなみに、上記で STARTUP_SONG に指定している SONG の内容は、約 2 kHz の周波数の音を鳴らし、その後に約 1 kHz の周波数の音を鳴らす、という指定になります。そう、これこそが、PC9801 の起動音です。

まとめ

このエントリでは、QMK Firmware と RP2040 の組み合わせで圧電スピーカーを扱いたいときにどうすれば良いか、その方法を紹介しました。

パソコンの電源を入れたときに、自ら組み立てたキーボードから「ぴこっ」と音が鳴る、それだけで楽しい気分になります。みなさんにも体験していただきたいな、と思っています。

明日は monksoffunkJP さんによる「近況かな」という内容の記事を読むことができる予定となっています。楽しみですね!

このエントリーをはてなブックマークに追加

関連記事

2022年を振り返って

現在のRemapと今後のRemapについて

スマートスピーカーはもう終わったデバイス?

QMK FirmwareとRaspberry Pi PicoでSPLIT_USB_DETECTを使わない方法

40%キーボードに慣れるためにやったこと