「Raspberry Pi」カテゴリーアーカイブ

次期モデル Mini Pupper 2 ラズパイCM4で足座標指定

前回はラズパイ CM4で直接サーボ角度を指定してミニぷぱ動作を楽しみました。

次期モデル Mini Pupper 2 ラズパイCM4で足座標指定

 

ここではラズパイ CM4で足の座標を指定しての動作を楽しみました。

 

足座標指定

ここではMini Pupper2に搭載されたラズパイCM4からサーボを制御するESP32に足の座標をシリアルデータ送信して動作させます。

足の座標は各足の付け根を原点にして前後方方向のX [mm]とY方向へのロール角 [°]と高さZ [mm]を指定するようにいたしました。

 

更に座標移動には以前実験したスムージング機能を持たせて、シリアルデータにスムージングの効き具合も一緒に送るようにいたしました。

 

具体的には以下の13のデータを送って動作させます。
[スムージング[%],  前右x, θ. z, 後右x, θ. z, 前左x, θ. z, 後左x, θ. z, ]

スムージングは以下のように実施しています。

$$現在の座標 = 指示座標 * (100 -スムージング) [\%] + 前回の座標 * スムージング [\%] $$

 

動作

まずは各足の高さを指定して屈伸させてみました。
スムージングがない(0%)と動作が急峻になります。

 

スムージング機能によって動作が柔らかくなり振動も減っています。
移動座標と一緒にスムージング具合[%]も送っていることが今回のミソです。

歩行

足の座標を指定して歩行も試してみました。


こちらもスムージングによって動きが非常にスムーズになっています。

 

歩行動作は以下の4ステートをシリアルデータとしてCM4からESP32(シリアルサーボ)に送るだけで実現できました。

各ステートを100msec毎に送信。

 

スムージングによって各ステート間が良い感じで補完されてスムーズな歩行が実現されました。

次の動作座標を動的に動かしても同様にスムーズな動作が可能であると考えます。
足座標指定による動作は非常に有用な方法なのではないでしょうか。

おわりに

ここではラズパイ CM4で足先の座標を指定してのミニぷぱ動作を楽しみました。

スムージング具合も指定することで大まかな座標指定でも滑らかに動けることがわかりました。
CM4でモーション座標をサクサク流したり、もしくはセンシングで動的に座標を指定しても十分な動作が期待できそうで大変喜んでおります。

それではまた。

次期モデル Mini Pupper 2 ラズパイCM4でサーボ角度指定

前回はミニぷぱ2でディスプレイ表示とスピーカによる音声再生を楽しみました。

次期モデル Mini Pupper 2 CM4でメディアを堪能

 

また前々回はRaspberry Pi Compute Module 4 (CM4) からESP32に組み込まれた動作モードを起動しての動作を楽しみました。

次期モデル Mini Pupper 2 に Raspberry Pi Compute Module 4 を搭載

ここではCM4で直接サーボの角度を指定して動かす仕組みを構築して、ミニぷぱを楽しんでみました。

ミニぷぱ2構成

ミニぷぱ2の構成は大まかに以下の通りです (製品版は変更となる可能性がございます)。

前々回はCM4からシリアル通信で1文字モーションコード送って、ESP32に書き込んだ動作を起動させました。

ここではミニぷぱの12個のサーボの角度をCM4から直接指定して動作させてみました。

サーボ角度指定

CM4から12個分のサーボの角度をシリアル送信してESP32でサーボを指定の角度に動かします。

以下の動画のようにCM4のNode-REDでシリアルデータを送信しました。

伏せの状態を初期姿勢としすべてのサーボの角度を0°としています。
Node-REDでは以下のようにシリアル送信しています。

var a = new Int8Array(13);
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;
a[4] = 0;
a[5] = 0;
a[6] = 0;
a[7] = 0;
a[8] = 0;
a[9] = 0;
a[10] = 0;
a[11] = 0;
a[12] = 0;
msg.payload = a + "\n";
return msg;

ミニぷぱのサーボは12個ありIDが1から12まで割り振られています。配列の0が扱いにくいのでa[13]としてa[1]~a[12]をサーボ角度として使用しています。

立ちの姿勢は以下の通り。

var a = new Int8Array(13);
a[0] = 10;
a[1] = 0;
a[2] = 45;
a[3] = 45;
a[4] = 0;
a[5] = -45;
a[6] = -45;
a[7] = 0;
a[8] = 45;
a[9] = 45;
a[10] = 0;
a[11] = -45;
a[12] = -45;
msg.payload = a + "\n";
return msg;

 

ミニぷぱ立つ

CM4から直接サーボの角度を指定できるようになったので、モーションの作りこみが楽になりました。
ESP32は書き込みに時間がかかりますので。。

早速モーションバリエーションを楽しみました。

なんと立ってしまいましたwww

詳細説明は省略しますがNode-REDのフローは以下のような感じ

 

サーボ角度をビシビシ指定しているので動きが急峻ですね。。
動作間のスムージングは必要そうです。

 

本当は立ち上がった後に前進歩行させたかったのだけど。。w
以下のように かかとかつま先のアタッチメントつければいいかもしれませんね。

おわりに

ここではCM4で直接サーボ角度を指定してミニぷぱ動作を楽しみました。

IMUはESP32に接続されているので、IMUと動作を絡める際にはどうすればよいかなどまだまだ検討の余地はあります。

CM4でサクサク モーション指定できるので色々な動作を検討したいです。
指定角度間のスムージングなども検討したいです。

それではまた。

追記

バク宙挑戦 (2022/11/15)

前機種でも試したバク宙。

 

今回もやってみた。CM4によってかなり軽量化されてるのでさてどうなるか。。

ダメでした。。後頭部殴打www

構造上後ろ足が後ろにまっすぐ伸びないのよ。。
前宙も試したけどダメだった。。

サーボのトルクどうこう以前に構造的に無理そうでした。

次の記事

次期モデル Mini Pupper 2 ラズパイCM4で足座標指定

次期モデル Mini Pupper 2 ラズパイCM4でメディアを堪能

前回はRaspberry Pi Compute Module 4 (CM4) をミニぷぱ基板に搭載してESP32との連動やAlexa連携を楽しみました。

次期モデル Mini Pupper 2 CM4でメディアを堪能

ここではミニぷぱ2基板上でCM4に接続されたディスプレイとスピーカの動作を楽しみました。

ここで使用している基板は製品版と異なる場合があります。何卒ご了承ください。

 

ディスプレイ

ディスプレイは前モデルと同様にST7789が使用されておりました。
以前と同じようにディスプレイ表示させてみました。バックライトのGPIOピンが異なるくらいの違いでした。

ロボット犬『Mini Pupperミニぷぱ』Pythonでモーション記述

動作

無事に表示。画像はST7789のpythonライブラリのサンプルを使用。
https://github.com/pimoroni/st7789-python

スピーカ

基板にはスピーカアンプ (NS4890B)も搭載されておりました。

アンプへの電源供給ON/OFFピンがGPIO22、モノラル入力がGPIO12でした。

アンプ出力に手持ちのスピーカを接続しました。
コネクタが持ってない型だったのではんだ付けしました。

動作

GPIO22をHighにしてアンプの電源をONにして、GPIO12からPWMを出力してみました。

ブザーのような音が出力されています。

 

CM4には通常のラズパイのようにヘッドホンジャックがないので、以下をconfig.txt に追加します。

dtoverlay=audremap,pins_12_13 

これによって、音声再生出力がGPIO12, 13からされるようになります。
ミニぷぱ2基板はモノラル出力なのでGPIO12のみ使用します。

CM4でYoutubeを再生しスピーカから音声が再生されることを確認しました。

参考

おわりに

ここではミニぷぱ2でディスプレイ表示とスピーカによる音声再生を楽しみました。

やはりラズパイはメディアに強いなという実感を強く受けました。
ミニぷぱの動作にメディアを絡めることでさらに表現が増すのではないでしょうか。

それではまたお会いしましょう。

追記

移動するメディアプレイヤー (2022/11/17)

CM4でYoutube再生しつつディスプレイにはサムネイルを表示。
ただそれだけww

次の記事

