2026年2月28日土曜日

CH32V003マイコン6 脳トレゲーム 基板設計

  「CH32V003マイコン2 制御学習のための制御ボード設計」で回路図を示しました。

 この回路でも動作するのですが、I2Cに関連する配線がUIAPdunioボード内で3.3Vにプルアップされています(右の回路図)。これは、UIAPudinoマイコンにI2Cを接続したとき、回路を簡単にするためです。

 このI2Cの端子は以前に示した回路では、7セグメントLEDに接続されており、マイコンの制御プログラムが動作していないブートモードの時には、プルアップ抵抗が働き、LEDが点灯してしまいます。余計な表示をさせないために、脳トレゲームの基板では回路を変更しました。

 この回路でPCB設計を行い、基板発注をしました。
 UIAP様から提供されているシンボルフットプリントをKiCAD9用を使ったため、見るためにはKiCAD9が必要です。
 リンクからKiCAD9脳トレゲームデータを見てください。

 基板が出来上がってきたら、試作基板用の脳トレゲームプログラムのポート変更をして、動作確認予定です。出来上がりましたら、ブログにて公開予定です。

脳トレゲーム基板のメリット

 マイコン学習をするときに、何らかの制御ボードを使います。その学習が終わると、制御ボードは役目が終了します。廃棄するにはもったいないので、プログラムを脳トレゲームに入れ替えると、ゲーム機に変わり、遊ぶ用途で利用できます。


2026年2月26日木曜日

CH32V003マイコン5 スリープ機能(低電力)

  脳トレゲーム用基板として設計をしましたので、最終的には電池駆動のゲーム機を想定しています。この時にゲームをしていないときには、少しでも電力を抑えたいものです。この時にマイコンでは「スリープ」モードが利用されます。

 CH32V003でもスリープモードがあります。スリープモードには、「スタンバイモード(DEEP SLEEP)」と「スリープモード」があり、モードになると、約10μA程度の電流になるようです。今回は「スタンバイモード」にします。


スタンバイモードの動作とプログラム

 スタンバイモードを使うときに、必要なのは、復帰するために何らかの「割り込み」が必要です。タイマや外部割り込みなどいろいろあるのですが、今回はスイッチを押したときにスリープから復帰するようにします。まずは、動画を見てください。
 7セグメントLEDの「g」のLED(中央)が点滅しています。一番左のスイッチを押すと、スリープモードになります。この時に、確認するため、LED「d」(下側)を点灯させてからスリープしています。一番右のスイッチ(緑)を押すと復帰します。
 プログラムは次です。
//割り込み処理
void ISR() {
  NVIC->SCTLR &= ~(1 << 2 | 1 << 3);  // deepsleep off 
  NVIC->SCTLR &= ~(1 << 1); //SLEEPONEXIT enters the main program
  digitalWrite(PD2, 0);
}

void setup() {
  // RESET button シームレススイッチ
  if (FLASH->STATR & (1 << 14)) NVIC_SystemReset();
  SystemReset_StartMode(Start_Mode_BOOT);
  pinMode(PD4, OUTPUT);

  pinMode(PD2, OUTPUT);   // seg_d
  pinMode(PC0, OUTPUT);   // seg_g
  pinMode(PC7, INPUT_PULLUP);   // sw1
  pinMode(PC1, INPUT_PULLUP);   // sw6
  // sw6 PC1(3)による割り込み
  attachInterrupt(digitalPinToInterrupt(PC1), GPIO_Mode_IPU, ISR, EXTI_Mode_Interrupt, EXTI_Trigger_Falling);
}

void loop() {
  digitalWrite(PC0, 1); delay(50);
  digitalWrite(PC0, 0); delay(50);
  if(digitalRead(PC7)==0){
    digitalWrite(PD2, 1);
    // sleep mode
    NVIC->SCTLR |= (1 << 2 | 1 << 3);  //SLEEPDEEP   deepsleep
    NVIC->SCTLR |= (1 << 1); //SLEEPONEXIT  low-power mode
    PWR->CTLR &= PWR_CTLR_PDDS;
    __WFE();    // sleep mode
  }
}
 
 19行目で「PC1」を外部割り込みのスイッチをして割り当てをしています。この割り込み設定で、2行目からの「ISR」関数が呼び出される設定です。
 25行目でスイッチ「PC7」を押すと、設定後にスタンバイモードに入ります。
 あとはスイッチ(PC1)が押されると外部割込みがかかり、ISR関数が実行されます。

 はじめは、先人たちのサイトを眺めてプログラムを行ったのですが、割り込みがかかって、ISR関数が実行されても、スタンバイから復帰しませんでした。
 スタンバイモードに関連する部分のドキュメント(右図)を見ていると、「SLEEPONEXIT」ビットを「1」にすると、スタンバイとなり、「0」にすると、通常の状態になるということが分かりました。
 割り込み処理でこのビットを「0」にする処理を加えました。プログラムの3行目です。この行を加えると、割り込み後に、通常のプログラムが実行されるようになりました。
 他の端子で、スタンバイモードから復帰するには、19行目の「PC1」の割り当てを変えることで変更できます。

