Tanuki_Bayashin’s diary

趣味で電子工作を楽しんでいます。最近、ラズベリーパイPicoというマイコンボードを使って、いろいろ遊んでいます。

お試しの記事

豆知識:フルカラーLEDの電源の容量が十分でないと、白を表示するようにデータを送っても、図2のように赤みがかることがある。おそらく電源の電圧が落ちて、緑や青のLEDが十分光ることができなくなっているためと思われる。

図2 WS2812Bにて白を表示 電池の出力電圧 左:  V 右: V

【Raspberry Pi Pico 専用】WS2812B のためのライブラリの試作

1.はじめに

 WS2812BというICチップ内蔵のフルカラーLEDのアレイがある(図1左)。これはRaspberry Pi Pico (以下Pico と記述:図1右)での制御も可能である。これらは筆者も愛用しており、Picoにて制御する際の専用のライブラリがあったら便利かと思い、製作してみた。あくまで自分用である。

※なるべく間違いや不確かな記述はしないように心掛けてはいますが、なにか気になる点がありましたらコメント欄からお伝えくださいますと助かります。

f:id:Tanuki_Bayashin:20210916214541j:plain:h240f:id:Tanuki_Bayashin:20210910192242j:plain:h240
図1 左:WS2812B 右:ラズベリーパイPico

2.回路

 WS2812BとPicoについてはここでは詳しくは説明しない。検索などで調べてください。
 全体構成図を以下に示す。(Pico 用の電源は省略。USBケーブルを接続すると給電される)

f:id:Tanuki_Bayashin:20210919234459p:plain:h360
図3 全体構成図

 簡単に説明すると、WS2812Bには3本の接続する電線がある。1本はGND、1本は電源、残りの1本が制御用である。制御用の電線はPicoからの出力信号を受け取り、WS2812Bの何番目のLEDのRGBをそれぞれどれくらいの強さで光らせるかを受信する。
 また、WS2812Bの電源に関して述べると、WS2812B1素子当たり、RGB3個のLEDが内蔵されていて、それぞれ定格は約12mA*1流して使う。WS2812Bが100個の素子で構成されているとすると、最大約3.6Aの電流が必要となる。電源ラインと直列に数百Ωの保護抵抗を入れるなど注意が必要である。(WS2812B内に保護抵抗が収められている場合もある。メーカーによって異なる模様)

3.ライブラリ

 リスト1に自作のライブラリを載せる。(多くは以下の書籍を参考にした)
THE OFFICIAL RASPBERRY PI PICO GUIDE : Get started with MicroPython on Raspberry Pi Pico
www.raspberrypi.org

リスト1(ファイル名:Class_ws2812b.py)

import array, utime
from machine import Pin
import rp2
from rp2 import PIO, StateMachine, asm_pio

# PIO State Machine to display ws2812
@asm_pio(sideset_init=PIO.OUT_LOW, out_shiftdir=PIO.SHIFT_LEFT, autopull=True,\
         pull_thresh=24)
def ws2812b():
    T1 = 2
    T2 = 5
    T3 = 3
    label("bitloop")
    out(x, 1)                .side(0)    [T3 - 1]
    jmp(not_x, "do_zero")    .side(1)    [T1 - 1]
    jmp("bitloop")           .side(1)    [T2 - 1]
    label("do_zero")
    nop()                    .side(0)    [T2 - 1]

class Class_ws2812b:
    
    def __init__(self):
        self.sm_no = 0         # state machine No(0-7)
        self.Pin_No = 16       # the Number of conected Pin(GPIO)

    def init_ws2812b(self, sm_no, freq, Pin_No):
        self.sm_no = sm_no
        self.freq = freq
        self.Pin_No = Pin_No

        # Create the StateMachine with the ws2812b program, outputting on Pin_No.
        sm = StateMachine(self.sm_no, ws2812b, self.freq, \
                          sideset_base=Pin(self.Pin_No))
        return sm

説明(筆者はクラスやインスタンスに関してよく理解していない):
 ① 1~ 4行目:必要なライブラリを読み込む
 ② 6~18行目:この部分は筆者はちゃんと理解していない。PIO State MachineというPicoを高速で動かすためのものらしい。(ラズパイPico用のマシン語?)前述の書籍に書かれていた。

 20~34行目:この記事のメインとなる部分である。以下順に見ていく
 ③20行目:クラスClass_ws2812b の宣言
 ④22~24行目:クラスの初期化(microPythonならではの記述である)
 ⑤26~34行目:WS2812Bの初期化。27~29行目で変数の受け渡しを行っている。

  27行目 sm_no:state machine の番号。8個用意され、0-7の間で指定できる。
  28行目 freq  :動作させる周波数
  29行目 Pin_No:信号を出力するピンの指定(GP○○の○○のこと)
  32~33行目   :StateMachine という関数で、sm_no、freq、Pin_Noと動作させる関数(ここではws2812b()(上の9~18行目))を指定し、変数sm にインスタンスを与えている。
  34行目 戻り値sm を返している

