本コースではマイコンのRaspberry Pi Picoを使って、ロボット制御の基礎を学習します。
LEDを光らせる通称Lチカに始まり、Raspberry Pi Picoで動くロボットを使い、ライントレースなどの自立制御や遠隔操縦などを体験します。
マイコンとは
マイコンは「マイクロコンピュータ(Micro Computer)」の略称で、その名の通り小型のコンピュータを指します。一般的に、コンピュータといえばPC(パソコン)を思い浮かべるかもしれませんが、マイコンはよりコンパクトで、特定の機能を制御するために作られています。マイコンは次のような電子部品から構成されています。
- I/O(入出力):外部とやり取りするためのピンで、センサーの信号を受け取ったり、モーターやLEDを動かしたりする役割を果たします。
- CPU(中央演算処理装置):マイコンの頭脳ともいえる部分で、プログラムの指示に従って処理を行います。
- ROM(読み出し専用メモリ):長期的にデータを保存する場所です。マイコンではフラッシュメモリが多く使われ、プログラムを保持するのに利用されます。
- RAM(ランダムアクセスメモリ):データを一時的に保存する場所で、プログラムの動作中に一時的な情報を格納するために使用されます。
マイコンの具体例
たとえば、Arduino UnoやESP32、Raspberry Piなどもマイコンの一種です。これらは「シングルボードマイコン」と呼ばれ、1つの基板上に最低限の入出力装置や電子部品が取り付けられています。また、これをさらに小型化したものを「ワンチップマイコン」と呼び、より狭いスペースでも活用できます。
Arduono UNO と ESP32
Raspberry Pi Picoの概要
Raspberry Pi Picoは、手のひらに収まる小型のマイコンボードで、プログラミングや電子工作に幅広く利用されています。このマイコンボードが選ばれる理由には、次のような特徴があります。
- 低コストでありながら高機能:Picoは比較的安価で手に入れることができ、コストを抑えながらマイコンを活用した学習や実験が可能です。特に、Raspberry Pi Pico WHのモデルにはWiFiやBluetooth機能が備わっており、無線通信を活用したプロジェクトにも適しています。
- プログラミングが簡単:Picoは「MicroPython」というPythonをマイコン用に特化した言語でプログラムが可能です。Pythonの基本的な機能を用いながらマイコン制御を学ぶことができ、初心者でも手軽に始められるうえ、参考資料や学習リソースが豊富に存在するため、学習の幅が広がります。
- 多様な言語での学習:PicoではMicroPythonだけでなく、C/C++でもプログラミングができます。これにより、1台で多様な言語を学びながら、幅広い用途に対応したプロジェクトが可能です。ArduinoやESP32といった他のマイコンと似た感覚で扱えるため、様々な学びを深めることができます。
https://akizukidenshi.com/catalog/g/g117947/
使用するロボットPlumbot
このコースではPlumbotという作動二輪型(2つのタイヤで駆動する)のロボットを使用します。
※現在は未発売
ロボットのシステム構成図を示します。
ロボットの概要です。
- 下部に2つのDCモーターを搭載し、それを制御するためのモータードライバ(緑の○)を装備。
- 距離を測定する超音波センサー(青い□)を搭載。
- 反射光を使ってラインを検知するフォトリフレクタ(青い○)を備える。
- 電源供給はリチウムイオンバッテリー(リポバッテリー)から3Vを供給。
- バッテリーの出力低下を補うため、昇圧コンバーター(赤い○)を搭載し、安定した3.3Vの供給を実現。
上部の基板にはRaspberry Pi Pico WHを取り付けてられるようになっています。
ロボットを扱う際の注意事項
以下にロボットを制御する際の注意事項を述べておきます。
- 3V3(OUT)端子には外部から電源を供給しない
- 配線を追加する際には、GNDを中央のピンソケット部分と共通化
- 下部基板のスイッチをオンにした際、基板上のLEDが光らない場合は、すぐにスイッチをオフに
自作した回路基板に問題がある可能性があります。 - 下部基板前方にある2つのLEDは、明るさが自動で変化しますが問題ありません(詳しくはライントレースの回で説明します)。
- 基板上のLEDはPWM制御ができません(Pico Wに限ります)。これは、Pico Wのポートが内部でWiFi機能と共有されているためです。
- ThonnyとVSCodeを併用する際の注意点として、Raspberry Pi Picoの接続が競合する場合があります。接続エラーが発生した場合は、それぞれのソフトウェアが自動で接続していないか確認してください。
環境構築
Raspberry Pi Pico W(以降、RPi Picoと記します)用の専用UF2ファイルをダウンロードしてください。
次のウェブページで「Raspberry Pi Pico W with Wi-Fi and Bluetooth LE support」と検索すると、ダウンロードリンクが見つかります。
公式サイト: Raspberry Pi 公式ドキュメント
次に、RPi Pico本体のBootselボタン(赤丸で示されています)を押しながらUSBケーブルを接続してください。
このボタンは、RPi Picoのディレクトリを開くためのもので、通常の接続時には押す必要はありません。
続いて、下の図のようにRPI-RP2フォルダが開いたら、先ほどダウンロードしたUF2ファイルをこのフォルダに移動してください。
ファイル名はバージョンの違いによって異なる場合があります。
次に、RPi Picoにプログラムを書き込むためのソフトウェア「Thonny」をインストールしましょう。
まず、Thonnyのウェブページへ移動し、下の画像で示されている赤枠部分からダウンロードしてください。(使用するWindowsのバージョンに合ったものを選びましょう)
ダウンロードした.exeファイルを開き、インストールを進めます。途中でポップアップが表示されたら、「日本語(ALPHA)」を選択してください。
参考: インストール手順に関する情報
インストール後、Thonnyを開き、右下の設定エリアから必要な設定を行います。
「Micropythonをインストール」を選択しましょう。
次に表示されるポップアップで「Raspberry Pi Pico W/WH」を選択します。
バージョンが自動で選択されるので、「インストール」ボタンを押します。
これでセットアップは完了です。
基板上のLEDを点滅させる(Lチカ)
インストールが正常に行われたか確認するために、定番の「Lチカ」を試してみましょう。
Thonnyのコードエディタに以下のコードを入力します。
# マイコンを操作するためのライブラリをインポートします
from machine import Pin, Timer
# 制御するピンを指定します
led = Pin("LED", Pin.OUT)
# タイマーを準備します
tim = Timer()
def tick(timer):
global led
# ledの状態を反転させます
led.toggle()
# 1Hz(1秒に1回)の間隔でtick()を呼び出します
tim.init(freq=1.0, callback=tick)
左の赤丸がプログラムを「実行」するボタン、右の青丸がプログラムを「停止」するためのボタンです。
実行してみましょう。
プログラムを保存する際には、以下のようなポップアップが表示されます。
どちらかを選択して保存してください。
(選択した場所にプログラムが保存されます。ただし、RPi Picoのメモリは小さいため注意が必要です。特に理由がなければ「This Computer」を選びましょう。)
なお、ローカルに保存する場合は必ずフォルダを作成して、その中に保存してください。
プログラムを実行してエラーが出なければ、インストールは正常に完了しています。
※「ImportError: no module named 'machine'」というエラーが表示された場合、RPi Picoとの接続がうまくいっていない可能性があります。
また、RPi PicoにPythonファイルを「main.py」という名前で保存しておくと、次回接続時に自動でその処理が実行されるため、ファイル名には注意してください。(これはRPi Picoの仕様です。)
プログラムの解説
最初の行、from machine import Pin, Timer
は、machine
というライブラリからPin
とTimer
を使うことを宣言しています。この宣言をしないとライブラリの機能が使用できません。
次に、led = Pin("LED", Pin.OUT)
は、マイコンのI/Oピンの設定を行っています。LEDを操作するためにピンを指定し、そのピンにled
という名前をつけることで、簡単に制御できるようにしています。
続いて、tim = Timer()
はタイマーを作成するコードです。もしこの動作がわからなければ、次のコードを追加して確認してみてください。自動的にタイマーの状態が計算され、tim
という変数に格納されます。
print(Timer())
print(tim)
次に、tick()
関数を定義しています。この関数内で使う変数を外部と共有するため、global led
と記述しています。これにより、関数の内外で同じled
変数を使うことができます。led.toggle()
は、LEDの現在の状態を反転させる関数です。
最後に、tim.init(freq=1.0, callback=tick)
で、1Hz(1秒に1回)の間隔でtick()
を実行するよう設定しています。ここでinit
は「初期化」を意味します。
以上です。
次回から本格的にプログラミングを進めていきます。
次回はこちら