スタンバイモードからの復帰後の処理(追記)

 スタンバイモードから復帰したときに、LEDの点滅が遅くなっていることに気づきました。内部状態をシリアルモニタで出力して確認すると、CPUクロックのPLL設定が変わっていました。PLLが無効になっているので、クロックが1/2となり、delay関数などの動作が2倍かかります。
//割り込み処理
void ISR() {
  NVIC->SCTLR &= ~(1 << 2 | 1 << 3);  // deepsleep off
  NVIC->SCTLR &= ~(1 << 1); //SLEEPONEXIT enters the main program
  SystemInit();
  digitalWrite(PD2, 0);
}
 これを解消するために、CPUクロックを設定している関数「SystemInit」を入れました(5行目)。CPUクロック変化すると、delay関数の他、シリアルモニタも文字化けしてしまいます。注意が必要です。

2026年2月24日火曜日

CH32V003マイコン4 シリアル通信機能(デバック機能)

  マイコンのプログラミングを行い、デバッグするときに内部の変数などの状態が知りたくなります。

 設計した回路図(右図)を見ると、シリアル通信用の端子「TX(送信)」を外部に接続できるようにしています。

 この端子をUSB-シリアル変換用のケーブルやボードに接続すると、PC側で受信して表示できます。

 例えば、秋月電子通商様の「USBシリアル変換モジュール」などがあります。

パソコンとの接続

 シリアルポートをパソコンに接続するときには、右図のようにマイコンESP①の「TX」をマイコンESP②の「RX」に接続します。(同じ記号の端子同士ではありません)
 この他に、信号グランドもお互いに接続します。
 この接続を「クロス接続」と言います。
 上側がシリアル変換モジュールです。わかりにくいのですが、UIAPduinoボードのUSBコネクタの下につながっています。
 UIAPduinoボードの「TX」と「GND」の2本をジャンバーで接続しています。




 プログラム例を示します。
#define SW1 9
#define SW2 7

void setup() {
  // RESET button シームレススイッチ
  if (FLASH->STATR & (1 << 14)) NVIC_SystemReset();
  SystemReset_StartMode(Start_Mode_BOOT);
  pinMode(PD4, OUTPUT);

  Serial.begin(9600);
  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  Serial.println("start.");
}
int count=0;
void loop() {
  if( digitalRead(SW1)==0){
    Serial.print("SW1 on: ");
    count++;
    Serial.println(count);
  }
  if( digitalRead(SW2)==0){
    Serial.print("SW2 on: ");
    count++;
    Serial.println(count);
  }
}
 スイッチSW1、SW2を押すと、パソコン側のシリアルモニタにメッセージが送信されます。

 変数countをカウントしているため、表示される数値が増えていることが分かります。
 この「Serial.print」関数を使うと、内部の変数の値などを表示して、デバッグすることができます。







CH32V003マイコン3 制御学習のためのプログラミング

制御対象の動作確認(LED)

 基板が完成したので、それぞれの制御対象が動作するかを確認します。プログラムはスケッチの例の「Blink」を基にしています。ポート番号の定義を変えて動作を確認します。

 setup内の4行目から7行目に記述しているところがリセットボタンを「シームレス動作」させるための追加プログラムです。

#define LED   8

void setup() {
  // RESET button シームレススイッチ
  if (FLASH->STATR & (1 << 14)) NVIC_SystemReset();
  SystemReset_StartMode(Start_Mode_BOOT);
  pinMode(PD4, OUTPUT);
  //ポート初期化
  pinMode(LED, OUTPUT);
}

