Client-side / CDN Ruby Parser Ruby × 電子工作

UIAPruby Lab

数百円のマイコンで始めるRuby電子工作。
ブラウザでRubyを書いてコンパイル、WebHIDでSDカードへ転送するだけ。
独自の TinyVM がバイトコードを実行。インストール不要。クラウド不要。

Powered by Wakayama.rb — 和歌山発Rubyコミュニティ
UIAPrubyとは? — はじめての方へ
数百円から始めるRuby電子工作

「Rubyで電子工作をやってみたい」——そう思っても、 高価なボード、複雑なセットアップ、専用ソフト… とハードルを感じていませんか?

UIAPruby は、そのハードルをぐっと下げます。
数百円のマイコン UIAPduino(CH32V003ベース)と、 手持ちのChrome/Edgeブラウザだけ。 普段書いているRubyの文法でLEDを光らせ、ブザーを鳴らし、ボタンで制御できます。

ブラウザ内の @ruby/prism でコードを解析し、 独自の軽量バイトコード(.uap)に変換。 WebHIDでSDカードへ直接転送し、マイコン上のTinyVMが実行します。
インストール不要・クラウド不要。すべてブラウザの中で完結。

Rubyist が電子工作へ踏み出す入口を、 Wakayama.rb が作りました。

✏️ Rubyコードを書く ⚙️ ブラウザ内コンパイル 📤 SDカードへ転送 ▶ TinyVMが実行

🔧 必要なハードウェア

  • UIAPduino SD版(CH32V003、v1.2.3以降推奨)
  • MicroSDカード(FAT32フォーマット)
  • USBケーブル(Micro-B または Type-C)
  • LED / タクトスイッチ / ブザーなど(実験用)

💻 必要なソフトウェア

  • Google Chrome または Microsoft Edge(最新版)
  • このページ — WebHID対応ブラウザのみ動作
  • Arduino IDE(スケッチ初回書き込み時のみ)
  • UIAP_HID ボードパッケージ v1.2.3以降

⚡ クイックスタート(4ステップ)

  1. 1
    UIAPrubyRunner スケッチを書き込む(初回のみ)
    下の「9. UIAPduino スケッチ」からコードをコピー/ダウンロードして、 Arduino IDEでUIAPduinoに書き込みます。
    FQBN: UIAP_HID:ch32v:CH32V003:pnum=V14,usb=webhid,opt=oslto
  2. 2
    Rubyコードを書く
    エディタにRubyコードを入力します。サンプルボタンですぐ試せます。
    例:led = GPIO.new(2, GPIO::OUT) → D2ピンをLED出力に設定
    loop do led.toggle; sleep(0.5); end → 0.5秒ごとに点滅
  3. 3
    「コンパイル」ボタンを押す
    ブラウザ内でRubyコードをAST解析し、TinyVM用 .uap バイトコードへ変換します。
    ✓ OK と表示されれば生成完了です。 命令数・サイズ・推定実行時間も確認できます。
  4. 4
    デバイスに接続 → SDカードに送信 → RUN
    USBケーブルでUIAPduinoを接続し「デバイスに接続」をクリック。 「📤 SDカードに送信」で SCRIPT.UAP を転送し、 「▶ RUN」で実行開始。Device Logに実行状況が表示されます。
    💡 ファイル名を SCRIPT.UAP にしておくと、次回以降はUSB接続しなくても 電源投入と同時に自動実行されます。単体動作させる際に便利です。
📌 ピン配置リファレンス

UIAPduino SD 版 対応ピン一覧

Arduinoピン番号 CH32V003ポート PWM ADC 用途・備考 UIAPruby記法
2 PC0 LED出力(基板上LED) GPIO.new(2, GPIO::OUT)
3 PC1 SDA (I2C — 未対応) / HC-SR04 TRIG Ultrasonic.new(3, 4)
4 PC2 SCL (I2C — 未対応) / HC-SR04 ECHO Ultrasonic.new(3, 4)
5 PC3 PWMブザー(圧電ブザー推奨) PWM.new(5)
11 PD1 タクトスイッチ(PULL_UP使用) GPIO.new(11, GPIO::IN | GPIO::PULL_UP)
0, 1, 12, 15, 16 PA1/PA2/PD2/PD5/PD6 アナログ入力(ADC対応ピン) ADC.new(0)
6 PC4 ✅* ✅* ⚠ SDカード SS専用 — 使用不可
7 / 8 / 9 PC5 / PC6 / PC7 ⚠ SDカード SCK/MOSI/MISO専用 — 使用不可
6(SS)・7(SCK)・8(MOSI)・9(MISO) はSDカードのSPI通信に専用です。GPIOには使用できません。
ピン6はPWM・ADC対応ですが、SDカード搭載版では使用不可です(* 印)。
1. Ruby ソースエディタ
⏳ @ruby/prism WASM 読み込み中...

UIAPruby v1 — Ruby構文を @ruby/prism でAST解析し、UIAPduino TinyVM用 UAP1 バイトコードへ変換します。
UIAPduino 上では Ruby VM を実行しません。

