電子趣味の部屋

電子系のガジェットやアプリ開発等の趣味の話題を書いてます

Raspberry Pi Pico で MicroPython

Raspberry Pi Picoを入手したので、MicroPythonで遊んでみました。
C/C++で開発してネイティブで動作させることもできるのですが、MicroPythonの方が手軽に遊べるのでRaspberry Pi PicoはMicroPythonで遊ぶことにします。

この手物のはインタプリタは遅くてコンパイルされたネイティブなバイナリコードを直接動作させるイメージがあるのですが、それは一般的に組み込み用のCPUがPCと比較して非力で動作が遅いというのが原因だと思います。
その点Raspberry Pi PicoはARMベースで動作クロックも133MHzもあるので、使用してみると思ったより快適で十分だと思います。まだそんなに高度なことはしていないので、ArduinoでC/C++で動作させるのと感覚的に同等で速度的にも気にならなさそうです。
PHPやJavaScriptからプログラミングを始めた人はわかりませんが、昔のPCでBASICから始めた人はコンパイル言語は憧れでどうしてもC/C++の速度に頼りがちになりますが、十分な速度で動作する場合はインタプリタの方が手軽で良いですね。
Raspberry Pi PicoでMicroPythonを動作させると、0.23W前後で動作しています。

開発環境はThonnyを使用します。
Thonny, Python IDE for beginners
個別にMicroPythonのファームウェアを書き込んでシリアル通信でソースを転送して実行という使い方もできると思いますが、Thonnyだとファームウェアの書き込みからソースの編集、実行まで簡単に出来るので便利です。

ソースファイルはRaspberry Pi Pico内のフラッシュROMに書き込まれます。ファイル単位なので、複数管理できます。
ファイル名を"main.py"とすると、電源投入時に実行されます。

Pythonシェルも使用できるので、リアルタイムにピンや接続したモジュールの値も確認出来て便利です。
例としてGP16にタクトスイッチを接続したとして、

sw1 = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_DOWN)
sw1.value()

で押下状態を確認できます。

参考にThonnyでMicroPythonを書き込むまでの手順です

Thonnyを起動してから、Raspberry Pi PicoのBOOTSELボタンを押しながらUSBを接続してください。
メニューの[ツール]-[Options...]を選択して開いたダイアログで[インタプリタ]タブを選択してください。
ここで"MicroPython (Raspberry Pi Pico)"を選択すると、MicroPythonのインストールダイアログが開いてインストールできます。

Raspberry Pi Pico

Raspberry Pi Pico

  • メディア: エレクトロニクス

FPGAで遊ぶ 基本編

今回は比較的入手しやすいDE0-CV 開発キットを使用して解説します。
これは INTEL (ALTERA) のFPGAのCyclone Vを搭載した入門用FPGA開発キットで、ボタンやVGA出力等の豊富なI/Oが初めから搭載されています。

ハードウェア記述言語はVerilog HDLを使用します。
今回は機種依存の書き方はしないので、基本的にXILINXや他のFPGAでもそのまま使用できます。
INTEL (ALTERA) のFPGAは開発環境としてQuartusを使用します。ここではQuartusの使用方法やピンの配置方法は説明をしません。

単純な回路の例

まずはVerilog HDLのソース

module sample01(LED, KEY);

    input [3:0] KEY;
    output [3:0] LED;
	 
    assign LED[3] = KEY[3];
    assign LED[2] = KEY[2];
    assign LED[1] = KEY[1];
    assign LED[0] = KEY[0];

endmodule

このソースの意味はKEYを入力に設定、LEDを出力に設定、KEYとLEDをそれぞれ接続しています。

ソフトウェアのプログラム言語に慣れていると「LED[3] = KEY[3]」を実行した後に「LED[2] = KEY[2]」が実行されてるように思いがちですが、このソースの場合はLEDとKEYをそれぞれ論理的に配線をして、リアルタイムに電気が流れます。

DE0-CVの場合のピン配置を下の様に設定してください。

Node Name Location
KEY[3] PIN_M6
KEY[2] PIN_M7
KEY[1] PIN_W9
KEY[0] PIN_U7
LED[3] PIN_Y3
LED[2] PIN_W2
LED[1] PIN_AA1
LED[0] PIN_AA2

これをDE0-CVで実行した場合は4個のLEDが点灯されていて、タクトスイッチを押すと対応するLEDが消えると思います。
タクトスイッチを押してLEDが消えるのは、タクトスイッチがプルアップされているからです。普段は電気が流れていて、ボタンを押すと電気がGNDに流れるのでOFFになります。