void loop() {
  digitalWrite(LED, 1); 
  delay(100);
  digitalWrite(LED, 0);
  delay(100);
}
 プログラムの書き込みが完了したら、リセットボタンで、実行が始まります。
(もう一度リセットボタンを押すとブートモードになり、書き込み可能となります)

トラブル1 ポート番号「11」が動かない

 UIAPduinoのポート番号「11」は、マイコンの「PD1」に接続されています。
この端子は、CH32Vマイコンへのプログラム書き込み装置「WCH-LinkEエミュレータ」を利用して書き込むときの接続端子「SWIO」となっています。この機能が働いているために、GPIOとして利用できません。少し検索すると、CH32VマイコンのマニュアルにGPIOにするレジスタ設定がありました。
 リセットボタンのシームレス化と同様に、レジスタの設定で、GPIOとして利用する設定は必要です。
void setup() {
  // RESET button シームレススイッチ
  if (FLASH->STATR & (1 << 14)) NVIC_SystemReset();
  SystemReset_StartMode(Start_Mode_BOOT);
  pinMode(PD4, OUTPUT);

  // PD1をGPIOとして利用する設定
  // function SWIO off
  // Enable GPIOs
  RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_AFIOEN;
  // Convert PD1 from SWIO to GPIO
  AFIO->PCFR1 &= ~(AFIO_PCFR1_SWJ_CFG);
  AFIO->PCFR1 |= AFIO_PCFR1_SWJ_CFG_DISABLE;

}
 7行目から13行目の「PD1をGPIOとして利用する設定」を追加すると、ポート11として利用できるようになりました。

UIAPサポート

 同じ症状で困っていた方がUIAPからサポートを受けていた記事を見ました。
もっと簡単にポート11をGPIOにする関数「pinV32_DisconnectDebug」があるようです。
void setup() {
  // RESET button シームレススイッチ
  if (FLASH->STATR & (1 << 14)) NVIC_SystemReset();
  SystemReset_StartMode(Start_Mode_BOOT);
  pinMode(PD4, OUTPUT);

  // PD1をGPIOとして利用する設定
  pinV32_DisconnectDebug(PD_1); // Disable SWIO (the argument is not "PD1")

}
 この関数を利用しても動作させることができました。


制御対象の動作確認(スイッチ・ブザー)

 スイッチとブザーの動作確認プログラムです。
#define LED   8
#define SW    12
#define BUZ   5

void setup() {
  // RESET button シームレススイッチ
  if (FLASH->STATR & (1 << 14)) NVIC_SystemReset();
  SystemReset_StartMode(Start_Mode_BOOT);
  pinMode(PD4, OUTPUT);
  //ポート初期化
  pinMode(LED, OUTPUT);
  pinMode(BUZ, OUTPUT);
  pinMode(SW, INPUT_PULLUP);
}

void loop() {
  if(digitalRead(SW)==0){
    tone(BUZ,880,100);
    digitalWrite(LED, 1); delay(100);
    digitalWrite(LED, 0); delay(100);
  }
}
 3行目のスイッチのポート番号を変えて、動作を確認します。
 これで、制御対象となるI/Oの動作が確認できました。

 同時に、7セグメントLEDに出力すると、右図のように数字を表示できるようになります。

2026年2月23日月曜日

CH32V003マイコン2 制御学習のための制御ボード設計

設計コンセプト

 制御学習用のボードを設計するにあたり、次の点を考慮しています。
 ・基本となるLED、スイッチ制御を組み入れる。
 ・「光る」、「音が鳴る」、「動く」の動作を入れる。
 ・制御学習が終わったら、ボードが無駄にならないようにする。

 2項目の「動く」はモータなどがありますが、今回は入れていません。
 3項目の「ボードが無駄にならないようにする」では、別プログラムを入れると、このボードを「脳トレゲーム」としてアゾぶことができるようにしています。

 制御ボード設計

 UIAPduinoで基本の制御学習を行うための制御ボードの設計を行います。

 組み込む制御対象は、よく使われるLED(7セグメントLED)、スイッチ、ブザーです。また、内部状態をモニタするための通信機能を付けました。
 右図が回路図です。スイッチは、ゲーム用の他に、「シームレス」用のリセットスイッチも追加してあります。
 制御ピン数が足りないため、シリアル通信用の「RX(受信)」を制御用端子に割当を行っています。これは、内部モニタをするときに、「TX(送信)」は必要ですが、「RX(受信)」は外部から受け取ることはあまりないと判断して、割り当てました。

 このボードで学習後、ゲームプログラムを書き込むと、ゲームマシンとして動作できるように設計しています。
 右図は、以前に工作教室向けにPICマイコン(16F1827)で設計した脳トレゲームです。「フラッシュ暗算」と「記憶ゲーム(サイモン)」ができるゲームボードです。