次期モデル Mini Pupper 2 に Raspberry Pi Compute Module 4 を搭載

次期モデル Mini Pupper 2 に Raspberry Pi Compute Module 4 を搭載

これまでは次期モデル Mini Pupper 2 をESP32のみで楽しんでまいりました。
前回はより製品版に近いとされる基板の動作を確認しました。

次期モデル Mini Pupper 2 新規基板を味見

 

Mini Pupper 2 の基板にはRaspberry Pi Compute Module 4 (CM4) も搭載可能です。

 

この度、CM4を提供いただきました。MangDang社様本当にいつもありがとうございます!!

ここからはCM4とESP32によるミニぷぱ動作を検証します。

ここで使用している基板は製品版と異なる場合があります。何卒ご了承ください。

 

CM4設定

提供いただいたCM4モジュールはeMMCのないモデルでした。
小さくてビックリ!!

 

早速搭載。

 

Mini Pupper 2基板にはSDカードスロットとmicro-HDMIコネクタが搭載されています。

 

Raspi OS(32bit)を書き込んだSDカードを入れて起動を試みたのですが、すぐにリセットしてしまう謎の症状に苦しみました。。

調査したところ以下でも同様の症状が報告されており、解決策として書き込みのあった
config.txt を修正 ( “dtoverlay=vc4-kms-v3d” -> “dtoverlay=vc4-fkms-v3d”) する方法で改善し無事に起動できました。

https://forums.raspberrypi.com/viewtopic.php?t=323920

CM4 – ESP32間通信確立

CM4の起動が無事できたので更にVNCとNode-REDの設定も実施し、ここではESP32-S3との通信を目指します。

基板上ではESP32-S3のUART1とCM4のUART3が接続されていましたので、以下を参考にCM4のUART3を有効化しました。
https://toki-blog.com/pi-serial/#UART3UART4UART5

無事にシリアル通信が可能になりました。

ミニぷぱ動作

CM4とESP32-S3 間の通信ができるようになったので、CM4から文字を送ってESP32に仕込んだ動作を起動してみました。

CM4上のNode-REDから文字をシリアル送信してESP32で文字に対応した動作でサーボを制御しています。

 

Alexa連携

ミニぷぱがラズパイOS (Node-RED) で使えるようになりましたのでAlexaとの連携も容易となります。

以下と同じ方法で連携してみました。

ラズパイで気圧測定

 

Node-RED Alexa Home Skill Bridgeでミニぷぱ動作用のデバイスを用意してAlexaアプリの定型アクションで起動発話を設定します。

 

Node-REDで動作用デバイスとモーションコマンドを連結させます。

動作

簡単にミニぷぱとAlexaを連携できました♪

おわりに

ここでは提供いただいたCM4モジュールをミニぷぱ基板に搭載してESP32との連動やAlexa連携を楽しみました。

これまでにCM4なしでESP32のみでミニぷぱ動作を実現していましたので、ここではCM4はESP32に組み込まれた動作を指定するのみの仕事しかしておりません。
しかしESP32で制御用のブラウザページを作りこむのはかなり大変だったので、ラズパイ(CM4)でかなり楽になりそうです。

ミニぷぱ動作においてCM4とESP32の役割の振り分けにはいろいろな方法が考えられそうです。
思いついたモノを上げると

  1. ESP32で各動作を組み込んでおいてCM4で起動 (今回の手法)
  2. CM4から足の座標をESP32に指定
  3. CM4から各サーボの角度をESP32に指定

ESP32のプログラム書き込みが面倒なので上の手法の2か3が良いのかなと現時点では思っています。
製品版の手法もウォッチしつつ検討すすめます。

 

次回はディスプレイやスピーカの動作確認を実施したいです。

次の記事

次期モデル Mini Pupper 2 に Raspberry Pi Compute Module 4 を搭載

みんなのラズパイコンテスト2021 優秀賞受賞!

HomeMadeGarbage Advent Calendar 2021 |5日目

今年も みんなのラズパイコンテストに応募しましたよ。

今年はラズパイを使った目新しいものは製作しなかったので応募を見送ろうかと思ったのですが、なんと今年ラズパイ財団より発売されたマイコンのRaspberry Pi Picoを使用した作品も対象となるとのことで せっかくなので投稿いたしました。

 

Raspberry Pi Pico バーサライタ

今年はRaspberry Pi Pico によるバーサライタで投稿してみました。

Raspberry Pi Pico バーサライタで PIO を考えるーRaspberry Pi Picoへの道8ー

 

新しいマイコンを入手したらバーサライタを製作するという癖があるのですが
Raspberry Pi Pico の高速処理やPIO機能などのおかげで解像度の高い表示が実現でき大変驚きました。

 

 

 

あまり目新しさもないので応募するか迷ったのですが、過去5回ずっとラズパイコンテストに応募して楽しんできたので
締め切りギリギリに思い切って投稿いたしました。

優秀賞をいただくことができ本当に応募してよかったです。
来年はもっと頑張りたいと思います。

一生ラズパイコンテストに投稿し続けることをここに誓います。

 

 

ラズパイコンテスト過去の実績

 

 

 

 

100均のソーラーパネルで Raspberry Pi Pico を駆動

ネットで面白い記事を見つけました。