ソフトウェアで処理する場合はクロック等を上から順番にトリガーにしてタクトスイッチの状態を順番にLEDに渡すようなイメージですが、ハードウェアで処理する場合は単なる配線なので常に同時に電気が流れてリアルタイムで同時に処理ができます。例えばGPU等の様にソフトウェアで処理できることもあえて専用のハードを使う意味が分かりますね。

Wio Terminalで軽く遊んでみました Wi-fi編

発売されて人気のあるWio Terminalで遊んでみました。
M5Stackがあれば良いと思ってたのですが、結構話題になっているようでつい買ってしまいました。

自分用のメモも兼ねて、Wi-fiに接続するサンプルを書きます。

Wi-fiのコントローラはESP32と違いSoCとは別にRealtek RTL8720が使用されています。
まずはRTL8720のファームウェアのアップデートとArduinoのライブラリの追加をします。

手順は公式サイトを参照してください
Wio Terminal Network Overview
https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/

Wi-fiに接続するサンプル
#include "AtWiFi.h"
#include "TFT_eSPI.h"

const char* ssid = "(WI-fiアクセスポイントのSSID)";
const char* password =  "(WI-fiアクセスポイントのパスワード)";

TFT_eSPI tft = TFT_eSPI();

void setup() {

  WiFi.mode(WIFI_STA);  // ステーション(子機)モードに設定

  tft.begin();
  tft.setRotation(1);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.fillScreen(TFT_BLACK);
  tft.setTextSize(2);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    tft.setCursor(10, 10);
    tft.printf("Connecting to WiFi...");
  }

  tft.printf(" OK");
  tft.setCursor(10, 30);
  tft.println(WiFi.localIP());

  WiFi.disconnect();
}

void loop() {

}

実行結果
f:id:uosoft:20200526144753j:plain

M5Stackで軽く遊んでみました 時計編

今回はM5Stackで遊んでみました。
これも前にM5StickCと一緒に買って積みハードになっていました。

サンプルスケッチを簡単にまとめただけですが、自分用のメモも兼ねてシンプルなソースを書きました。

Wi-fi経由でNTPサーバから時間を取得して日時を表示するまでのサンプルです。


#include <time.h>
#include <M5Stack.h>
#include <WiFi.h>

const char* ssid       = "(Wi-fiアクセスポイントのSSID)";  
const char* password   = "(Wi-fiアクセスポイントのパスワード)";

// NTPサーバのURL
const char* ntpServer =  "ntp.jst.mfeed.ad.jp";
//  GMT+9(日本時間)
const long  gmtOffset_sec = 9 * 3600;
// サマータイム時差(無し)
const int   daylightOffset_sec = 0;

void setup() {
  M5.begin();
  
  M5.Lcd.clear(TFT_BLACK);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
  M5.Lcd.setTextSize(4);

  WiFi.begin(ssid, password);

  // 500ms*120回なので、1分でタイムアウト
  for (int i = 0; i < 120 && WiFi.status() != WL_CONNECTED; i++) {
    delay(500);
  }
  if (WiFi.status() != WL_CONNECTED) {
    // Wifi接続エラー
  }

  if (WiFi.status() == WL_CONNECTED) {
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
    struct tm t;
    if (!getLocalTime(&t)) {
      // NTPサーバ接続エラー
    }
  }
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);

}