制御ボード基板の組立

 基板設計を行い、基板加工機で試作をしました。部品を付けて基板の組み立てを行いました。
 UIAPduinoボードの右下にあるのがリセットボタンです。
 



CH32V003マイコン1 Arduino環境開発

 CH32V003マイコンの入手

 だんだんと半導体の高騰する中で、何か安価で使えるマイコンは無いかと探していたところ、1月中旬頃、某中華サイトでCH32V003マイコンが1個100円程度で販売されていることを見て、注文しました。2月19日に届き、Arduino環境構築と簡単なLEDスイッチ制御をし始めました。マイコンは安価なため、USBによる書き込み機能は無く、USB-Cコネクタは付いていますが、電源供給用でした。
 その後、2月21日(土)・22日(日)に行われた「NT加賀2026」でUIAP様の展示で「UIAPduino」というCH32V003チップを使ったもので、ソフトウェアでUSB書き込みを実現されているものでした。

 左側が某中華サイトのマイコン、右がUIAP様の「UIAPduino」です。

Arduino開発環境の構築

 UIAP社のサイトを見ながら、UIAPduinoボードの環境構築を行いました。その後、ブレッドボードに制御対象として、LED、スイッチ、ブザー回路を組み、制御を始めました。

 まず、はじめにやりにくいと感じたのは、このボードを書き込むためのブートモードにするためには、「リセットボタンを押しながら、USBケーブルをつなぎ、その後、リセットボタンを離す」とあります。
 制御系のプログラミングを行うときに、書き込むたびに、「USBケーブルをつなぎ直す必要があるのか?」ということです。
 しかし、この解決は、HPサイトの「シームレススイッチ 」という説明です。プログラムのsetupに4行のプログラムを追加しておくと、リセットボタンが「ブートモード」と「実行モード」の切り替えを行ってくれる機能です。これを追加すると、USBケーブルのつなぎ直しをせずに、プログラム変更ができるようになります。
 これで、制御プログラム開発ができるようになりそうです。


2026年2月9日月曜日

micro:bit 始める(5) ArduinoIDEでプログラミング4

 外部端子を使う

 micro:bitの外部端子がArduinoIDE環境で利用できるかを確認しました。

 右図は、いろいろなマイコン系で表示されるポートの利用を示す図です。
 外部I/Oには、P0~P16、P19、P20の合計19本が利用できます。Arduinoからのポート番号は、Pxxの番号と一致しています。
 例) P9端子は、Arduinoのポート9番

 ここまでArduino環境下で、内部LEDマトリックス、ボタン、加速度・磁気センサ、タッチセンサ、外部I/Oの動作確認をしました。
 注意が必要なのは、LEDマトリックスを表示させているときには、P3、P4、P6、P7、P10が利用できません。また、内部のボタンA、Bを使っているときにも、P5、P11は注意が必要です。

ライブラリ「MicrobitV2-HHS」

 標準の関数で「tone」命令が無いので音は出せないと思っていましたが、ライブラリを見つけました。「MicrobitV2-HHS」というライブラリです。早速、ライブラリを追加(ライブラリの管理から追加)してサンプルプログラムを実行しました。スーパーマリオブラザーズのメロディもありました。
 そこから、音を出力する「tone」命令に関わる部分のみを示します。
#include "Tone.h"
// On Microbit V2 the speaker is on pin 27
#define SPEAKER 27

void setup() {
  pinMode(SPEAKER, OUTPUT);
}

void loop() {
  tone(SPEAKER, 880, 100 );
  delay(100);
  noTone(SPEAKER);
  delay(100);
}
 このプログラムで880Hzの音が鳴り続けます。命令の使い方は、Arduinoのtone命令と同じです。ArduinoIDEのメリットであるライブラリが豊富ということはありがたいものです。

 前回、加速度センサでI2Cの接続先の変更について記載しましたが、このライブラリに加速度センサを使うサンプルがあり、動作できました。
 このライブラリのサンプルを見ると、サーボモータのサンプルがありました。これでサーボモータも動くのかもしれません。