[bc url=”https://fabcross.jp/news/2021/20210414_sensignal_spresenseexpansionboard.html”]

Spresense用の拡張ボード発売の記事で

”一旦起動すると2V付近まで電圧が落ちても動作し続けるので、乾電池や太陽電池などのエナジーハーベスト電源でも動作可能だとしている。”

とのこと。
 

「ん? こういったマイコンにソーラー直結って用途ありうるの?」
と思ったのですが

といった返信をいただき、なるほど日中のロガー用途がありうるのかと勉強になった次第です。

 

 

自分でもやってみたくなった

特に応用は考えてないのですが、ソーラーパネルをマイコンに直結して駆動できるのか試してみたくなりました。

ダイソーでソーラーパネル調達

早速私が愛用する電子部品屋さんの100円均一ショップ ダイソーに向かいました。

100円と300円のガーデンライトを購入し分解してソーラーパネルを取り出しました。

100円ガーデンライト

 

300円ガーデンライト

 

無事にソーラーパネルの調達ができました。

今回は分解したので使用しませんが、ライトにはニッケル水素バッテリが使用されていました。
日中は充電して夜間はバッテリで点灯という動作です。

Raspberry Pi Pico 駆動

入手したソーラーパネルでRaspberry Pi Pico を駆動してみます。

[amazonjs asin=”B08TZX8X9V” locale=”JP” title=”Raspberry Pi Pico”]

Raspberry Pi Pico には昇降圧DCDC (RT6150) が搭載され入力電圧が1.8~5.5 Vと広いので採用しました。

早速、直射日光のもと300円ガーデンライトのソーラーパネルをRaspberry Pi Picoの電源入力端子 VSYSに直結してみました。

動いた!

本当に動きました!!

Raspberry Pi Pico にはLチカのサンプルコードを書き込んでいます。
安定化電源で消費電力を観たところ、1.8Vで60mAほどと約0.1W消費します。

300円ガーデンライトのソーラーパネルは無負荷時で2.5Vまで上昇しました。
これは正確な実力値ではないので、実際に直結する際には過電圧でデバイスが壊れないようにお気を付けください。

 

ちなみに100円ガーデンライトのソーラーパネルでは出力が足りず2個をパラレルにしてもRaspberry Pi Pico は起動しませんでした。

 

TINY EXPANSION BOARD for Spresense

冒頭に紹介したSpresense用拡張ボードに話を戻します。
以下は販売元のページです。

TINY EXPANSION BOARD for Spresense [R2] 技術資料

入力電源範囲が3〜20Vと広いです。
これであれば無負荷で20Vほど出力する10W級のソーラーパネルでも使用できますね。
起動後は2V近辺まで動作できるとのことで、ソーラーパネル直結駆動に最適な仕様といえます。

しかし高い。。。
明確な応用がない趣味の勉強で¥12,800は出せない。。

[bc url=”https://www.switch-science.com/catalog/7096/”]

 

おそらく入力電源範囲の広い昇降圧DCDCがのってるはずだから、電源部だけ欲しいなww 

 

おわりに

100均のソーラパネル直結でRaspberry Pi Pico を駆動できることが分かりました。
しかし日中クリーンエネルギーでラズパイLチカして何になるのだという話です。
分解しないでガーデンライトとして使用したほうが意味があります。

いいえこの経験は今後の私の人生になにかしら良い影響があるはずです。そう思わせておいてください。

TINY EXPANSION BOARD for Spresenseのように広い入力電圧範囲が実現されればソーラパネルの選択肢もひろがり、応用もききそうです。

なんせSpresenseにはGPS搭載されていますのでリアルタイムに時刻がとれ
真のバッテリレスでのロガーが作れる可能性があります。

 

入力電圧範囲の広い良い昇降圧DCDCが入手出来たら、私もSpresenseでバッテリレスロガー作ってみたいです。

 

追記

Spresenseも動かしてみた(21/4/21)

100円ガーデンライトのソーラーを2個シリーズに接続してSpresenseに直結してみました。

なんとこちらも動きましたね!

[amazonjs asin=”B07H2CG1HP” locale=”JP” title=”SONY SPRESENSE メインボード CXD5602PWBMAIN1″]

Spresenseのメインボードの電源入力
 ・動作推奨電圧:3.6V~4.4V
 ・最大絶対定格電圧:7V
とのことです。

100円ガーデンライトのソーラーを2個シリーズに接続して日光に当てると、無負荷で5Vほど出力しました。

Spresenseは4つのLEDを点灯させるサンプルコードを書き込んでおり
3.6V入力で10mAほど 約0.04Wの消費で非常に低消費電力でした。

Spresenseが低消費電力設計がなされているため、100円ガーデンライトのソーラー2個でも駆動できたと考えられます。

これにGPS動作や外部周辺機器をつけてどれほど消費電力が増すのかが興味深い点ですね。

次の記事

100均のソーラーパネルと SPRESENSE でバッテリーレス ロガー製作

Raspberry Pi Pico バーサライタで PIO を考えるーRaspberry Pi Picoへの道8ー

前回は狭ピッチLEDバーを用いてバーサライタを製作しました。

Raspberry Pi Pico バーサライタ解像度向上 (C/マルチコア) ーRaspberry Pi Picoへの道7ー

 

LEDを2本 Raspberry Pi Pico の2つのSPI出力でそれぞれ制御しました。
その際にシングルコアでの制御とデュアルコア制御で性能が変わらないという不可解な結果を得ました。

ここではこの件について深堀りします。

 

 

仮説

前回は2本のSPI入力LEDバーをPIOを用いて制御しました。
その際にPIOブロックの2つのステートマシン(sm)を用いました。
具体的にはpio0のsm0で64セル、sm1で63セルのLEDを制御しました。

この時シングルコアでLEDを制御した場合とデュアルコアにしてcore0で64セル、core1で63セル駆動した場合で バーサライタの表示分解能に差は生じませんでした。
デュアルコアによる並列処理で分解能が2倍近く向上すると予想していたのですが、全く改善はなかったのです。

そこでステートマシンを分けた時点で並列処理がなされているのではないかという仮説を思い立ちました。
シングルコアでも2本のLEDをPIOで異なるステートマシンで制御していたので既に並列処理されているためデュアルコアにしても性能向上がなかったのではないかと考えたのです。

 

仮説の確認

ステートマシンが並列処理されていることを立証するため、以前製作したバーサライタで動作確認します。

このバーサライタは5mm角LEDテープ24セルを1本用いております。
この時 1周 1000分割を達成し非常に驚きました。

このバーサライタに更にLED 24セルを追加しても別のステートマシンで制御すれば分解能は変わらないはずです。

[amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]

バーサライタ製作

LEDテープを追加します。
 

 

LEDの台の両サイドに割りばしを接着して幅を拡張します。

 

 

完成!
2本のLEDはそれぞれ異なるSPI端子(SPI0, SPI1)で制御します。

動作

仮説通りLED追加しても1000分割達成できました。

追加したLEDはPIOの別ステートマシンで並列処理されていると言えます。

 

おわりに

前回と今回の実験でPIOのステートマシンによる処理が並列に実行されていることがわかりました。

Raspberry Pi Pico にステートマシンは8個搭載されているのでPIO機能によってGPIOを8並列処理できることになります。

これは凄いですね。
PIOの応用によってさまざまな高速処理が実行できそうです。
夢が広がります!

それでは次の道でお会いしましょう!

 

追記

Adafruit 公式ブログ (2021/2/26)

Adafruit公式ブログにて紹介していただきました!

 

[bc url=”https://blog.adafruit.com/2021/02/26/pov-display-using-raspberry-pi-pico-piday-raspberrypi-raspberry_pi/”]

ラズパイ 公式マガジン (2021/3/25)

Raspberry Pi 公式マガジン The MagPi に掲載していただきました!

以下で無料でダウンロードできます。

[bc url=”https://magpi.raspberrypi.org/issues/104″]

[bc url=”https://magpi.raspberrypi.org/articles/pov-display”]

Raspberry Pi Pico バーサライタ解像度向上 (C/マルチコア) ーRaspberry Pi Picoへの道7ー

前回はRaspberry Pi Pico を用いてバーサライタを製作しました。

Raspberry Pi Pico でバーサライタ製作 (C/C++) ーRaspberry Pi Picoへの道6ー

ここでは、表示映像の解像度向上のためにSPI複数出力とデュアルコア動作を検証しましたので報告します。

 

 

SPI複数出力

Raspberry Pi Pico にはハードウェアSPI端子が2個あります (SPI0, SPI1)。

 

この2つのSPI端子でそれぞれLEDテープを制御してみました。

 

[amazonjs asin=”B07VGH4XSQ” locale=”JP” title=”APA102 5050 SMD高輝度チップLEDピクセルフレキシブルストリップライトDC 5V (白 PCB, 1M 144leds IP20)”]

Cコード

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"

#define PIN_CLK0 2
#define PIN_DIN0 3
#define PIN_CLK1 14
#define PIN_DIN1 15

#define N_LEDS 11
#define SERIAL_FREQ (30 * 1000 * 1000)

// Global brightness value 0->31
#define BRIGHTNESS 3

uint32_t color[] ={
    0xFF0000,
    0x00FF00,
    0x0000FF,
    0x00FFFF
};

void put_start_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, 0u);
}

void put_end_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, ~0u);
}

void put_bgr888(PIO pio, uint sm, uint32_t c) {
    pio_sm_put_blocking(pio, sm,
                        0x7 << 29 |                   // magic
                        (BRIGHTNESS & 0x1f) << 24 |   // global brightness parameter
                        c
    );
}


int main() {
    stdio_init_all();

    PIO pio = pio0;
    uint sm0 = 0;
    uint sm1 = 1;
    uint offset = pio_add_program(pio, &apa102_mini_program);
    apa102_mini_program_init(pio, sm0, offset, SERIAL_FREQ, PIN_CLK0, PIN_DIN0);
    apa102_mini_program_init(pio, sm1, offset, SERIAL_FREQ, PIN_CLK1, PIN_DIN1);

    while (true) {
        for (int j = 0; j < 4; ++j) {
            put_start_frame(pio, sm0);
            put_start_frame(pio, sm1);
            for (int i = 0; i < N_LEDS; ++i) {
                put_bgr888(pio, sm0, color[j]);
                put_bgr888(pio, sm1, color[3-j]);
            }
            put_end_frame(pio, sm0);
            put_end_frame(pio, sm1);
            sleep_ms(500);
        }
    }
}

PIO

SPI入力LEDをPIOなる機能で点灯制御しているのですが、2本制御の際はステートマシンなるモノを分けて使用するとよいようです。

PIOブロックは2個内蔵 (pio0, pio1)され、それぞれにステートマシン4個搭載されています (sm0~3)。

 
ここではpio0のsm0でSPI0を、sm1でSPI1を制御して2本のLEDを点灯しました。
 

狭ピッチバーサライタ

以前製作した狭ピッチのLEDバーサライタをRaspberry Pi Picoで制御してみます。

APA102-2020の再考 - バーサライタへの応用 –

このLEDはリフレッシュレートが低いためRGBそれぞれをフル輝度で使用しなくてはならず8色しか出力できませんが
2mm角のLEDが狭ピッチで配置されていますので解像度向上実験にはもってこいです。

構成

2つのSPI出力でLEDを64セル, 63セルずつ制御します。

 

[bc url=”https://www.adafruit.com/product/3776″]

 

動作

先ほどと同様に2個のSPI出力で制御し、回転速度470rpmで回してみたところ、計127個のLEDを1周 240分割で表示できました。

 

ESP32のデュアルコア制御でも200分割が限界でしたので、やはりRaspberry Pi Pico の高速IOは素晴らしいです。

 

デュアルコア制御

Raspberry Pi PicoはCortex-M0+を2個搭載しています。
更なる高解像表示を目指してデュアルコア制御を試します。

Cコード

core0で回転速度計測とSPI0のLED制御し、
core1でSPI1のLED制御しています。

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"
#include "pico/multicore.h"

#define PIN_CLK0 2
#define PIN_DIN0 3
#define PIN_CLK1 14
#define PIN_DIN1 15

#define N_LEDS 64
#define Div 240

#define SERIAL_FREQ (30 * 1000 * 1000)

// Global brightness value 0->31
#define BRIGHTNESS 1

uint32_t color[] ={
    0xFF0000,
    0x00FF00,
    0x0000FF,
    0x00FFFF
};

unsigned long rotTime, timeOld, timeNow;
int numRot = 0;

int stateDiv = 0;
int stateDiv2 = 0;
int numDiv = 0; 
int num = 0;

void gpio_callback() {
    timeNow = time_us_64();
    rotTime = timeNow - timeOld;
    timeOld = timeNow;
    
    numRot++;
    if(numRot >= Div ) numRot = 0;
}

void put_start_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, 0u);
}