2. ライブラリ管理 (require / require_relative)
登録されたライブラリを require "name" または require_relative "name" で読み込めます。
3. コンパイル結果
— 未コンパイル
命令数
UAP サイズ (bytes)
推定実行時間 (ms)
8.3 形式推奨 / 最大 26 文字
4. UAP ファイル操作
LED: D2 (PC0) / PWM Buzzer: D5 (PC3) / Button: D11 (PD1 PULL_UP) から試してください。
⚠ D7(SCK) D8(MOSI) D9(MISO) D6(SS) は SD カード SPI 専用のため GPIO に使用できません。
💡 ファイル名を SCRIPT.UAP にすると、UIAPduino に電源を入れるだけで自動実行されます。
USB 接続・RUN ボタン操作なしで単体動作するので、完成したスクリプトの運用に便利です。
5. SD カード — ファイル管理
デバイスに接続すると SD カードのファイル一覧が表示されます。
6. Device Log
未接続
UIAPrubyRunner.ino を書き込んだ UIAPduino SD を USB 接続し、「デバイスに接続」を押してください。
7. HID Console
💻 UIAPruby print / puts / p / putc 出力
8. UAP1 フォーマット v1

ファイルヘッダー(8 バイト)

オフセット
サイズ
内容
0x00
4 bytes
magic "UAP1" (0x55 0x41 0x50 0x31)
0x04
1 byte
version = 1
0x05
1 byte
flags = 0
0x06
uint16 LE
code_size (bytecode のバイト数)

TinyVM 命令セット v1(リトルエンディアン)

Opcode
命令
引数
サイズ
0x00
END
1
0x01
WAIT_MS
uint16 ms
3
0x02
GPIO_MODE
uint8 pin, uint8 mode (0=IN 1=OUT 2=IN_PULLUP 3=IN_PULLDOWN)
3
0x03
GPIO_WRITE
uint8 pin, uint8 value
3
0x04
GPIO_READ
uint8 pin, uint8 reg
3
0x05
PWM_FREQ
uint8 pin, uint16 freq
4
0x06
JMP
int16 relative_offset
3
0x07
JZ
uint8 reg, int16 relative_offset
4
0x08
JNZ
uint8 reg, int16 relative_offset
4
0x09
GPIO_TOGGLE
uint8 pin
2
0x0A
LOAD_Q16
uint8 reg, int32 value
6
0x0B–0x0E
ADD/SUB/MUL/DIV_Q16
uint8 dst, uint8 src
3
0x0F–0x14
CMP_<op>_Q16
uint8 lhs, uint8 rhs, uint8 out_reg
4
0x15
LOAD_BOOL
uint8 reg, uint8 value
3
0x16
PRINT_STR
uint8 flags, uint8 len, byte[len] str (flags: 0x01=newline 0x02=inspect)
3+N
0x17
HALT
uint8 error_code
2
0x18
ADC_READ
uint8 pin, uint8 reg → Q16.8 (0〜255) ピン: 0,1,12,15,16
3
0x1A
ULTRASONIC_READ
uint8 trig, uint8 echo, uint8 reg → Q16.8 cm (0=タイムアウト) HC-SR04
4
0x19
PRINT_REG
uint8 flags, uint8 reg → Q16.8 を "n.nn" 形式で出力 (flags: 0x01=newline)
3
JMP/JZ/JNZ の offset は命令直後位置からの相対バイトオフセット (int16)。
レジスタ R0–R3 は int32_t。Q16.8 固定小数: 1.0=256, 0.5=128。
9. UIAPruby API v1

GPIO / PWM

Ruby 記法変換後命令Phase
led = GPIO.new(2, GPIO::OUT)GPIO_MODE pin=2 OUTPUT1
button = GPIO.new(11, GPIO::IN | GPIO::PULL_UP)GPIO_MODE pin=9 INPUT_PULLUP1
led.on / led.high / led.write(1)GPIO_WRITE pin, 11
led.off / led.low / led.write(0)GPIO_WRITE pin, 01
led.toggleGPIO_TOGGLE pin1
buzzer = PWM.new(5)GPIO_MODE pin=5 OUTPUT1
buzzer.frequency(440)PWM_FREQ pin, 4401
buzzer.off / buzzer.frequency(0)PWM_FREQ pin, 01
buzzer.tone(440, 0.2)PWM_FREQ 440 → WAIT_MS 200 → PWM_FREQ 01
button.low? / button.high?GPIO_READ pin, R0 + JNZ/JZ2
sleep(0.2) / wait_ms(200)WAIT_MS 2001
print / puts / p / putcPRINT_STR3
raise "msg" / raise unless condPRINT_STR + HALT4
def name … endインライン展開5
break / nextJMP loop_end / loop_start6
g = 0.1 * 0.5 / Q16.8 演算LOAD_Q16 + MUL_Q16 …7
require_relative "path"compile-time include8
sensor = ADC.new(0) ピン: 0,1,12,15,16 (初期化なし)ADC
puts sensor.read / print sensor.readADC_READ pin,R0 + PRINT_REGADC
sonar = Ultrasonic.new(3, 4) 任意のGPIOピンGPIO_MODE trig OUT + GPIO_MODE echo INUS
puts sonar.read / print sonar.readULTRASONIC_READ trig,echo,R0 + PRINT_REGUS
10. UIAPduino スケッチ
UIAPrubyRunner.ino
GitHub ↗

FQBN: UIAP_HID:ch32v:CH32V003:pnum=V14,usb=webhid,opt=oslto