ここまでの動作確認結果

 動作しないのは、ロゴマークのタッチセンサです。
 ここまでで、未確認は、マイク、BLEです。

micro:bit 始める(4) ArduinoIDEでプログラミング3

 加速度センサを使う

 micro:bit V2には、STマイクロエレクトロニクス社の「LSM303」という3軸加速度センサ、3軸地磁気センサのセンサが載っています。LSM303用のArduinoライブラリを追加し、サンプル「X_NUCLEO_IKS01A2_LSM303AGR_DataLog_Terminal」を実行させてみます。

 実行させ、シリアルモニタを見ると、何か数値が表示されています。しかし、micro:bitを動かしても、値は変化しません。

 I2Cの場合に、必ずデバイスのアドレスが設定されています。回路図を見ると、加速度センサが「0x19」、磁気センサが「0x1E」となっています。

 このI2Cデバイスが認識されているのかをチェックするときに、「i2c_checker」というプログラムが使われます。検索してプログラムを書き込むと、シリアルモニタに結果が表示されます。

 結果を見るとデバイスがありません。この状態では、いくらプログラムがあっていても、デバイスとの通信ができないため動作しません。

I2Cの接続されている端子が原因

 回路図を見ると「I2C_INT_SCL」、「I2C_INT_SDA」と、「I2C_EXT_SCL」、「I2C_EXT_SDA」という2系統のI2Cがあることが分かりました。前者はmicro:bitに組み込まれているデバイス用、後者は外部端子に接続され、拡張用のI2Cです。
 複数ある場合には、標準で使えるI2Cと、SCL、SDA端子の設定をしてから使用するI2Cの違いがあります。この端子の設定は、「Wire.begin(SDA,SCL);」のように、初期化の時に変更できるのですが、この命令ではエラーとなりました。
 そこで、Arduinoのフォルダをみて、I2C関連を探しました。すると、次のファイルを見つけました。
 「hardware\nRF5\0.8.0\libraries\Wire\Wire_nRF52.cpp」
このファイルとみると、
TwoWire::TwoWire(NRF_TWIM_Type * p_twim, NRF_TWIS_Type * p_twis, IRQn_Type IRQn, uint8_t pinSDA, uint8_t pinSCL)
 これは、I2C(TwoWire)インターフェースを初期化するためのコンストラクタです。この命令を見ると、次のようになっており、「pinSDA」、「pinSCL」の引数を内部の変数に設定しています。
TwoWire::TwoWire(NRF_TWIM_Type * p_twim, NRF_TWIS_Type * p_twis, IRQn_Type IRQn, uint8_t pinSDA, uint8_t pinSCL)
{
  this->_p_twim = p_twim;
  this->_p_twis = p_twis;
  this->_IRQn = IRQn;
  this->_uc_pinSDA = pinSDA;
  this->_uc_pinSCL = pinSCL;
  transmissionBegun = false;
}
 この命令で設定出来たら、I2Cの接続先を変更できるのです。しかし、このコンストラクタの他の設定が分かりません。
 検索をしているときに、GoogleAIが答えを示してくれました。
TwoWire WireM(NRF_TWIM0, NULL, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, SDA, SCL);
 これを組み込み、まずはI2Cスキャナを動作させます。変更点はコンストラクタで作成されるインスタンス名が「WireM」となっているので、プログラムの「Wire」を「WireM」に変更します。

 動作させると、I2Cアドレスが表示されました。つまり、I2Cデバイスとして認識できているということです。
 また、設定の通り、加速度センサが「0x19」、磁気センサが「0x1E」として接続されています。
 結果を見ると、「0x70」、「0x72」のデバイスも接続されているようです。調べると、インターフェースMCU「MKL27Z256」が該当します。USBやDACなどコントローラのようです。

加速度センサが動く

 このコンストラクタの変更を、サンプルプログラムに追加、変更します。この時コンストラクタの定義の前に「#include<Wire.h>」が必要です。
変更して書き込みます。

 結果は、右図のシリアルモニタです。
 micro:bitを動かすと、値も変化しました。

 これで、加速度センサ、地磁気センサ、温度センサが使えるようになりました。


micro:bit 始める(3) ArduinoIDEでプログラミング2

 ボタン動作

 今回はmicro:bitの2個のスイッチを動作させるようにします。ボタンAはポート5、ボタンBはポート11に割り当てられています。
 ボタンを押したときに、LEDを表示させるようにするプログラムは、次のようになります。