4.ライブラリを使ってプログラムを組む

4.1ライブラリの使用例

 実際に3章で紹介したライブラリの使用例を示す(リスト2)。長々と書いているが、大事な部分は18行目ぐらいまでである。

スト2

import array, utime
from Sep_2021 import Class_ws2812b

#Configure the number of WS2812B LEDs.
NUM_LEDS = 16

# Get the Instance of StateMachine with the WS2812B
ws = Class_ws2812b.Class_ws2812b()

# StateMachine(0, ws2812, freq=8000000, sideset_base=Pin(16))
sm = ws.init_ws2812b(0, 8000000, 16)

# start the StateMachine, it will wait for data on its FIFO.
sm.active(1)

# Display a pattern on the LEDs via an array of LED RGB values.
ar = array.array("I", [0 for _ in range(NUM_LEDS)])

# すべてのLEDの r g b の値を、
# 指定されたr g b の値にセットする
def ar_color_all(red, green, blue):
    for i in range(NUM_LEDS):
        ar[i] = (green<<16) + (red<<8) + blue
    sm.put(ar,8)
    utime.sleep(1)
            
# すべてのLED の値をゼロにする
def clear_all():
    for i in range(NUM_LEDS):
        ar[i] = 0
    sm.put(ar,8)


if __name__ == '__main__':
    # Process arguments
    print('Press Ctrl-C to quit.')

    try:
        while True:
        # ar_color_all(red, green, blue)
            ar_color_all(100, 0, 0)         # 赤
                
            ar_color_all(50, 0, 50)         # マゼンタ

            ar_color_all(50, 50, 0)         # 黄色

            ar_color_all(0, 100, 0)         # 緑

            ar_color_all(0, 50, 50)         # 水色

            ar_color_all(0, 0, 100)         # 青

            ar_color_all(20, 20, 20)        # 白

    except KeyboardInterrupt:
        #### clear WS2812B
        clear_all()
        print('program is finished')

解説
1行目 必要なライブラリを読み込む
2行目 3章で作ったライブラリを読み込んでいる。リスト1のファイル名はClass_ws2812b.pyで、Sep_2021という名前のフォルダーに入っている。
5行目 LEDの個数である。
8行目 クラスClass_ws2812bのオブジェクト(?)を取得している。
11行目 smという変数にオブジェクトwsのインスタンスを取得している。
14行目 smはまた、ステートマシンでもあるので、それをオンの状態にしている。
17行目 今までの流れとは別にarというリスト型変数を定義している。要素数はLEDの個数と等しい。
21~25行目 ar_color_all()という関数を定義している。コメントにもあるが、すべてのLEDのRGB値をred、blue、greenの値にセットする。
28~31行目 clear_all()という関数を定義している。すべてのLEDのRBG値を0にしている。
(上の2つの関数のなかに ”sm.put(ar,8)”という記述がある。これにより、変数ar のなかに記述されているデータがWS2812Bに書きこまれている)
34~58行目 プログラムの本体である。if 文とtry と except にて CtrlーC が押されたとき、すべてのLEDを消してプログラムを終了する。
プログラムの中身としては、関数 ar_color_all() により、7色の色を順番に点灯させている。

4.2 動画

 実際にWS2812Bが点灯している様子を以下に示す。

動画:【ラズベリーパイPico専用】WS2812Bのためのライブラリの試作

youtu.be


5.まとめ

 WS2812Bの初期設定を行う、ラズベリーパイPico専用のライブラリを製作した(試作の段階)。microPyhtonの学習の一環でもある。また、少しだけ、独自の関数も例示した。(あくまで自分用である)
 今回は示していないが、もっとグラフィカルな表示も可能である。今後試してみたい。

臭気センサ【TGS2450】にてにおいを検知する(ラズベリーパイPicoの応用)

1.はじめに

 ラズベリーパイPico(以下Picoと表記)なるマイクロコントローラが世に出て7か月以上になる。Arduinoラズベリーパイなどを用いて臭いを検知する記事が見受けられるが、同じことをPicoを用いて行ってみた。

f:id:Tanuki_Bayashin:20210910192242j:plain
図1 ラズベリーパイPico

ラズベリーパイ財団
www.raspberrypi.org

2.回路構成

 図2に回路図を載せる。あわせて、図3 に実態配線図も載せる。(秋月電子のHPを参考にした)臭気センサからの出力は電圧値によって検出されるので、Pico内臓のADコンバータにて電圧値を読み取りシェルに表示した。