void loop() {
  struct tm t;
  if (getLocalTime(&t)) {
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.printf("%04d/%02d/%02d", (1900 + t.tm_year), (t.tm_mon + 1), t.tm_mday);
    M5.Lcd.setCursor(0, 40);
    M5.Lcd.printf("%02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
  }
  
  delay(100);

}

M5StickCで軽く遊んでみました2 UIFlow編

前回紹介したM5StickCですが、今回はUIFlowで遊んでみました。

UIFlowはWEB版とデスクトップ版があるのですが、今回は手軽そうなWEB版を使いました。
WEB版を使用するには、ネットにつながったWifi環境が必要です

準備

ダウンロードページ

Download – m5stack-store
https://m5stack.com/pages/download

ここから M5Burner をダウンロードします。
デスクトップ版(UIFlow-Desktop-IDE)もここでダウンロードします。

M5Bunner

ダウンロードした M5Bunner でファームウェアM5StickCに書き込みます。
2020年5月14日の時点でM5StickCに対応しているファームウェアはUIFlow-v1.4.5.1です。

UIFlow-v1.4.5.1でを押してファームウェアをダウンロードした後で各設定をして[Burn]ボタンを押すとファームウェアM5StickCへ書き込まれます。

COM: M5StickCが接続されたCOMポートを選択
Baudrate: Series設定時に変更されたデフォルトの値のままでOK
Series: StickCを選択
SSID: WifiアクセスポイントのSSID
Password: Wifiアクセスポイントのパスワード

ファームウェアが書き込まれると、M5StickCに下の画像のような画面が表示されます。
f:id:uosoft:20200302165016j:plain
丸いマークが緑ならネット接続に成功しています。それ以外の場合はSSID等のネットの設定を見直してください。
で隠してある部分にAPIキーが表示されます。

UIFlow

ブラウザでUIFlowのページを開きます。

設定

起動時に下のような画面が表示されるので、APIキー等の設定をします。

Api key M5StickCに表示されたAPIキー
Language 日本語も選択できます
Device Stick-c

遊んでみる

前回 と同じように簡単なカウンターを作ってみました。

ソース?
f:id:uosoft:20200514111814p:plain
表示の部分は本来テキストを表示するブロックがあるのですが、数値の0埋め表示が無かった(わからなかった)ので、コード実行ブロックを使用して直接Pythonのコードを書きました。
内部的にはMicroPythonで動かしているようで、Pyhonに置き換えられたコードも見ることができます。
f:id:uosoft:20200514112836p:plain

プログラムできる人はArduinoIDEで普通にコードを書くのが圧倒的にやりやすいと思いますが。
ちょっと遊んだりプログラムの勉強をするのには面白いと思います。

M5StickCで軽く遊んでみました

結構前に買って放置していたM5StickCを見つけたので軽く遊んでみました。

開発環境

開発環境はいくつかあるのですが、とりあえず使い慣れたArduino IDEで行います。
セットアップ方法は公式ページに書いてあります。
M5Stack Docs-The reference docs for M5Stack products.
https://docs.m5stack.com/#/en/arduino/arduino_development
解説は英語で書かれてますが、設定個所は同じなのでわかると思います。

サンプルプログラム

簡単なカウンターを作ってみました。

M5ボタン(ホームボタン)を押すとカウントアップして、リセットボタンを押すとカウントが0になります。

// M5StickCのライブラリをインクルード
#include <M5StickC.h>

// カウントを0で初期設定
int count = 0;

void setup() {

  // M5StickC初期化
  M5.begin();
  
  // 背景色を黒で塗りつぶし
  M5.Lcd.fillScreen(TFT_BLACK);
  // 文字色を白、背景色を黒に設定
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

  // M5StickCの向きを設定(M5ボタンが左)
  M5.Lcd.setRotation(1);
  // 文字サイズを設定
  M5.Lcd.setTextSize(6);

  // カウント表示
  print_count();
}

void loop() {

  // M5ボタンが押された時の処理
  if (digitalRead(M5_BUTTON_HOME) == LOW) {
    // ボタンを離すまで待つ
    while (digitalRead(M5_BUTTON_HOME) == LOW) ;
    // カウントアップ
    count++;
    // 9999以上は9999にする
    if (count > 9999) {
      count = 9999;
    }
    // カウント表示
    print_count();
  }

  // リセットが押された時の処理
  if (digitalRead(M5_BUTTON_RST) == LOW) {
    // ボタンを離すまで待つ
    while (digitalRead(M5_BUTTON_RST) == LOW) ;
    // カウントを0に
    count = 0;
    // カウント表示
    print_count();
  }

}

void print_count() {
  // カーソル位置をセット
  M5.Lcd.setCursor(10, 20);
  // カウントを4桁0埋めで表示
  M5.Lcd.printf("%04d", count);
}

Hallo world を少し発展させたようなプログラムですが、基本の文字の表示とボタンの状態取得はわかると思います。

低価格で便利なマルチテスタ

コンデンサの容量や抵抗の値が簡単に見えるのがないかと思い探していたところ、便利なものを見つけました。

aliexpressで2千円ほどで購入しましたが、Amazonでも結構安く購入できそうです
外見は微妙に違うものもありますが、中身は同じだと思います。

コンデンサをセットしてStartボタンを押すだけで計測できます。


同じように抵抗値も計測できます。

さらにIRセンサで波形まで調べることができます。

他にも色々とできるようですが、説明書がないので徐々に調べていきます。