#define BTN_A   5
#define BTN_B  11
#define COL1    4
#define COL5   10
#define ROW1   21

void setup() {
  pinMode(BTN_A,INPUT);
  pinMode(BTN_B,INPUT);
  pinMode(COL1, OUTPUT);
  pinMode(COL5, OUTPUT);
  pinMode(ROW1, OUTPUT);
  digitalWrite(COL1, 1);
  digitalWrite(COL5, 1);
  digitalWrite(ROW1, 1);
}

void loop() {
  if(!digitalRead(BTN_A)){
    digitalWrite(COL1, 0);
  }else{
    digitalWrite(COL1, 1);
  }
  if(!digitalRead(BTN_B)){
    digitalWrite(COL5, 0);
  }else{
    digitalWrite(COL5, 1);
  }
}
 ボタンAを押すと左上のLEDが点灯、ボタンBを押すと右上のLEDが点灯します。
 

 タッチセンサ動作

 micro:bitには、タッチセンサとして働く機能があります。micro:bit端子の「0」、「1」、「2」と表示されている端子と、LEDの上にある「ロゴ」が、タッチセンサとして働きます。
 この中の「ロゴ」は、Arduinoのポート設定を見ると、26番に割り当てられていますが、動作しませんでした。
 Arduinoのポート設定は、[hardware\nRF5\0.8.0\variants\BBCmicrobitV2]フォルダにあります。
 [variant.h]のファイルにArduinoで利用できる定義名が書かれています。
 [variant.cpp]ファイルにCPUの端子とArduinoのポート番号を関連付けているファイルです。

 端子「0」、「1」、「2」はそれぞれ、Arduinoのポート「0」、「1」、「2」に割り当てられています。読み取るときに、アナログ入力「analogRead」で処理します。


#define TOUCH0   0

void setup() {
  Serial.begin(9600);
  pinMode(TOUCH0,INPUT);
}

void loop() {
  Serial.println(analogRead(TOUCH0),DEC);
}
 実行させ、「シリアルプロッタ」で表示すると、グラフにしてくれます。
 タッチしていないと約1000の値で、タッチすると小さく変化します。

 3つのポートとも同じ動作をします。


micro:bit 始める(2) ArduinoIDEでプログラミング1

  micro:bitを操作していく中で、なかなか馴染めないのが「ブロックプログラミング」です。キーボードで入力すれば、すぐなのにマウスで操作していかなければなりません。

 これは、プログラミング初心者がよく起こすスペルミスによる「誤入力」で動作できないことがあるため、初心者向けには扱いやすいものです。

 しかし、細かなことをしたりするうえでは、コードプログラミングがしたくなります。Pythonでもプログラミングができるのですが、慣れないためか、タブの段付けによる構造化プログラミングが馴染めず、うまく動作しない原因の一つと感じています。(これは環境かもしれません。タブとスペースの混在する場合は画面上は同じでも、プログラミング構造が違うなど...)


ArduinoIDEでプログラミングする

 検索すると、すぐにArduinoIDEでのプログラミングができる環境構築について見つかります。そこで、サイトを参考にして導入しました。簡単にコードプログラミングができるようになりました。
 ArduinoIDEでプログラミングするときに、知る必要があるのは、ポート番号です。
 micro:bitには、V1.5、V2.0、V2.2といくつかのバージョンがあります。内部の回路が異なるため、ポートの割り当てが異なります。詳しく知るためには、回路図があれば解析できます。回路図はmicro:bit教育財団から取得できます。

LEDマトリックスのプログラミングする

 micro:bitには、25個のLEDが付いていま
す。micro:bit V2.0のLEDは内部回路のようにLEDマトリックスとなっています。ROW側をHigh、COL側をLowにすると、LEDが点灯します。
 例えば、ポート21(ROW1)をHigh、ポート4(COL1)をLowにすると、左上のLEDが点灯します。プログラムは次のようになります。
void setup() {
  pinMode(4, OUTPUT);
  pinMode(21, OUTPUT);
  digitalWrite(4, LOW);
  digitalWrite(21, HIGH);
}

void loop() {
}
 また、LEDマトリックスの動作チェック用にポート番号を配列に設定して、左上から順番に1つずつ表示させるプログラムは、次のようになります。