f:id:Tanuki_Bayashin:20210911133827p:plain
図2 回路図
f:id:Tanuki_Bayashin:20210911134027p:plain
図3 実態配線図

 ただし注意する点として、臭気センサの動作電圧は5Vで、Picoの信号線は3.3Vで動作している。そこでPicoの40番ピンから5Vが出力されているので、これを臭気センサの電源とし、併せてPicoに内蔵されているAD変換のリファレンス電圧(Pico:35番ピン)も5Vとした。こうすることにより、臭気センサからの出力を正しく観測することができる。さらに、アナロググランド(33番ピン)も0Vに接続している。
 また、もう1つ注意する点として、Picoの1番ピンと2番ピンから臭気センサのヒーターとセンサへと電力を供給しているが、その電圧は秋月の推奨する回路図では5Vとなっている。このため、トランジスタと抵抗を用いて5Vの信号に変換している。
 更には、電源からのノイズを減らすため、コンデンサを並列に接続している。

3.コード

 次にコードのリストを載せる。臭気センサからの出力電圧をPico内臓のA/D変換器を通して、Pico用のIDEであるthonnyのシェルに表示させている。臭気センサからは電圧は0vから最大で電源電圧(5V)まで変化する。被測定物(インク、アルコールなど)を感知すると電圧値が下がるので、この変化を検出して臭気を感じ取ることができる。

import machine
import utime

# ヒーター:GP0 センサー:GP1 に割り当て
PinHeater = machine.Pin(0, machine.Pin.OUT)
PinSensor = machine.Pin(1, machine.Pin.OUT)

# A/D 変換 初期化
PinOutput = machine.ADC(26)
conversionFactor = 5.0 / (65535.0)

PinHeater.value(0)    # Heater OFF
PinSensor.value(1)    # Sencor Pullup OFF

# メインルーチン
while True:
    utime.sleep(0.237)
    PinSensor.value(0)    # センサーへ給電
    utime.sleep(0.003)    # 250ms 中 3ms ON

    # センサーの電圧値を取得
    voltage = PinOutput.read_u16() *  conversionFactor

    utime.sleep(0.002)    # 2ms ON (合計 5ms ON)
    PinSensor.value(1)    # センサー OFF

    PinHeater.value(1)    # 8ms ヒーター ON
    utime.sleep(0.008)
    PinHeater.value(0)    # ヒーター OFF

    print('voltage: ', voltage) # shell へ印字

コードの説明

  • 1,2行目 ライブラリのインポート
  • 5,6行目 GP0とGP1を、それぞれセンサのヒーター電源とセンサへの給電に使うよう、指定している。
  • 9,10行目 AD変換器のインスタンスを取得している(GP26を指定)。またAD変換の結果を電圧値に換算する比例係数を求めている。
  • 12,13行目 初期設定。ヒーターとセンサへの給電をオフにする。

 図2の回路図から、3.3Vを5Vに変換しているところでNOT回路になっている。
 ヒーターへの信号はPNPのトランジスタを通っていることから再度NOT回路が入っている。
 結論:ヒーターは正論理、センサは負論理 したがって、初期設定ではヒーターは0、センサは1としている。

  • 16行目以降  

 237msの間、センサもヒーターもOFF
 5msの間センサをオン(その間にセンサの出力の値を読み取る)
 続いて8msの間ヒーターをオン
 合計で250msごとに信号をON/OFFしている(4Hz)
 読み取った値をprint文にて出力

4.測定結果

 PCの表示画面を以下に載せる。マジックインキを近づけると、1秒ばかり遅れて電圧値が下がり始め、0.2Vくらいまで値が下がっているようすがうかがえる。

ラズベリーパイPico】臭気センサ(TGS2450)にてインクの臭いを検出した
youtu.be

5.まとめ

 臭気センサの出力をラズベリーパイPicoにて処理し、PCの画面から電圧値を読み取った。今後取り組みたいことを以下に示す。

  • 表示に関して一目で様子が分かるものを考案する
  • 口臭チェッカーを作る。

おまけ

 おそらく臭気センサを使っているであろう事例をSNSにて見つけたので、載せておく。
japanese.engadget.com

CNCルータを用いてプリント基板を製作した

1.はじめに

 プリント基板をCNCルータを用いて製作した。まだ未完成ではあるが、いくらかまともなものができたので、一区切りつけておく。(この記事のメインは4.FlatCAM の部分)

※備忘録の要素が大きいので、再現性は保証できかねます。適宜、検索などでネット上の情報を確認していただけると助かります。
※至らない点などありましたら、ご指摘くださいますようお願いいたします。

f:id:Tanuki_Bayashin:20210828122848j:plain
図1 自作したプリント基板