void put_end_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, ~0u);
}

void put_bgr888(PIO pio, uint sm, uint32_t c) {
    pio_sm_put_blocking(pio, sm,
                        0x7 << 29 |                   // magic
                        (BRIGHTNESS & 0x1f) << 24 |   // global brightness parameter
                        c
    );
}


void core1_entry() {
    PIO pio = pio0;
    uint sm = 1;
    uint offset = pio_add_program(pio, &apa102_mini_program);
    apa102_mini_program_init(pio, sm, offset, SERIAL_FREQ, PIN_CLK1, PIN_DIN1);

    while (true) {
        if(stateDiv2 == 1){
            put_start_frame(pio, sm);
            for (int i = 0; i < N_LEDS; ++i) {
                put_bgr888(pio, sm, color[num]);
            }
            put_end_frame(pio, sm);
            stateDiv2 = 0;
        }
    }
}

int main() {
    stdio_init_all();
    gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);

    multicore_launch_core1(core1_entry);

    PIO pio = pio0;
    uint sm = 0;
    uint offset = pio_add_program(pio, &apa102_mini_program);
    apa102_mini_program_init(pio, sm, offset, SERIAL_FREQ, PIN_CLK0, PIN_DIN0);

    while (true) {
        if(stateDiv == 1 && time_us_64() - timeOld > rotTime / Div * (numDiv)){
            stateDiv = 0;
        }

        if(stateDiv == 0 && time_us_64() - timeOld < rotTime / Div * (numDiv + 1)){
            stateDiv = 1;
            stateDiv2 = 1;
            
            put_start_frame(pio, sm);
            for (int i = 0; i < N_LEDS; ++i) {
                put_bgr888(pio, sm, color[num]);
            }
            put_end_frame(pio, sm);

            numDiv++;
            if(numDiv >= Div ) numDiv = 0;

            num++;
            if(num > 1 ) num = 0;
        }
    }
}

 

しかし、

デュアルコアでの1周の分割数の向上は確認できませんでした。。。
core1でのLED点灯制御は確実にできていると思うのですが。

core1の動かし方に何か問題があるのでしょうか?

参考

 

画像表示

浮世絵を表示してみました。
シングルでもデュアルでも1周240分割以上にすると表示がおかしくなります。

シングルコア

 

デュアルコア

 

 

おわりに

ここではRaspberry Pi Picoを用いて狭ピッチLEDバーサライタを製作しました。
高解像表示を目指しましたがデュアルコアによる向上は達成されませんでした。

しかしLED 127個で1周 240分割は過去最大の分解能ですので、ひとまず嬉しいです。

 

デュアルコアはについては引き続き勉強します。なにか間違ってるかもしれません。

それでは次の道でお会いしましょう!

 

追記

回転検出部を別コア化(2021/2/17)

以下のブログでPIOで別ステートマシンでのLED制御がすでに並列処理されているために、
デュアルコアによる表示解像度の向上がなかったことがわかりました。

Raspberry Pi Pico バーサライタで PIO を考えるーRaspberry Pi Picoへの道8ー

そこでステートマシンでの並列処理については理解できたので、LED制御と回転計測をデュアルコアで試してみました。

以下のようにcore0で回転計測、core1でPIOのステートマシン2個でLED(64セル、63セル)を制御してみます。

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"
#include "pico/multicore.h"

#define PIN_CLK0 2
#define PIN_DIN0 3
#define PIN_CLK1 14
#define PIN_DIN1 15

#define N_LEDS 64
#define Div 240

#define SERIAL_FREQ (30 * 1000 * 1000 )

// Global brightness value 0->31
#define BRIGHTNESS 1

uint32_t color[] ={
    0xFF0000,
    0x00FF00,
    0x0000FF,
    0x00FFFF
};

unsigned long rotTime, timeOld, timeNow;
int numRot = 0;

int stateDiv = 0;
int numDiv = 0; 
int num = 0;

void gpio_callback() {
    timeNow = time_us_64();
    rotTime = timeNow - timeOld;
    timeOld = timeNow;
    
    numRot++;
    if(numRot >= Div ) numRot = 0;
}

void put_start_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, 0u);
}

void put_end_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, ~0u);
}

void put_bgr888(PIO pio, uint sm, uint32_t c) {
    pio_sm_put_blocking(pio, sm,
                        0x7 << 29 |                   // magic
                        (BRIGHTNESS & 0x1f) << 24 |   // global brightness parameter
                        c
    );
}


void core1_entry() {
    PIO pio = pio0;
    uint sm0 = 0;
    uint sm1 = 1;
    uint offset = pio_add_program(pio, &apa102_mini_program);
    apa102_mini_program_init(pio, sm0, offset, SERIAL_FREQ, PIN_CLK0, PIN_DIN0);
    apa102_mini_program_init(pio, sm1, offset, SERIAL_FREQ, PIN_CLK1, PIN_DIN1);

    while (true) {
        if(multicore_fifo_pop_blocking() == 1){
            put_start_frame(pio, sm0);
            put_start_frame(pio, sm1);
            for (int i = 0; i < N_LEDS; ++i) {
                put_bgr888(pio, sm0, color[num]);
                put_bgr888(pio, sm1, color[num]);
            }
            put_end_frame(pio, sm0);
            put_end_frame(pio, sm1);
        }
    }
}

int main() {
    stdio_init_all();
    gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);

    multicore_launch_core1(core1_entry);

    while (true) {
        if(stateDiv == 1 && time_us_64() - timeOld > rotTime / Div * (numDiv)){
            stateDiv = 0;
        }

        if(stateDiv == 0 && time_us_64() - timeOld < rotTime / Div * (numDiv + 1)){
            stateDiv = 1;
            multicore_fifo_push_blocking(stateDiv);

            numDiv++;
            if(numDiv >= Div ) numDiv = 0;

            num++;
            if(num > 3 ) num = 0;
        }
    }
}

 

結果としましては大きな分解能向上はありませんでした。
1周 240分解能がギリギリ260分割できそうになるくらいの変化でした。

 

ステートマシンが完全に並列処理できていて、回転が470rpm、SPI信号が30MHzの場合、理論分解能値はだいたい
 30MHz ÷ (32bit × 64セル + 64bit) × 60sec ÷ 470rpm = 1813分割
ですので、SPIクロックが遅すぎることはないようです。