const uint8_t max_cols = 5;
const uint8_t max_rows = 5;
const uint8_t cols[max_cols] = { 4,  7,  3,  6, 10};
const uint8_t rows[max_rows] = {21, 22, 23, 24, 25};

void led_init() {
  for (int i = 0; i < max_cols; i++) {
    pinMode(cols[i], OUTPUT);
    digitalWrite(cols[i], HIGH);
  }
  for (int i = 0; i < max_rows; i++) {
    pinMode(rows[i], OUTPUT);
    digitalWrite(rows[i], LOW);
  }
}

void led_pset(const uint8_t x, const uint8_t y, const uint8_t mode) {
  digitalWrite( cols[x], !mode );
  digitalWrite( rows[y], mode );
}

void setup() {
  led_init();
}

void loop() {
  for (int y = 0; y < 5; y++) {
    for (int x = 0; x < 5; x++) {
      led_pset(x, y, HIGH);
      delay(200);
      led_pset(x, y, LOW);
    }
  }
}
 1列のみ表示するのは簡単なのですが、パターンを表示させるには、ダイナミック点灯方式が必要です。ただ、Adafruit社がmicro:bit用のArduinoライブラリを提供しているので、こちらを使うと、文字列も簡単に表示できます。

micro:bit 始める(1) AIとは?

  先日、本屋で情報収集をしていると、「micro:bitではじめるAI工作」という本を見つけました。

 マイコン系でAIが使えるということをあまり聞きません。それも、子供向けのIoTである「micro:bit」でできるという衝撃を受け、この書籍とmicro:bit本体+αを購入しました。


micro:bitでAIする(マイク)

 書籍とマイコンが届き、早速、プログラム環境を整えてプログラミングを開始しました。
 micro:bitをさわるのも初めてなので、簡単なLED点灯から始めました。書籍を眺めながら、プログラミングを始め、ブロックプログラミングもScratchを少し触っただけなので、テキストを参考にして操作し、基本の動作させることができました。
 やりたいのはAIです。他の環境に活用できるのかを知りたいのです。

 AIは、Googleの「Teachable Machine」というサイトに接続して、学習させます。このサイトでは、パソコンに接続したカメラやマイクの情報を学習させます。「画像」、「音声」、「ポーズ」を学習させることができ、結果をシリアルデータの文字列で返してくれます。
 パソコンに接続したマイクから、「うれしい」(uresii)、「さいこう」(saiko)などのキーワードを複数回、学習させると、学習した結果から、該当する文字列を返してくれるものでした。(学習は外部サイトにあるサーバで行われます)
 しかし、言葉を認識できるという点では、確かにAIです。ただし、この場合にはパソコンが必要になるのがネックです。(IoTするときに、外部PCが必要となるため)
 

micro:bitでAIする(加速度センサ)

 書籍を読み飛ばしながら見ていくと、micro:bit内蔵の加速度センサをAI学習させることができるいうことです。

 micro:bitを「左右に振る」、「落とす」などの動作による加速度センサの変化を学習させます。「micro:bit CreateAI」のサイトです。

 「CreateAI」サイトでは、学習させたセンサの状態が表示されます。
 また、実際に動作させて、確認することもできます。


 これで、内部センサ(加速度センサ)の動作で、AI学習により、動作を変えることができます。
 外部機器も不要で、オフラインでも動作できるため、使い方で利用できそうです。

micro:bitでAIする(その他)

 PC接続のマイク、内蔵の加速度センサが外部AIサーバでの学習により、プログラミングして、動作させることができることが分かりました。
 他のセンサ(内蔵マイクなど)やmicro:bitに接続したセンサの動作を学習させ、プログラミングすることができるのであろうか?
 「Teachable Machine」では外部カメラ、マイクがソースになります。「micro:bit CreateAI」では加速度センサのみが対応しています。これ以外の学習はありませんでした。(今後、拡張されていく可能性はあります)

 それでもAIで学習させた結果をもとにして、マイコンで動作させることができることは、他のマイコンにはないものです。


LEDマトリックス表示装置の設計・製作 9(画像表示)

  LEDマトリックスに画像を表示させるには、いろいろな画像形式を知る必要があります。現在、よく使われるJPG形式やPNG形式は圧縮処理されて保存されています。これに対して、BMP形式やTIFF形式は非圧縮形式で、画像データがそのまま保存されています。このため、ファイルは大きくな...