2.構成

 全体の構成の概要を以下に示す。(ここに挙げたものはほんの一例です。人によっては、もっと適したものがあるかと思います。)

2.1 CNC ルータ

 2021/1/27 にAmazonにて購入した。
GENMITSU CNC ROUTER 3018-PRO

 Sain SMART社製 GENMITSU CNC ROUTER 3018-PRO を利用した。組み立て式で、切削部は横300mm 縦180mm 高さ45mm 移動可能。スピンドルモータは10,000回転まで動かせる模様。CNC ルータの細かい話は筆者は理解していません。悪しからず。
 ちなみに、防音と安全のため別売りのカバーを購入した。
別売りのカバー

2.2 PC Windows 10 Home (64bit)

 Windows10のPCを用いた。(CPU RYZEN 1.8GHz、GRAPHICS RADEON メモリ8GB)
 CNCルータはUSB接続にて動作している。

2.3 KiCad(ver 5.1.6)

 プリント基板の配線パターンを設計し、ガーバーデータを出力する。ラインナップにubuntumac などに対応しているものもある。

2.4 FlatCAM(ver 8.994 BETA 2020/11/7 64bit)

 ガーバデータからGコードを生成するソフト。exe 形式のもの。Python ベースのものもあるようだが、ライブラリのインストールなどが手間取りそうだったので、こちらのものを利用した。

Gコード:CNCルータを操作するうえで使用されるコード、命令。Gで始まる命令文から構成される。MやFの付く命令もある。

2.5 Candle(ver 1.2.9.2b)

 CNCルーターを動かすソフトウェア。Gコードを取り込み、基板の不必要な銅の部分を削り取る。(他にも3Dの形状の削り出しができる)

3.KiCad

 ガーバーデータを出力するときの設定は、CNCルーターで基板を作る場合では、基板メーカーに発注する場合と少し異なる。以下のサイトなどに詳しく書かれているので、参照してください。
elchika.com

4.FlatCAM(※この記事のメイン)

 Gコードを生成するソフト。削る深さや移動速度、スピンドルモータの回転数などを指定できる。ここでは F.Cu 層と B.Cu 層(基板の表、裏の銅の部分)のみの解説をする。Edge.Cuts の部分(基板の輪郭)やドリル穴については前出のサイト(「3.KiCad」内)を参考にしてください。また、手順中エンドミルと書いているが、V字カッターも使用可能である。

f:id:Tanuki_Bayashin:20210826104528p:plain
図2 ファイルを開き、左右反転

手順
1. ガーバーデータを開く
2. 基板の図が現れる。パターンの部分をクリックする
3. B.Cu などパターンを裏返したい場合は、[Options]-[flip on X axis]にて左右反対になる

f:id:Tanuki_Bayashin:20210826112446p:plain
図3 NCC Tool を選択

4. 左側のウィンドウで[Properties]を選択
5. [Tools] の2番目[NCC Tool] をクリックする

f:id:Tanuki_Bayashin:20210826104829p:plain
図4 NCC Tool のタブが開く

6. [NCC Tool]のタブが開く。[Diameter] の表において、片方の項目を削除する。
 (クリックして選択- 右クリックーdelete)
  その後、残った項目の値をエンドミルの直径に合わせる。(複数のエンドミルの直径を使い分けできるか、未確認)
7. 下のほうの[Generate Geometry]をクリックする。[Overlap]、[Margin] を変更してもよい。

f:id:Tanuki_Bayashin:20210826105007p:plain
図5 削り取る部分が赤く変わる