まだまだデータ転送方法など工夫次第で高解像度化できそうですが、とにかくPIOは素晴らしいということがわかりました。

Raspberry Pi Pico でバーサライタ製作 (C/C++) ーRaspberry Pi Picoへの道6ー

前回はフォトリフレクタによる割り込みでLED制御を試しました。

SPI入力LEDを堪能 (C/C++) ーRaspberry Pi Picoへの道5ー

今回はついにRaspberry Pi Pico でバーサライタを製作しました。

 

 

バーサライタ構成

構成はこれまで製作してきたハンディーバーサライタ PovRanianと同様です。

バーサライタ装置の製法

 

モータを安定化電源(1V)で給電して回転部を回します。回転部には24セルのLEDのほかに回転を検出するフォトリフレクタとRaspberry Pi Picoが載っており、給電にはワイヤレスチャージモジュールを使用しています。

フォトリフレクタとRaspberry Pi Pico間にはチャタ防止にフィルタとシュミットトリガを挿入しています。

部品

  • Raspberry Pi Pico
    [amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]
     
  • SPI 入力LEDテープ
    [amazonjs asin=”B07VGH4XSQ” locale=”JP” title=”APA102 5050 SMD高輝度チップLEDピクセルフレキシブルストリップライトDC 5V (白 PCB, 1M 144leds IP20)”]
     
  • フォトリフレクタ QTR-1A
    [amazonjs asin=”B014FB8E5C” locale=”JP” title=”QTR-1A フォトリフレクタ・モジュール (2個セット)”]
     
  • シュミットトリガ
    [bc url=”https://akizukidenshi.com/catalog/g/gI-10588/”]
     
  • ワイヤレスチャージモジュール
    [amazonjs asin=”B074PPGM15″ locale=”JP” title=”Seeedstudio_ワイヤレス充電モジュール – 5V / 1A”]
     
  • マブチモーター RS-540SH
    [amazonjs asin=”B004OVD1DO” locale=”JP” title=”マブチモーター RS-540SHモーター”]

 

 

バーサライタ分解能

Raspberry Pi Pico によるバーサライタができましたので、1周の分割数をどれほど大きくできるか試してみます。
これによりRaspberry Pi Pico の実力を測れるのではないかと考えました。

Cコード

フォトリフレクタで1周の時間を計測し、その時間を変数Divで分割して色分け(RGBYの4色)してLEDを点灯させるプログラムをです。

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"

#define PIN_CLK 2
#define PIN_DIN 3

#define N_LEDS 24
#define Div 4

#define SERIAL_FREQ (30 * 1000 * 1000)

// Global brightness value 0->31
#define BRIGHTNESS 3

uint32_t color[] ={
    0xFF0000,
    0x00FF00,
    0x0000FF,
    0x00FFFF
};

unsigned long rotTime, timeOld, timeNow;
int numRot = 0;

int stateDiv = 0;
int numDiv = 0; 
int num = 0;

void gpio_callback() {
    timeNow = time_us_64();
    rotTime = timeNow - timeOld;
    timeOld = timeNow;
    
    numRot++;
    if(numRot >= Div ) numRot = 0;
}

void put_start_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, 0u);
}

void put_end_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, ~0u);
}

void put_bgr888(PIO pio, uint sm, uint32_t c) {
    pio_sm_put_blocking(pio, sm,
                        0x7 << 29 |                   // magic
                        (BRIGHTNESS & 0x1f) << 24 |   // global brightness parameter
                        c
    );
}


int main() {
    stdio_init_all();

    gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);

    PIO pio = pio0;
    uint sm = 0;
    uint offset = pio_add_program(pio, &apa102_mini_program);
    apa102_mini_program_init(pio, sm, offset, SERIAL_FREQ, PIN_CLK, PIN_DIN);

    while (true) {
        if(stateDiv == 1 && time_us_64() - timeOld > rotTime / Div * (numDiv)){
            stateDiv = 0;
        }

        if(stateDiv == 0 && time_us_64() - timeOld < rotTime / Div * (numDiv + 1)){
            stateDiv = 1;
            
            put_start_frame(pio, sm);
            for (int i = 0; i < N_LEDS; ++i) {
                put_bgr888(pio, sm, color[num]);
            }
            put_end_frame(pio, sm);

            numDiv++;
            if(numDiv >= Div ) numDiv = 0;

            num++;
            if(num > 3 ) num = 0;
        }
    }
}

 

4分割

まずは Div = 4で動作確認しました。

400分割

Div = 400 まで増加させても問題なく点灯動作を確認できました。
SPIのクロックSERIAL_FREQ は30MHzとしました。これ以上大きくするとLED表示が正常に実施されませんでした。

Raspberry Pi PicoのIO は非常に高速に動作できるのだと実感できました。

 

画像表示

このままRGBYの4色で分割数上げてもよくわからなくなってきたのでアニメ画を表示してみます。

回転速度 960rpmで1周1000分割でも余裕でアニメ表示ができました!!

回転方向の分解能が大きくてもLEDが24セルですので少し寂しいですね 🙄 

 

性能指数

これまでいろいろなマイコンでバーサライタを製作してきましたので、独自の性能指数を設けております。

性能指数 [hPOV(ヘクトポブ)] = LED数 × 回転数 × 一周の分解能 ÷ 100

現状 Raspberry Pi Picoの性能指数は
 LED 24個 × 回転速度 960rpm × 1000分解能 ÷ 100 = 230,400 hPOV
となりました。

以下が過去のその他マイコンの実績値ですので、Raspberry Pi Picoの性能がうかがい知れます。

  • Teensy 4.0:LED 64個 × 回転速度 530rpm × 200分解能 ÷ 100 = 67,840 hPOV
  • ESP32(デュアルコア):LED 58個 × 回転速度 730rpm × 220分解能 ÷ 100 = 93,148 hPOV
  • SPRESENSE(3コア):LED 57個 × 回転速度 730rpm × 400分解能 ÷ 100 = 166,440 hPOV

 

おわりに

Raspberry Pi Pico によって信じられないほど回転方向の分解能の高いバーサライタ動作を確認することができました。

今後はLEDのセル数を増やすべくSPIの複数出力やマルチコア動作を検討したいと思います。

それでは次の道でお会いしましょう!

次の記事

Raspberry Pi Pico バーサライタで PIO を考えるーRaspberry Pi Picoへの道8ー

SPI入力LEDを堪能 (C/C++) ーRaspberry Pi Picoへの道5ー

前回はフォトリフレクタによる割り込み動作を確認しました。

WindowsでのC/C++環境構築 ーRaspberry Pi Picoへの道2ー

ここではSPI入力のテープLEDの点灯を試してみました。

 

 

サンプルコード動作確認

以下のSPI入力LED APA102のサンプルコードを試してみます。
 https://github.com/raspberrypi/pico-examples/tree/master/pio/apa102

構成

Raspberry Pi Pico のハードウェアSPI(SPI0)でLEDを制御します。

 

[amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]

 

[amazonjs asin=”B07VGH4XSQ” locale=”JP” title=”APA102 5050 SMD高輝度チップLEDピクセルフレキシブルストリップライトDC 5V (白 PCB, 1M 144leds IP20)”]

動作

サンプルコードをビルドしてuf2ファイルをRaspberry Pi Pico にドラッグ&ドロップします。

LEDの制御シーケンスは.pioファイルに記述されていました。

 

独自プロジェクト作成

サンプルコードを参考に自分のワークスペースにフォルダを作成して所望の色でを光らせてみます。

フォルダ (SpiLedTest) には以下を用意します。

  • Pico SDKを参照するための設定を記述した pico_sdk_import.cmakeをコピー
  • LEDの制御シーケンスを記述した apa102.pio をコピー
  • プログラム .cファイル (SpiLedTest.c) 作成。詳細は後述
  • プログラムとビルドの設定を記述する CMakeLists.txt 作成。詳細は後述

Visual Studio Codeでフォルダを開いてビルドします。

.cファイル

4色で交互に点灯するコードです。

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"

#define PIN_CLK 2
#define PIN_DIN 3

#define N_LEDS 11
#define SERIAL_FREQ (5 * 1000 * 1000)

