PicoRuby から始めるたのしい電子工作

# PicoRuby から始めるたのしい電子工作

[`大阪Ruby会議03`](https://regional.rubykaigi.org/osaka03/) で [`PicoRuby から始めるたのしい電子工作`](https://speakerdeck.com/ogom/enjoy-ruby-electronic-programming) を発表したときに時間の都合で割愛したコードの紹介と説明です。
また、告知していた PicoRuby Follow-up Osaka は開催することができましたので少し様子を紹介しています。

## 電子工作 のおさらい

電子工作は、電子部品や半導体素子を用いた工作のことです。

- 入力部品：スイッチ（人が操作）、センサー（周囲を調べる）
- 出力部品：LED（人に伝える）、モーター（何かを動かす）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/a5dd74ae-59c7-0fde-6565-9eca09deaf83.png)

[秋月電子通商](https://akizukidenshi.com/) や [共立エレショップ](https://eleshop.jp/) で電子パーツを購入できます。

## mruby

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/d3d86ebb-efe3-0509-9946-99bbb22e78a7.png)

[mruby](https://github.com/mruby/mruby) は、Ruby 言語の軽量実装で組み込みシステムに利用されます。

- コンパイルが必要なので環境構築や利用方法が手間
- バイナリ（.mrb）をマイコンに送信し、実行するエディタが便利

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/87d08e5a-59a2-f9af-52ce-c2fe5c027310.png)

[Crione](https://github.com/ogom/crione) というエディタを作って使っていました。

## PicoRuby

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/e06d5d4d-87c2-77f7-1eda-438da947db0c.png)

PicoRuby は、mruby の軽量実装で組み込みシステムに利用されます。

- ワンチップマイコンで動作するので環境構築が簡単
- ファイルをドラッグ＆ドロップするだけで実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/571cfa00-d77e-0f19-396f-d5ed14a37ae8.png)

[Seeed Studio XIAO RP2040](https://www.switch-science.com/products/7634) のマイコンで動作します。

## PicoRuby の Hello World

プログラミングの `hello, world` は電子工作では `Lチカ` です。

- [R2P2 (Ruby on Raspberry Pi Pico)](https://github.com/picoruby/R2P2) はマイコン で Ruby が実行できる環境
- screen コマンドのシリアル通信で マイコン に接続

irb の対話形式でプログラムを実行することができます。

```sh
$ screen /dev/tty.usbmodem*
$> irb
$> puts "hello, world"
```

GPIO クラスで入出力するピンを指定して write を `1` か `0` に指定すると `Lチカ` ができます。

```ruby
pin = GPIO.new(29, GPIO::OUT)
pin.write(1)
pin.write(0)
```

loop や puts や sleep など Ruby と同じメソッドが利用できます。

```ruby
def hello_world(pin, items=10)
  i = 0
  loop do
    i += 1
    puts i
    pin.write(i % 2)
    sleep 0.5
    return "hello, world" if i >= items
  end
end

pin = GPIO.new(29, GPIO::OUT)
puts hello_world(pin)
```

## PicoRuby で 電子工作

Ruby は、オブジェクト指向スクリプト言語なのでクラスを利用

- クラスやメソッドでプログラミングが捗る
- ブレッドボードの回路を Ruby で制御できる

Dice クラス には number の属性と turn や lighten の振る舞いを定義しています。

```ruby
HIGH = 1
LOW = 0

class Dice
  attr_reader :number

  def initialize(pin1=0, pin2=1, pin3=5, pin4=7)
    @pin1, @pin2 = GPIO.new(pin1, GPIO::OUT), GPIO.new(pin2, GPIO::OUT)
    @pin3, @pin4 = GPIO.new(pin3, GPIO::OUT), GPIO.new(pin4, GPIO::OUT)
    @min, @max = 1, 7
    @number = 0
  end

  def turn
    @number = random
    puts "Dice is #{@number}"
    lighten
  end

  def lighten
    [@pin1, @pin2, @pin3, @pin4].each { |pin| pin.write(LOW) }
    @pin1.write(HIGH) if [1, 2, 3].include? @number
    @pin2.write(HIGH) if [1, 2, 3, 4, 5].include? @number
    @pin3.write(HIGH) if [2, 4, 6].include? @number
    @pin4.write(HIGH) if [1].include? @number
  end

  def random
    loop do
      number = Machine.rand.to_s[2].to_i
      return number if @min <= number && number < @max
    end
  end
end

switch_pin = GPIO.new(10, GPIO::IN)
dice = Dice.new

loop do
  if switch_pin.read == LOW
    5.times do
      dice.turn
      sleep 0.5
    end
  end
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/d817981f-eab8-a7d7-701c-bbcd42a687b3.png)

[IchigoJam 電子工作パーツセット 電子さいころ](https://eleshop.jp/shop/g/gF65416/) で電子パーツの一式を購入できます。

## PRK Firmware の RGBLED

PRK Firmware は、DIY キーボード ファームウェア フレームワーク

- マイコンの PR2040 で動作し、マウスなどの制御可能
- RGBLED(フルカラー LED) では RGB Matrix もサポート

Keyboard や RGB などのクラスが用意されています。

```ruby
kbd = Keyboard.new

kbd.init_pins(
  [   1,  2,  3  ],   # row0, row1,... respectively
  [  28, 27, 26  ]    # col0, col1,... respectively
)

kbd.add_layer :default, %i[
  KC_7    KC_8    KC_9
  KC_4    KC_5    KC_6
  KC_1    KC_2    KC_3
]

rgb = RGB.new( 0, 54, 0 )
rgb.effect     = :circle
rgb.speed      = 10
rgb.hue        = 0
rgb.saturation = 100
rgb.value      = 2

[
  [ 28, 0], [ 14, 0], [  0, 0],
  [  0,16], [ 14,16], [ 28,16],
  [ 28,32], [ 14,32], [  0,32],
].each do |p|
  rgb.add_pixel(p[0], p[1])
end

kbd.append rgb
kbd.start!
```

## PicoRuby Follow-up Osaka

[naniwa.rb](https://naniwarb.doorkeeper.jp/events/163428) で 自作キーボードを組み立てるイベントを開催

- 開催日：2023 年 10 月 28 日（土曜日）
- 会場： シリコンハウス 共立電子産業 セミナールーム

RubyKaigi 2023 で配布された RK2023 や 無限の可能性 のビルドアップをサポートしてから
新世界に串カツを食べに行きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8369/b6a42b1b-e593-e873-a2db-d00ca5379559.png)

Enjoy Ruby, Enjoy Hackathon