8. 右のプリント基板のパターンのうち、削り取る部分が赤く変わる。
9. [Geometry Object]が開く。[dia]に手順6.にて指定したエンドミルの直径が表示される。
10. その下の[Parameters for Tool2]で設定ができる。
   [Cut Z]     掘る深さ (mm)
   [Travel Z]    高速移動時のZ軸(エンドミル先端)の高さ (mm)
   [Feedrate X-Y]  X-Y面の移動速度(mm/分)
   [Feederate Z]   Z軸の移動速度 (mm/分)
   [Spindle Speed] スピンドルモータの回転数(rpm
11. その下のCommon Parameters での設定
   [Tool Change Z] エンドミル交換時のZ軸の高さ (mm)
   (3018 PROでは高さ調整が必要。対応するGコードを読み込めない可能性あり)
   [End move Z]   削り出し終了時のZ軸の高さ(mm)
   [End move X,Y]  削り出し終了時のX、Y 座標 (mm)

f:id:Tanuki_Bayashin:20210826105154p:plain
図6 赤から青く変わる(Gコードが生成された)

12. [Generate CNC Job object] をクリックする。CNCルーター用のGコードが出力される。
  (削る部分が青く変わる)
13. 中段の[Save CNC Code] をクリックすると、保存先を聞いてくるので、適当なところに適した名前で保存する

5.筆者の設定例

 FlatCAM での設定例を以下にとどめておく。(未来の自分用)
 710番目の手順内の値
   [Cut Z]     -0.1500 (mm) (銅はくの厚さが0.05mmくらいなので)
   [Travel Z]    2.0000 (mm)
   [Feedrate X-Y]  60 (mm/分)
   [Feederate Z]   60  (mm/分)
   [Spindle Speed] 10000(rpm
 811番目の手順内の値
   [Tool Change Z] 使用しなかった
   [End move Z]   15.0000(mm)
   [End move X,Y]  None (mm)

6.Candle.exe

 GコードをもとにCNCルータを動かす。以下に簡単に手順を示す。

f:id:Tanuki_Bayashin:20210826115537p:plain
図7 Candle.exe の操作画面

1. 基板を台座に固定する。水平方向での原点の調整を行う
2. Z軸(垂直方向)の原点調整をする(Z-prove)
3. FlatCAM にて生成されたGコードを読み込む
4. Gコードを走らせる
5. 完成

7.製作例

7.1 LEDのピコピコ回路

 100年ほど前に開発された回路を題材にした。(図8)
youtu.be

- YouTube
  図8 実際に部品を実装してみた

8.まとめ

 プリント基板をCNC ルーターを用いて製作する手順を示した。さらに精度よく作り上げることができるように、手法を確立したい。
 ゆくゆくは、2.54mm以外のピッチの部品や、表面実装の部品を実装できるプリント基板を製作できるようになりたい。

【確率・統計ロボティクス学習キット MZIP-01】自作キットを組み立てて動かしてみた

1.はじめに

 先日、twitterを見ていたら、倒立振子のロボットが動いている映像を見つけた。学生時代、卒業研究で、同じ研究室内に倒立振子を動かしている人がいたということもあり、懐かしい気持ちになった。また4年ほど前にYouTubeだったかと思うが、Arduinoで制御された倒立振子を見つけ、自分でも作ろうとしたがうまくいかなかったという悲しい過去もある。倒立振子への執着に再び火が付いたといったところである。
 作り方を是非知りたいと思い、映像の投稿者に「回路図やコードを教えてほしい」と書き込んだところ、タイトルに挙げた組立てキットを紹介していただき、購入するに至った。
 今回、このキットを作るにあったって、いろいろと運のいいことが多かったように思った。また、所々、気づいた点もあったのでそれらを記しながら、運の良さも見ていこうと思う。(すべての工程は載せていないです)

確率・統計ロボティクス学習キット MZIP-01(マルツオンライン)
www.marutsu.co.jp
※結果から先に知りたい方は、『3.まとめ』から読むことをおすすめします。必要となる道具などを一部載せています。

2.製作

 制作時の感想です。気づいたことなどを記していきます。

2.1 制御基板にパーツを取り付ける

2.1.a  モータドライバICの取り付け

 まず、基板(図1 左)にドライバICを取り付ける。

f:id:Tanuki_Bayashin:20210726200604j:plainf:id:Tanuki_Bayashin:20210726232816j:plainf:id:Tanuki_Bayashin:20210726185859j:plain
図1 左:基板の銅はく面 中:2.4D型のコテ先 右:仮はんだを付ける

 部品はSMD(表面実装デバイス)なので、はんだごてのコテ先は2.4D型を用いる。(図1 中)ピン幅に対して幅が広すぎると思われるかも知れないが、これくらいがよいと今年3月に受けたはんだ付け講習会で教わった。手順を以下に示す。

f:id:Tanuki_Bayashin:20210726191006j:plainf:id:Tanuki_Bayashin:20210726191109j:plainf:id:Tanuki_Bayashin:20210726191247j:plain
図2 左:部品(ドライバIC)中:部品の仮止め 右:フラックスを塗る
  1. 仮はんだを付ける(図1 右 基板を90°回転しました)軽く1ピンか2ピン分ぐらい、銅はくにはんだを流す。(糸はんだの太さははΦ0.3mmがやりやすいようです)
  2. 部品を仮止めする(図2 左、中)はんだごてを当て固定する。部品がナナメになったり、ズレや浮きがないようにピンセットで調整する
  3. フラックスを塗る(図2 右)フラックスを塗ると、はんだが銅はくの部分だけに乗るようになる(順番が違っているかも知れないです)
f:id:Tanuki_Bayashin:20210726191335j:plainf:id:Tanuki_Bayashin:20210726191419j:plainf:id:Tanuki_Bayashin:20210726191450j:plain
図3 左:はんだ付けする 中:アルコールで掃除をする 右:アルコールを拭き取る
  1. はんだ付けをする(図3 左)銅はくを温め、コテ先の【下側】に少しだけはんだを乗せ、図の場合だと右から左にずらすようにしてはんだ付けしていく。(右利きの場合) 基板とハンダゴテの間にあるはんだを、滑り込ませていくような感じ。
  2. アルコール(IPA)を歯ブラシに付け、部品の周りの残ったフラックスを取り除く。(図3 中)
  3. アルコールを布(キムワイプ)などで拭き取ってできあがり。(図3 右)

※はんだ付けの知識が少しあるので解説しましたが、はんだ付け検定3級(電子工作レベル)は不合格のままなので、自信をもってお伝えできないもどかしさはあります。はんだ付けの詳しいことは以下のリンクをご参照下さい。
godhanda.net

※あるいは最近出版されたものとして以下の本があります。分かりやすいと思いました。
www.amazon.co.jp

※製作後、電源を入れると、左側のモーターしか動きませんでした。もしやと思い、右側のドライバICのはんだ付けをやり直してみたところ、うまく動作しました。作業は確実に行うほうがいいようです。

2.1.b センサモジュールの組立て
f:id:Tanuki_Bayashin:20210731103641j:plainf:id:Tanuki_Bayashin:20210731103723j:plainf:id:Tanuki_Bayashin:20210731111832j:plain
図4 左:センサーをテープで固定する 中:ブレッドボードにてはんだ付け 右:完成

 先に基板の裏側のジャンパの一部を、はんだでブリッジする。テープで固定してはんだ付けを行った。(図4左)
 ピンヘッダはブレッドボードに取り付けた状態ではんだ付けするのもありかと思った。(図4右)

2.1.c NUCLEOボードの取り付け
f:id:Tanuki_Bayashin:20210731103815j:plain
図5 ピンソケットの浮き(少し銅の部分が見えている)

 NUCLEOボードを取り付けるための2列のピンソケットを、2つ取り付ける。ピンソケットが浮かないように、マスキングテープなどで固定するとよいかと思った。(筆者は片方を斜めに浮かせてしまい、NUCLEOボードを差し込むとき少し手こずった:図5)

2.2 車体を作る

2.2.a ロータリー・エンコーダの取り付け
f:id:Tanuki_Bayashin:20210731103844j:plain
図6 車軸とカップリングとロータリー・エンコーダ

 ロータリー・エンコーダとギヤボックスをカップリングでつなげる。軸と軸を留めるので、お互いの中心線がぴったり一致するのが望ましい。筆者はどうしてもずれたままだった。(車軸を回転させるとズレの分だけ、エンコーダがずれて回転する:図6)
 カップリングは4個のイモネジで固定するが、ギヤボックス側の2つのイモネジを固定するときは、それぞれ少しずつ、中心に合うように締めるといいと思った。(ロボットが完成した後、20分ほど試運転をしたが、イモネジが緩んできた。少しきつめに締め直したら、その後緩むことはなくなった)

f:id:Tanuki_Bayashin:20210731103909j:plain
図7 ギヤボックスのレンチと2mmの六角レンチ

 ギヤボックスに付いている六角レンチは細すぎるので、説明書にあるとおり2mmか2.5mmの六角レンチを用意するとよい。(図7)(全く別の組立てキットを購入したときに、同梱されていた六角レンチが2mmで、新しく購入する必要はなかった。2.5mmの六角レンチも持っていたが、筆者に届いたキットでは、大きさが合わなかった)

f:id:Tanuki_Bayashin:20210731113314j:plain
図8 クリスマスツリー(模型)と余っているカラ-モール

 エンコーダがずれて回転するので、キットに付いているスポンジゴムを台にした上で、細い針金状のもので台座と固定するとよいと思われる。(筆者はクリスマスツリーの模型を作ったときに、飾り付けに使ったモールを転用した(図8)どうでもいい情報だった・・・)

2.2.b 電池ボックスの取り付け

 簡易的に両面テープで貼り合わせた。倒立振子ロボットを動かしているとき、部品面を下にして倒れてしまうと、勢いのせいか、電池ボックスは、はがれてしまう。安全に実験を行うには、ビスとナットで固定したほうがいいと思われる。取り付け穴を大きくするのには、ピンバイスか小形のドリルも使えると思った。

2.2.c 配線する

 電線を1cmぐらいむいて、端子台にからげてから、はんだ付けした。より線もしっかり”より”を入れるといいようである。(はんだ付け講習会のときに教わった接続法。今のところ、電線は切れていない)

2.3 動作確認

2.3.a Ni-MH充電池を使う場合

 筆者は以前サンヨー製のエネループを購入していたので、充電した後、完成した倒立振子ロボットに取り付けた。そのとき、予備も含めて8本購入していた。運がよかった。4本で稼働している間に、4本を充電することができる。(乾電池 単3×4本でも動作可能)
 エネループで連続運転してみたところ、だいたい30分位で電池がなくなってきたように思う。(電池がなくなると、加速して姿勢を保つことが難しくなると思った。更に使い続けると、制御系の動作がうまく働かなくなるように感じた)

2.3.b NUCLEOボードへのプログラムの書き込み
f:id:Tanuki_Bayashin:20210731103935j:plain
図9 USB mini B - typeA のUSBケーブル

 このロボットは、NUCLEOボードを搭載しており、このボードによりうまく立つように制御されている。(このキットは、センサーからの信号からノイズを取り除く機能がメインであるが)そのため、ボードにプログラムを転送しないと動かない。そのとき必要になるのが、USB mini B typeAケーブルである。(図9)昔使ったUSBケーブルの中に、NUCLEOボードの端子と一致するものがあった。運が良いことが続く。

以上で筆者が気になった内容を書き終えた。以下に筆者が動かした倒立振子ロボットの映像を示す。感想などあったら、聞かせてください。

【映像】マルツオンラインの動画と比べて、動きが大きいように思う。制御系のチューニングが必要かもしれない。
youtu.be

3.まとめ

 今回の製作で、運がよかったところを以下に記す。(一般の製作記とはひと味違う)

  • 倒立振子ロボットがキットとなって販売されていた(製作された方から教えていただいた)
  • 今年の3月にはんだ付け講習を受けていた
  • ロータリー・エンコーダの取り付けで、2mmの六角レンチと、固定するためのモールを持っていた
  • Ni-MH充電池8本と専用の充電器を持っていた(乾電池 単3×4本でも動作可能)
  • USB mini B type A ケーブルを持っていた

製作自体はさほど難しくなかった。キットがよくできているからだと思う。(ドライバICのはんだ付けの)手直しをした後、スイッチを入れると、当たり前のようにバランスをとって動作したのには感動した。同時に4年前の自分の至らなさが、もどかしくてたまらなく感じた。(大学ではロボットの研究をしていました)

4.今後の展望

 今後、取り組んでみたいことを以下に記す。

  • 自分なりの制御則を試してみる(勉強し直さないといけない。まずはカルマンフィルタから。時間がかかるだろう)
  • リモート操作で前や後ろに動作させてみる(wifiBluetoothを利用できるマイコンボードにて制御する)
  • 製作された方のようにラズベリーパイ Picoで構成する
  • ロータリー・エンコーダを両輪の軸に付け、右や左にターンさせたり、その場で回転させたりする。(すでにそういう倒立振子の製品は出回っているが・・・)

以上

Raspberry Pi Pico を単体にて、電池駆動で動かす

1.はじめに

 今年1月にRaspberry Pi Pico がRaspberry Pi 財団より発売され、記事を見かけることも多くなったかと思います。初期設定に関する方法を紹介する記事も多く見受けられ、関心の高さが伝わってきます。

 しかし、このRaspberry Pi Pico(以下Pico)を単体で(USB接続することなしに)動かす方法にはあまり触れられていないかと思います(?)。そこで、この記事では、Picoを単体で、そして電池駆動にて動かす方法を紹介したいと思います。

情報ソース:

Pico を単体で動かす
www.itmedia.co.jp



Pico を電池駆動で動かす
https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf



2.picoを単体で動かすには

 Picoを単体で動かす方法はわりと簡単です。Pico内のプログラムで単体動作時に動いて欲しいファイルを"main.py"と名前を付け保存します(図1)。この状態で一旦電源を切り、再度電源が入ると、main.pyが動作を始めます。

f:id:Tanuki_Bayashin:20210530225031j:plain
図1 ファイル名を"main.py"として保存する

 ※電池駆動する前に、USB端子にPCからのケーブルを接続することで動作確認をすることができます。このとき、BOOTSEL ボタンを押しておく必要はありません。

3.Picoを電池で動かすには

3.1乾電池で動かす場合

 乾電池で動かす場合の接続法を説明します。GNDをしっかりつないだ上でPicoの39番の端子に1.8~5.5vの電圧を掛けると動き始めます(図2)。Picoには全部で8本のGND端子がありますが、そのうちの1つを電池のマイナス側につなげばOKです。(GND端子:#3, #8, #13, #18, #23, #28, #33, #38)

f:id:Tanuki_Bayashin:20210601201242j:plain
図2 電池駆動にて動作させる

 (付け加えると、#39 端子に十分な電圧が加わった場合、Pico内蔵のパワーサプライにより、Pico内にはRP2040やGPIOのための3.3vの電圧が作られます。また、#36 端子からは内部で作られた3.3Vが出力されます)

 1.8vでも十分なので、単3や単4の乾電池2本で間に合いますね。ただ、注意すべきこととして、電池の寿命を考えると充電可能な電池にすべきかも知れないです。

3.2モバイルバッテリーで動かす場合

 モバイルバッテリーで駆動するのであれば、USB端子にモバイルバッテリーの端子を接続すれば完了です(図3)。乾電池の場合よりさらに簡単ですね。難点としては、少し大きくなってしまうと言ったところでしょうか?(Picoの端子はmicroUSBです。スマホ用のUSBケーブルなら大体つなぐことができると思います)

f:id:Tanuki_Bayashin:20210531232322j:plain
図3 モバイルバッテリーにて駆動する

4.サンプルプログラム

以下にお試しで動かしたコードを載せます。押しボタンswを押すとLEDが付くといういたってシンプルなものです。

import machine
import utime

#This LED is GPIO25 on the board of pico
led = machine.Pin(25, machine.Pin.OUT)

#button GPIO16 -> the real Pin21 of pico
button = machine.Pin(16, machine.Pin.PULL_DOWN)

# count: Do print() once when LED ON <--> OFF
count = False

# loop forever
while True:
    while( button.value() == 1):    # while button is pressed
        led.value(1)                # let LED ON
        if count == True:           # Do print() once if button is pressed
            print('LED ON')
            count = False
        utime.sleep(0.1)            # wait 0.1 [sec]

    while( button.value() == 0):    # while button is not pressed
        led.value(0)                # let LED OFF
        if count == False:          # Do print() once if button is not pressed
            print('LED OFF')
            count = True
        utime.sleep(0.1)            # wait 0.1[sec]

動画もご視聴下さい。
・字幕をオンにしてお楽しみください

youtu.be

5.まとめ

 以下に内容をまとめます。

  • Raspberry Pi Pico を単体で動かすときは、ファイル名をmain.py とする
  • 乾電池で駆動するのであれば、#39 の端子にプラス、GNDの端子にマイナスを接続する
  • モバイルバッテリーであればUSBに接続端子をつなげばOK

 ボタン電池で駆動し、3Dプリンタなどでケースを作れば、ペットの首輪などに取り付けて、留守のときに、リモートで様子を知ることもできるかも知れません(少し大きめかも?)。(終わり)

2xy=(x+1)(y+1) の式を満たす整数解について

豆腐を切っていてふと思いついた。 2×3で豆腐を切ると6個、1ずつ足して、3×4で切ると12。なので、

問:以下の式でxyを満たす整数の組を全て求めよ。但し、x < y とする。
 2xy=(x+1)(y+1)・・・①

(※なにか不明点などがありましたら、ご指摘ください)


解:まず①式を展開して整理する。

xy=x+y+1・・・②

次に

y=x+m・・・③

と置く。(mはゼロより大きい整数) ①式に代入し整理すると、

x^2+(m-2)x-m-1=0・・・④

xについて解くと、

\displaystyle{x= \frac{1}2 \{2-m \pm\sqrt{m^2+8} \} } ・・・⑤

このとき、ルートの中が整数の2乗になっていなくてはならない。その整数をnと置くと、

m^2+8=n^2・・・⑥

n^2-m^2=8・・・⑦

(n+m)(n-m)=8・・・⑧

n+mn-mも整数であり、また、m>0でもあるので、

{\displaystyle 
\begin{eqnarray}
  \left\{
    \begin{array}{l}
        n+m &=8 \\
        n-m &=1 ・・・⑨-a
    \end{array}
  \right.
  \left\{
    \begin{array}{l}
        n+m &=-1 \\
        n-m &=-8 ・・・⑨-b
    \end{array}
  \right.
\end{eqnarray}
}

{\displaystyle 
\begin{eqnarray}
  \left\{
    \begin{array}{l}
        n+m &=4 \\
        n-m &=2 ・・・⑨-c
    \end{array}
  \right.
  \left\{
    \begin{array}{l}
        n+m &=-2 \\
        n-m &=-4 ・・・⑨-d
    \end{array}
  \right.
\end{eqnarray}
}

の4つの式が導かれる。

これらを解くと、
\displaystyle{(n, m) = ( \frac{9}2, \frac{7}2 ), (-\frac{9}2, \frac{7}2 ), (3,1), (-3,1 ) ・・・⑩}
これらより、

m=1・・・⑪

これを③,⑤式に代入すると、

(x, y) = (-1, 0) または (2, 3) ・・・⑫ █

※多くのはてなブログにおける数式のMarkdown記法の記事を、参考にさせていただきました。
ありがとうございました。