// Global brightness value 0->31
#define BRIGHTNESS 8

uint32_t color[] ={
    0xFF0000,
    0x00FF00,
    0x0000FF,
    0x00FFFF
};

void put_start_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, 0u);
}

void put_end_frame(PIO pio, uint sm) {
    pio_sm_put_blocking(pio, sm, ~0u);
}

void put_bgr888(PIO pio, uint sm, uint32_t c) {
    pio_sm_put_blocking(pio, sm,
                        0x7 << 29 |                   // magic
                        (BRIGHTNESS & 0x1f) << 24 |   // global brightness parameter
                        c
    );
}


int main() {
    stdio_init_all();

    PIO pio = pio0;
    uint sm = 0;
    uint offset = pio_add_program(pio, &apa102_mini_program);
    apa102_mini_program_init(pio, sm, offset, SERIAL_FREQ, PIN_CLK, PIN_DIN);

    while (true) {
        for (int j = 0; j < 4; ++j) {
            put_start_frame(pio, sm);
            for (int i = 0; i < N_LEDS; ++i) {
                put_bgr888(pio, sm, color[j]);
            }
            put_end_frame(pio, sm);
            sleep_ms(500);
        }
    }
}

 

CMakeLists.txt

コピーした.pioファイルを pico_generate_pio_header で宣言しています。

cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)

project(SpiLedTest_project)

pico_sdk_init()

add_executable(SpiLedTest SpiLedTest.c)

pico_generate_pio_header(SpiLedTest ${CMAKE_CURRENT_LIST_DIR}/apa102.pio)


pico_enable_stdio_usb(SpiLedTest 1)
pico_enable_stdio_uart(SpiLedTest 1)

target_link_libraries(SpiLedTest
  pico_stdlib
  hardware_pio
)

pico_add_extra_outputs(SpiLedTest)



動作

これで自由にLEDを制御できるようになりました!

 

割り込みと組み合わせ

前回確認したフォトリフレクタによる割り込み動作と組み合わせてみました。

 

ここではフォトリフレクタで光が遮られると割り込みでLEDの点灯カラーを変えています。

 

おわりに

ついにRaspberry Pi PicoでSPI入力のLEDを自由に制御できるようになりました!

次回はいよいよバーサライタを組み立てていこうと考えております。
Raspberry Pi Picoの性能が浮き彫りになるのではないかと非常に楽しみです♪

それでは次の道でお会いしましょう!

次の記事

Raspberry Pi Pico バーサライタ解像度向上 (C/マルチコア) ーRaspberry Pi Picoへの道7ー

フォトリフレクタで割り込み動作 (C/C++) ーRaspberry Pi Picoへの道4ー

前回は Raspberry Pi Pico で割り込み動作を確認しました。

WindowsでのC/C++環境構築 ーRaspberry Pi Picoへの道2ー

今回は前回のタクトスイッチをフォトリフレクタに変えて割り込み動作を楽しみました。

 

 

構成

前回のタクトスイッチをフォトリフレクタに変えて、チャタリング防止のためにフィルタとシュミットトリガを挿入しています。

 

[amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]

 

[amazonjs asin=”B014FB8E5C” locale=”JP” title=”QTR-1A フォトリフレクタ・モジュール (2個セット)”]

 

[bc url=”https://akizukidenshi.com/catalog/g/gI-10588/”]

 

 

動作

コードは前回とほぼ同じで割り込みのトリガを立下りを立ち上がりにしただけです。

 

フォトリフレクタを指で遮るとシリアル出力されます。
チャタもなく正確に動作できています。

 

おわりに

フォトリフレクタでの割り込み動作が実現できました。
これでバーサライタを製作した際に回転速度をフォトリフレクタによって計測できそうです。

次回はSPI入力LEDの点灯実験を実施したいと思います。

それでは次の道でお会いしましょう!

次の記事

Raspberry Pi Pico バーサライタ解像度向上 (C/マルチコア) ーRaspberry Pi Picoへの道7ー

割り込み動作を堪能 (C/C++) ーRaspberry Pi Picoへの道3ー

前回は Raspberry Pi Pico のWindowsでのC/C++環境構築 を行いました。

WindowsでのC/C++環境構築 ーRaspberry Pi Picoへの道2ー

 

当初はRaspberry Pi Picoの公式ドキュメントをしっかり読んできちんと理解しようと意気込んでいたのですが。。。

SDKの資料を読んでもよくわかりませんでした。 😥  特にCMakeLists.txtのこととか
 Pico C/C++ SDK

Raspberry Pi PicoのキモであろうPIOについても.pioファイルに謎の記述しないといけないなど使いこなせる気が全くしませんでした。

Raspberry Pi Pico をぶん投げてやろうかとも思いましたが、いつも通りサンプルコードをゴリゴリ
いじってやりたいことを達成していく いつものスタイルにもどします。

ソフトウェア難しすぎ。

 

 

割り込み動作

まずはGPIOによる割り込み動作の実現を目指します。

以下にC言語のサンプルコードがありました。
 https://github.com/raspberrypi/pico-examples/blob/master/gpio/hello_gpio_irq/hello_gpio_irq.c

サンプルコードを参考にGPIOに接続されたボタンを押すと、割り込みでシリアル出力するコードを作成しています。

構成

GPIO2ピンをプルアップしてタクトスイッチを接続しました。

[amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]

 

Cコード

サンプルコードを参考にGPIO2がLOWレベルに落ちた時に割り込んでシリアル出力するコードを作成しました。

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "pico/binary_info.h"


void gpio_callback() {
    puts("interrupt!!\n");
}

int main() {
    stdio_init_all();

    gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);

    while (1) {
        
    }
}

 

動作

 

本来はボタンを押したときに1回シリアル出力してほしいのですがチャタリングのように複数回出力されるときがあります。
これはRaspberry Pi Pico の動作が高速のためにボタンを押して信号が落ちきる前にしきい値付近で複数回判定してしまうために起きます。ESP32でも同様の動作となります。

 

おわりに

Raspberry Pi Picoの公式ドキュメントをしっかり読んで理解を深めるのはあきらめました。

いきなり頓挫してしまいましたが、サンプルコードを勉強してなんとか Raspberry Pi Picoをもちいてバーサライタ製作を実現したいと思っています。
噂ではSPIが非常に高速とのことなので非常に楽しみです。

今回は割り込み動作を試してみました。
次回は、Raspberry Pi Pico のGPIOが内部でプルアップ/プルダウンできるのかの調査と割り込みボタンのチャタリング対応を実施したいと思います。

それでは次の道でお会いしましょう!

追記

GPIOプルアップ (21/2/11)

次の記事

フォトリフレクタで割り込み動作 (C/C++) ーRaspberry Pi Picoへの道4ー

WindowsでのC/C++環境構築 ーRaspberry Pi Picoへの道2ー

前回はこの道での意気込みと目標のみで何もできなかったので、
今回はいよいよ Raspberry Pi Picoに火を通していきたいと思います。

 

 

開発環境構築

以下の公式ドキュメントに従って開発環境を構築しました。
 

基本的にはRaspberry Pi 4などでRaspberry Pi Picoを開発するような書き方になっているのですが、
ラズパイでコーディングはしんどすぎるので ここではWindowsで
開発環境を構築します。

WindowsでのC/C++ 開発環境構築方法は スタートガイド の8.2節に記載ございます。
ほぼ書いてる内容通りに実施で構築できました。

各種ソフトインストールの際に”Pathを通す”にチェック入れるなど注意が必要です。
以下の動画と合わせて実行するとスムーズです。

サンプルコード実行

スタートガイド に従ってVisual Studio Codeでサンプルコードをビルドしてみました
(ガイドに従うとすべてのサンプルコードがビルドされ少し時間がかかるのでご注意ください)。

ビルド後にbuildフォルダに各サンプルコードのuf2ファイルが生成されます。
このuf2ファイルをRaspberry Pi Picoに書き込みます。

Raspberry Pi PicoのBOOTSELボタンを押しながらPCに繋がれたUSBケーブルを接続すると、
下のようにUSBストレージとして認識されます。

ここにuf2ファイルをドラッグ&ドロップするだけです。

サンプルコードblinkを書き込むと下の動画のように基板に実装されたLEDが点滅します。

 

書き込み時にいちいちUSBケーブルを抜いてBOOTSELボタンを押しながらつながなくてはならないので少し面倒です。

イネーブルピン(RUN)とGND間にスイッチを接続して、USBケーブル抜き差しを回避する工夫をされている方もいます。

[bc url=”https://qiita.com/jamjam/items/de7b050ccd108baa0947″]

 

プロジェクト作成

ここまではサンプルコードをダウンロードしてビルドしただけですが、独自コードの作製に向けて
プロジェクトの作り方を学びます。

スタートガイド の7章にプロジェクト生成方法の記載がございます。

フォルダを作成(フォルダ名”test”としました)して、そこにプログラムとビルドの設定を記述した CMakeLists.txtと
Pico SDKを参照するための設定を記述した pico_sdk_import.cmakeをコピーします。

プログラム(test.c)とCMakeLists.txtはスタートガイド (p. 27)に記載のものをコピーして使用しました。
test.cはLEDを点滅しながら文字列”Hello World\n”を出力するコードです。
CMakeLists.txtでシリアル出力先の有効無効など記述していました。正直CMakeLists.txtについてはまだよく理解できていません。

Visual Studio Codeで作製したtestフォルダを開いてビルドしました。
test/buildフォルダにuf2ファイルが生成されるのでRaspberry Pi Picoに書き込みます。

Visual Studio Codeでシリアルモニタできるのか私にはわかりませんでしたので
親しみ深いTera Termで文字列出力を確認しました。

 

[amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]

おわりに

ついにWindowsでRaspberry Pi PicoのCプログラムを作れそうなところまで来ました!

PICの時にも感じましたが開発環境構築って本当に大変ですね。。
書いてある通りにやってるつもりでも間違うこと多々あるし。。

次回からは以下の公式ドキュメントを紐解いてRaspberry Pi Pico の理解を深めたいと思います。
 Pico C/C++ SDK

それでは次の道でお会いしましょう!!

次の記事

Raspberry Pi Pico バーサライタ解像度向上 (C/マルチコア) ーRaspberry Pi Picoへの道7ー

Raspberry Pi Picoへの道 爆誕 ーRaspberry Pi Picoへの道1ー

Raspberry Pi財団からとんでもない製品が発売されましたね。

独自開発したデュアルコア(ARM Cortex M0+) RP2040マイコンを搭載したRaspberry Pi Pico とのことです。

ラズパイなのにシングルボードコンピュータじゃなくマイコンだということで大変驚きました。

 

 

Raspberry Pi Pico

Raspberry Pi Picoの仕様は以下の通り
 https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf

詳細は各所で取り上げられておりますので、私が気がなった点のみ挙げます。

昇降圧DCDC

昇降圧DCDC (RT6150) が搭載され、内部電源3.3Vが生成されています。

Vsysピンに1.8~5.5V印可でボードが起動するとのことです。
乾電池2本で楽しめるかもしれませんね。

PIO

プログラマブルI/O(PIO)が8ピンあるとのこと。
PIOとは何でしょうか?現状私にはわかりません。大変気になります。

開発環境

公式の開発環境としてCとMicroPythonが用意されているようです。

Adafruit社もRP2040チップ搭載の独自ボードを発売予定なので、今後CircuitPythonにも対応すると思います。

 

ArduinoもRP2040搭載ボード開発中とのことですのでArduino IDEに対応もするでしょうね。
なんだかすごい時代ですね!

 

道 爆誕

早速スイッチサイエンスで購入いたしました。

[bc url=”https://www.switch-science.com/catalog/6900/”]

 
リールカットされた状態で届き、高級感すら漂います。

 
いつもなら新しいマイコンを入手した際には バーサライタ を製作するのがだいたいの習わしなのですが、 Raspberry Pi Pico については開発環境の構築から実施しなくてはなりません。

これまではArduino IDEでサンプルコードをいじくりながらブラックボックスであるマイコンを何とか動かしてきましたが
折角ですのでマイコンが何たるかを知るべくきっちり勉強しようと思い ここに道を開通します!

以下資料に沿ってC/C++開発環境で Raspberry Pi Pico を学ぶ予定です。

 

[amazonjs asin=”B08TQSDP28″ locale=”JP” title=”Raspberry Pi Pico Raspberry Pi RP2040デュアルコアARMCortex M0 +プロセッサをベースにしたフレキシブルマイクロコントローラーボード”]

道の目標

この道の目標として、Raspberry Pi Picoを通してマイコンの何たるかを知るのはもちろんとして
具体的にはバーサライタ製作実現に向けて以下を挙げます。

  • センサで割り込んで回転速度を計測
  • 2つのハードウェアSPIでLEDを制御
  • デュアルタスクでLEDを制御して高解像表示を実現

まだRaspberry Pi Picoを開封すらしていないのでどうなるかわかりませんが、
良い機会ですので一生懸命勉強したいと思います。

この道を通してRaspberry Pi Picoの理解だけではなく慣れ親しんだArduino や ESP32の理解が深まれば、今後の人生に良いと考えております。

それでは次の道でお会いしましょう!

次の記事

フォトリフレクタで割り込み動作 (C/C++) ーRaspberry Pi Picoへの道4ー

Raspberry Pi で 金魚水槽管理システム を構築

HomeMadeGarbage Advent Calendar 2020 |4日目
Raspberry Pi Advent Calendar 2020 |4日目

これまでESP32等で構成していた我が家の金魚水槽システムですが、
この度メンテナンスのし易さや拡張性の高さから制御をRaspberry Pi で実施することにいたしました。

☟従来型の構成は以下の通りです。
家のローカルネットワーク内で水槽の監視・管理を実施しておりました

金魚水槽のフィルターをブクブクから外掛けフィルターへグレードアップ

 

外出時にも対応したいと考え、外部監視・制御にはセキュリティの観点からATOM CamやAlexaアプリの既存のサービスの使用を採用いたしました。

 

 

システム概要

本システムの機能は以下の通りです。

  • 水槽LED照明のON/OFF
  • 自動エサあげ機構
  • 水槽の水温、pHの監視

いずれも自宅内でWebページからの制御・監視が可能で
さらにAlexaアプリと連動させてスマートスピーカ Amazon Echo dot での音声による制御も可能です。
水温、pHについては以前製作した我が家のコンシェルジュのおしゃべりティラノくんに発話で報告させることができます。

外出先からのエサあげ等の制御にはAlexaアプリを用いてスマホで実施し、
遠隔監視にはネットワークカメラ ATOM Cam を使用いたします。

 

構成

以下が本システムの構成図です。
Raspberry Pi Zero W のGPIO端子に照明用のテープLED、温度センサ、エサあげ用ソレノイドを接続し、
pHセンサをマイコンを介してUSB Host端子に接続しています。

部品

  • Raspberry Pi Zero W
    [amazonjs asin=”B07PHPK8CP” locale=”JP” title=”Raspberry Pi Zero WH GPIOピンヘッダー ハンダ付け済み Wi-Fi & Bluetooth(ヒートシンク、SDカード32GB(Raspbian Buster Liteインストール済)付き”]
     
  • フルカラーLED Neopixel (WS2812B ) 48セル
    [amazonjs asin=”B01N6AJAI8″ locale=”JP” title=”ALITOVE LEDイルミネーション WS2812B アドレス可能 LEDテープライト5050 RGB SMD 5 m 300個ピクセル夢色 防水IP67ホワイトPCB DC 5V”]
     
  • 防水温度センサ DS18B20
    [amazonjs asin=”B07M886SBK” locale=”JP” title=”3個 セット ArduinoセンサーDS18B20のための防水デジタルサーマルプローブまたはセンサーラボ温度測定材料 (3個 1M)”]
     
  • pHセンサ PH-4502C
    [amazonjs asin=”B07VWFNBL8″ locale=”JP” title=”DiyStudio 液体PH0-14値検出センサーモジュール+ PH電極プローブBNC Arduino用”]
     
  • Arduino Pro Micro 互換ボード
    [amazonjs asin=”B086GPX434″ locale=”JP” title=”VKLSVAN Pro Micro USB ATmega32U4 5V/16MHz マイクロコントローラ Micro USB 開発ボード Arduinoに対応”]
     
  • ソレノイド
    [bc url=”http://www.takaha.co.jp/SHOP/ssbc-0830.html”]
     
  • N-MOSFET IRF520PBF
    [bc url=”https://www.digikey.jp/product-detail/ja/vishay-siliconix/IRF520PBF/IRF520PBF-ND/811765″]
     
  • ダイオード 1N5819
    [amazonjs asin=”B009HJKVAO” locale=”JP” title=”【ノーブランド品】20枚 1N5819 DO-41 ダイオードショットキーダイオード”]
     
  • MOSFET駆動用レベルシフタ
    [amazonjs asin=”B011U11SKI” locale=”JP” title=”ロジックレベル双方向変換モジュール”]

 

各部品の動作確認

本システムはNode-REDで構築しております。
ここでは各接続部品のNode-REDによる動作確認を行います。

Neopixel制御

NeoPixel用のNode-REDノードは存在し以下を参考に導入致しました。
 https://www.npmjs.com/package/node-red-node-pi-neopixel

NeoPixelの信号線をラズパイの12ピン(GPIO 18)し、
以下のようにrpi-neopixelsノードにカラーコードを送るとLEDが点灯いたします。

自動エサあげ機構

エサあげの機構には タカハ製の5Vプッシュソレノイド SSBC-0830/SSBC-0830-01(7.5Ω) を使用いたしました。

筐体は3Dプリンタで製作いたしました。

 

構成は以下の通り

Node-REDでラズパイのGPIOピンを制御して
ソレノイドに5V印可してエサが押し出される仕組みにしました。

水温計

水温系として1 wire温度センサ DS18B20を使用いたしました。

DS18B20のNode-REDノードも存在し、以下を参考に導入致しました。
 https://www.denshi.club/pc/raspi/iot6.html

DS18B20の出力をラズパイの7ピン(GPIO 4)に接続します。

pH計

pH計にはアナログ出力の PH-4502C を使用しました。

センサの校正方法など詳細は以下を参照ください。

pHセンサを味見 ーエッジAI活用への道 7ー

 

ラズパイにはアナログ値の入力ピンがないためArduino互換マイコンのアナログピンにpHセンサ出力を接続し、シリアルでpH値を出力します。

ラズパイのUSB Hostコネクタにマイコンを接続してシリアルでpH値を受信します。

シリアル通信Node-REDノードは以下を使用しました。
 https://flows.nodered.org/node/node-red-node-serialport

 

マイコンArduinoコード

シリアルで文字”1″が入力されるとpHをシリアル出力します。

byte  input;

const int analogInPin = A3; 
int sensorValue = 0; 
unsigned long int avgValue; 
float b;
int buf[10],temp;

void setup() {
  Serial.begin(115200);
}

void loop() {
  input = Serial.read();
  
  if (input == '1') {
    for(int i=0;i<10;i++) {
      buf[i]=analogRead(analogInPin);
      delay(10);
    }
    for(int i=0;i<9;i++){
      for(int j=i+1;j<10;j++){
        if(buf[i]>buf[j]){
          temp=buf[i];
          buf[i]=buf[j];
          buf[j]=temp;
        }
      }
    }
    
    avgValue=0;
    for(int i=2;i<8;i++) avgValue+=buf[i];
    
    float pHVol=(float)avgValue*5.0/1024/6;
    float phValue = -6.1507 * pHVol + 22.511;
   
    Serial.println(phValue);
  }
}

 

Node-red自動起動設定

以下のコマンドの実行でラズパイ起動で自動的にNode-REDも起動します。

$ sudo systemctl enable nodered.service

 

水槽システム Node-REDフロー

水槽LED制御

水槽の照明としてLEDテープを48セル設置し、WebページやAlexaによる音声でON/OFF 制御します。

 

① LED ON functionノード

次段に全白のLEDカラーコード(#FFFFFF)を送信します。

 

② LED OFF functionノード

次段にLED消灯カラーコード(#000000)を送信します。

 

③rpi-neopixelsノード

前段からの色信号(ON:#FFFFFF / OFF:#000000)を受けてLEDを制御します。
輝度は30%としています。

エサあげソレノイド制御

WebページやAlexaによる音声でラズパイのGPIO23をON/OFFしソレノイドを 制御します。

 

① ソレノイド ON functionノード

次段に数値1を送ります。

 

② LED OFF functionノード

ON function後200msecの遅延後に次段に数値0を送ります。

 

③ rpi-gpio outノード

前段からの信号を受けてソレノイドを制御します。200msecの間だけ数値1がきてGPIO23がONになりソレノイドに電流が供給されエサが押し出されます。

ラズパイのGPIO制御ノードでGPIO23を制御します。

 

水温・pH測定

Alexaによる音声で起動しおしゃべりティラノくんに発話で水温とpHを報告させます。

 

① rpi-ds18b20ノード

rpi-ds18b20ノード で水温を取得します。

 

② functionノード

前段からの水温を小数点第1位で丸めて変数waterに格納し、
次段に”1″の文字を送信。

 

serial requestノード

前段の文字”1″を受けてpHセンサ値を次段に返します。

 

④ functionノード

前段からのpH値を変数phに格納

 

⑤ templateノード

水温とpHの測定値を受けて、発話内容を生成します。

 

⑥ google-ttsノード

Google Text to Speech APIを呼び出すgoogle-ttsノードを使用しました。
 https://flows.nodered.org/node/node-red-contrib-google-tts

前段からの発話内容を入力して発話のmp3 URLを返します。
言語は日本語(ja-JP)を指定しています。

 

⑦ udp outノード

前段で生成されたmp3 URLをUDPで おしゃべりティラノくんに送信して発話させます。

Webページ生成

“ラズパイのNode-REDのURL/aquarium”にアクセスでWebページを生成します。

ブラウザ表示前に水温とpHを計ってtemplateノードに渡しています。
templateノードにWeb表示用コードを記述しています。

以下がWebページ画面です。

“ごはんをあげる”ボタンで/feedにGETリクエストを投げてソレノイド制御します。
LEDのON/OFFスイッチで/on または /offのGETリクエストを投げてLEDを制御します。

水温とpHの数値を表示します。

Alexa連動

Node-RED Alexa Home Skill Bridge というNode-REDノードを用いてAlexaと連動させ、システムの音声による制御を可能にしました。

Node-RED Alexa Home Skill Bridgeの設定等の詳細は以下を参照ください。
Node-RED Alexa Home Skill Bridge へのユーザ登録や、
スマホのAlexaアプリでNode-REDスキルを有効にしてAlexaサービスとNode-RED Alexa Home Skill Bridgeを紐づける必要があります。

ラズパイで気圧測定

 

デバイス登録

水質の発話報告を起動する”Aquarium”とエサやりソレノイドを起動する”Feed”と
LEDを起動する”水槽”を登録しました。

“水槽”はON/OFF動作させるのでActionにONとOFFを選択しました。

 

Node-RED

Node-REDに登録したデバイスのノードを配置します。

 

定型アクションを編集

以上で登録したデバイスをスマートスピーカAmazon Echoから起動させることが可能になりました。

デバイス”水槽”はLEDのON/OFFを制御するので「水槽つけて」、「水槽消して」で問題ないですが、
“Aquarium”と”Feed”はON/OFFの発話だと不自然なので
Alexaスマホアプリで定型アクションを登録しました。

「アレクサ、ご飯あげて」でデバイス”Feed”を起動してソレノイドを制御します。

 

「アレクサ、水質教えて」でデバイス”Aquarium”を起動してティラノくんに水温とpHを報告してもらいます。

 

動作

水槽設置前の動作テスト

 

ユニットはタッパに入れて水槽裏に設置いたしました。

Webページによる動作

音声による動作

遠隔動作

旅行先でもご飯の供給ができました!

 

追記

みんなラズパイコンテスト

本システムで今年もみんなのラズパイコンテストに応募いたしました。
受賞はできましたが3年連続となるスタートダッシュ賞をいただくことができました♪