HOME | Raspberry Pi | ビジネス書籍紹介 | 2026-03-16 (Mon) Today's Access : 234 Total : 1311311. Since 10 Sep. 2019

micro:bit & Pico 拡張ボード
2026.01.29 / 2026.03.07更新

今回は多々あるmicro:bit拡張ボードからお薦め商品のご紹介です

●Keyestudio Micro:bit Smart Robot Car


この micro:bit Smart Robot Car は、micro:bit V2 用です。


とても小さくて、全長10cm,車幅8cm です

micro:bitを熟知されている方は、基本は読み飛ばしてください

●micro:bit v2.21
これから購入するのであれば、v2.21がお薦めです。 新型のv2.21では性能がかなり向上していて、なにより旧型のv1系とはピンの仕様が異なります。


マイクロビット (micro:bit) v2のデータシート

Features
○Upgraded processor (nRF52833)
 ○64MHz Arm Cortex-M4 + FPU (over 4 times faster!)
 ○512KB Flash storage on board
 ○128KB RAM
○MEMS Microphone with LED indicator and on-board speaker
○5x5 LED matrix display
○Touch sensitive logo "button"
○Accelerometer/compass (LSM303AGR)
○Light and temperature sensors
○Sleep/off mode for batteries powered projects (w/ LED indicator)
○Up to 200mA of current for external accessories
○Bluetooth 5.0 radio allowing micro:bits to talk to each other
○Notched edge connector (easier to connect things like crocodile clips and conductive thread)
○Dimensions: 52mm x 42mm x 11.7mm

micro:bit v2、Arduino環境でプログラミングに使う端子番号とその機能
Pxx番号端子機能Pxx番号端子機能
0A0, LEFT PAD 21ROW1
1A1, MIDDLE PAD22ROW2
2A2, RIGHT PAD 15ROW3
3A3, COL3 24ROW4
4A4, COL1 19ROW5
5BTN A 26LOGO (touch sensor)
6COL4 27SPEAKER
7COL2 28RUN_MIC
8NFC2, GPIO1 29A6, MIC_IN
9NFC1, GPIO2 30I2C_INT_SDA
10A5, COL5 31I2C_INT_SCL
11BTN B 32COMBINED_SENSOR_INT
12Accessbility 33RX
13SCK 34TX
14MISO
15MOSI
16GPIO3
173.3V
183.3V
19SCL
20SDA
カードエッジにはP0からP20までの信号が引き出されています。 21番から後はボード上のみでの接続です。
シリアルピンは、(RX,TX) = (33,34) なので、USB端子以外からは接続することはできません。
★ADC (P0(A0),P1(A1),P2(A2))
アナログ‐デジタルコンバータ(ADC)付きGPIO(汎用デジタル入出力)、デフォルトで 10 bit (0~1023) の ADC です。 DAC に使えるピンはありません。
★3V:3ボルト電源入出力
電源出力:microbitがUSBまたはバッテリーで動いている場合、3Vピンを電源出力として使用して周辺機器に電源を供給することができます。
電源入力:microbitがUSBまたはバッテリーで電源供給されていない場合、電源入力として3Vの端子を使ってmicorbitに電源を供給することができます。

micro:bit v2.21は、Nordic Semiconductor (ノルディック・セミコンダクター) の nRF52833チップ を搭載し、 磁気・加速度センサも LSM 303AGR と実用的な仕様になっています。 micro:bit は学習用デバイスと思っていたのですが、コスパに優れており、nRF52833を搭載していることから、 Arduino IDE や PlatoformIOなどの開発環境を使って、Arduino言語(C言語)による開発が可能です。

●開発環境
ソースコードのビルドには、Raspberry Pi / PlatformIOを使用しています。
Arduino開発環境構築 PlatformIO

$ pio boards micro:bit
Platform: nordicnrf51
=======================================================
ID          MCU      Frequency Flash RAM  Name
----------- -------- --------- ----- ---- -------------
bbcmicrobit NRF51822 16MHz     256KB 16KB BBC micro:bit

Platform: nordicnrf52
===============================================================
ID             MCU      Frequency Flash RAM    Name
-------------- -------- --------- ----- -----  ----------------
bbcmicrobit_v2 NRF52833 64MHz     512KB 128KB  BBC micro:bit V2
ボード情報、ピン定義をを確認しておきます。
$ cat ~/.platformio/platforms/nordicnrf52/boards/bbcmicrobit_v2.json
$ cat ~/.platformio/packages/framework-arduinonordicnrf5/variants/BBCmicrobitV2/variant.h
$ cat ~/.platformio/packages/framework-arduinonordicnrf5/variants/BBCmicrobitV2/variant.cpp

$ pio init -b bbcmicrobit_v2
Tool Manager: Installing platformio/toolchain-gccarmnoneeabi @ >=1.60301.0,<1.80000.0
UnknownPackageError: Could not find the package with 'platformio/toolchain-gccarmnoneeabi @ >=1.60301.0,<1.80000.0' requirements for your system 'linux_aarch64'

toolchain でエラーとなってしまったので、明示的にバージョンを指定しました

$ vi platformio.ini
[env:bbcmicrobit_v2]
platform = nordicnrf52
board = bbcmicrobit_v2
framework = arduino
platform_packages =
        toolchain-gccarmnoneeabi@~1.90301.0
まずは、ボタン操作をしてみます

●1.Bottun A, B
boolean buttonA = false;
boolean buttonB = false;

void setup()
{  
	Serial.begin(115200);
	Serial.println("microbit is ready!");
	pinMode(PIN_BUTTON_A, INPUT);
	pinMode(PIN_BUTTON_B, INPUT);
}

void loop()
{
	if ((!digitalRead(PIN_BUTTON_A))&&(!buttonA)) {
		Serial.println("Button A pressed");
		buttonA = true;
	} else {
		buttonA = false;
	}
	if ((!digitalRead(PIN_BUTTON_B))&&(!buttonB)) {
		Serial.println("Button B pressed");
		buttonB = true;
	} else {
		buttonB = false;
	}
	delay(100);
}
$ pio device list
/dev/ttyACM0
------------
Hardware ID: USB VID:PID=0D28:0204 SER=XXXXXX LOCATION=1-1:1.1
Description: BBC micro:bit CMSIS-DAP - mbed Serial Port

/dev/ttyAMA0
------------
Hardware ID: 3f201000.serial
Description: ttyAMA0

$ pio device monitor -p /dev/ttyACM0 -b 115200
A Button!
B Button!

●2.LED MATRIX
5x5のLEDマトリクスはv1.x系にもv2にも存在します。 しかし、v1.x系はROW3端子、COLUMN9端子の非対称な構成で12端子を使って制御、v2系はROW5端子、COLUMN5端子の直交的な配置で10端子で制御です。
LED Matrix
const uint8_t cols[5] = {4, 7, 3, 6, 10};
const uint8_t rows[5] = {21, 22, 23, 24, 25};

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

void loop() {
	for (int y = 0; y < 5; y++) {
		for (int x = 0; x < 5; x++) {
			digitalWrite(cols[x], LOW);
			digitalWrite(rows[y], HIGH);
			delay(200);
			digitalWrite(cols[x], HIGH);
			digitalWrite(rows[y], LOW);
		}
	}
}
Adafruit_Microbit ライブラリを使用すると、マトリックスLEDを多彩に制御することができます

adafruit/Adafruit_Microbit

●I2Cスキャニング
micro:bitは2系統のI2Cを実装していて、オンボードのI2Cを走査するにはWire1を、外部I2C接続にはWireを指定します。 Wire1のピン番号は (SDA,SCL) = (30,31) で、エッジコネクタには引き出されていません。
#include <Wire.h>

void setup()
{
  Wire1.begin();
  Wire1.setClock(400000);    // I2C fast mode, 400kHz

  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    Wire1.beginTransmission(address);
    error = Wire1.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);
}
$ pio device monitor -p /dev/ttyACM0 -b 115200
Scanning...
I2C device found at address 0x19 !
I2C device found at address 0x1E !
I2C device found at address 0x70 !
I2C device found at address 0x72 !
done

0x19 と 0x1E がオンボード磁気・加速度センサのI2Cアドレスです。

●磁気・加速度センサ LSM 303AGR

・I2C 7-bit addresses 0x19 & 0x1E
・±50 gauss magnetic dynamic range
・1.5 mGauss magnetic sensitivity
・Accelerometer ranges: ±2/±4/±8/±16 g
・As little as 1mg accelerometer sensitivity


stm32duino/LSM303AGR
gitHubには、LSM303など類似のソースコードがアップされていますが、LSM303AGRを使用しないと正常に動作しません。
srcディレクトリ配下のすべてのソースファイルとexamplesディレクトリのX_NUCLEO_IKS01A2_LSM303AGR_DataLog_Terminal.ino を PlatformIO の srcディレクトリにコピーします。
※inoファイルとLSM303AGR関連コードを別のフォルダ―に配置するとビルド時にエラーになることがあります。

X_NUCLEO_IKS01A2_LSM303AGR_DataLog_Terminal.ino
line:50
#define DEV_I2C Wire
   ↓
#define DEV_I2C Wire1

line:60
pinMode(13, OUTPUT); ← 削除

ビルド、micro:bit に書き込み、デバイスモニターで計測結果を表示します。

$ pio device monitor -p /dev/ttyACM0 -b 115200
| Acc[mg]: 12 -974 43 | Mag[mGauss]: -454 132 240 | Temp[C]: 23.00 |
| Acc[mg]: 12 -974 39 | Mag[mGauss]: -462 127 231 | Temp[C]: 22.75 |
| Acc[mg]: 16 -970 47 | Mag[mGauss]: -462 130 243 | Temp[C]: 23.00 |
| Acc[mg]: 12 -974 35 | Mag[mGauss]: -450 135 241 | Temp[C]: 22.75 |


本題は、ここからです

●KEYESTUDIO micro:bit V2ロボット


Dimension:99x78*58mm
1Slot of Micro:bit board
2Potentiometer
3Photoresistor
4RGB LED
5Ultrasonic port
6LM393 Voltage comparator
7LIne Tracking sensors
8IO ports
9STC8G1K08 download port
10Motor / speed:200RPM
11ETA3413 drop voltage IC
12IR Receiver
13Power switch
14Power indicator
15External power port / DC 4.5V
16I2C extended port
17HR8833 motor
18STC8G1K08 38I-SOP16
Operating voltage of sensors: 3V

Resources

●10.MOTOR

モーターには変速用金属製ギアが取付けられていて、回転数は最大で200RPMになっています

●11.ETA3413 電圧変換
単4乾電池直列電池ボックス4.5Vを3.3Vに降圧します

ETA3413周辺の表面実装抵抗
R23: 473 = 47KΩ
R25: 01C = 10KΩ
R21: 01C = 10KΩ
R22: 222 = 2,2KΩ
R24: 01C = 10KΩ

  ((R22 + R24)/R22)*0.6
 = ((2.2 + 10)/2.2)*0.6
 = 3.327V

これにより直列乾電池3本の外部電源は
4.5Vから3.3Vに降圧されます

●18.STC8G1K08 / 9.Download Port


micro:bitはI2Cを介してSTC8G1K08に制御命令を送信し、ST8G1K08はHR8833モーター駆動ICにPWM信号を送信してモーターの回転を制御します。 RGB LEDにもPWM信号を送信します。
STC8G1K08は、8051コアを搭載した8ビットマイコンです。外部水晶振動子が不要で、1.9V~5.5Vの広い電圧範囲で動作します。


左上の16ピンICがSTC8G1K08、キャパシタを挟んで右にSTC8G1K08へのコード書込み用シリアルポート(TX,RX,GND,3V)が実装されています。 STC8G1K08には既にコードが書き込まれている為、このポートは通常使用しません。 書込み済ファームウェアのコードは公開されていないようです。

●I2Cデバイス・スキャン
STC8G1K08のI2Cアドレスを確認してみます
#include <Wire.h>

void setup()
{
  Wire.begin();
  Wire.setClock(400000);    // I2C fast mode, 400kHz

  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}
$ pio device monitor -p /dev/ttyACM0 -b 115200
Scanning...
I2C device found at address 0x30 !
done

0x30 は STC8G1K08 のI2Cアドレスです。

●STC8G1K08制御用クラスライブラリ作成
Keyestudio から提供されている Micro:bit Smart Robot Car用のソースコードはMakeCodeとPythonです。 ざっとコードを眺めてみると主要部分はライブラリに纏められ、ユーザ側記述コードはとてもシンプルです。 しかし美しくありません、制御の実態が分かりにくいので、Arduino言語(C言語)に書き換えました。

ロボットカー用にKEYESTUDIOから提供されているpythonソース・コードを参考にして STC8G1K08制御用のクラスライブラリを作成しました

STC8G1K08.h
#ifndef __STC8G1K08_H
#define __STC8G1K08_H

#include <Wire.h>

#define STC8G1K08_ADDR  0x30
#define LEFT_MOTOR_INA      0x03
#define LEFT_MOTOR_INB      0x04
#define RIGHT_MOTOR_INA     0x02
#define RIGHT_MOTOR_INB     0x01
#define LEFT_RED_REG        0x08
#define LEFT_GREEN_REG      0x07
#define LEFT_BLUE_REG       0x06
#define RIGHT_RED_REG       0x09
#define RIGHT_GREEN_REG     0x0A
#define RIGHT_BLUE_REG      0x05

class STC8G1K08
{
	private:
		TwoWire  *i2c;
		bool     write(uint8_t addr, uint8_t cmd, uint8_t value);

	public:
		STC8G1K08(TwoWire *wire);
		~STC8G1K08();
		void motor_pwm(int left, int right);
		void led_pwm(long left, long right);
};

#endif /*__STC8G1K08_H*/
STC8G1K08.cpp
#include "STC8G1K08.h"

STC8G1K08::STC8G1K08(TwoWire *wire) {
	i2c = wire;
}

STC8G1K08::~STC8G1K08() {}

bool STC8G1K08::write(uint8_t addr, uint8_t cmd, uint8_t value)
{
	uint8_t error;

	i2c->beginTransmission(addr);
	i2c->write(cmd);
	i2c->write(value);
	error = i2c->endTransmission(1);
	if (error==4) {
		return false;
	} else {
		return true;
	}
}

void STC8G1K08::motor_pwm(int left, int right)
{
	int speed;
	if (left > 0 ) {
		speed = left;
		// left advanced
		write(STC8G1K08_ADDR, LEFT_MOTOR_INA, speed);
		write(STC8G1K08_ADDR, LEFT_MOTOR_INB,     0);
	} else if (left < 0) {
		speed = left * -1;
		// left back
		write(STC8G1K08_ADDR, LEFT_MOTOR_INA,     0);
		write(STC8G1K08_ADDR, LEFT_MOTOR_INB, speed);
	} else {
		// left stop
		write(STC8G1K08_ADDR, LEFT_MOTOR_INA,     0);
		write(STC8G1K08_ADDR, LEFT_MOTOR_INB,     0);
	}

	if (right > 0 ) {
		speed = right;
		// right advanced
		write(STC8G1K08_ADDR, RIGHT_MOTOR_INB,     0);
		write(STC8G1K08_ADDR, RIGHT_MOTOR_INA, speed);
	} else if (right < 0) {
		speed = right * -1;
		// right back
		write(STC8G1K08_ADDR, RIGHT_MOTOR_INB, speed);
		write(STC8G1K08_ADDR, RIGHT_MOTOR_INA,     0);
	} else {
		// right stop
		write(STC8G1K08_ADDR, RIGHT_MOTOR_INB,     0);
		write(STC8G1K08_ADDR, RIGHT_MOTOR_INA,     0);
	}
}

void STC8G1K08::led_pwm(long left, long right)
{
	uint8_t redL, greenL, blueL;
	uint8_t redR, greenR, blueR;

	// LED lights are common anode,
	// 255 is the lowest value and 0 is the brightest value.
	redL   = 255 - ((left  >> 16) & 0xFF);
	greenL = 255 - ((left  >>  8) & 0xFF);
	blueL  = 255 - ((left       ) & 0xFF);
	redR   = 255 - ((right >> 16) & 0xFF);
	greenR = 255 - ((right >>  8) & 0xFF);
	blueR  = 255 - ((right      ) & 0xFF);

	write(STC8G1K08_ADDR, LEFT_RED_REG,    redL  );
	write(STC8G1K08_ADDR, LEFT_GREEN_REG,  greenL);
	write(STC8G1K08_ADDR, LEFT_BLUE_REG,   blueL );
	write(STC8G1K08_ADDR, RIGHT_RED_REG,   redR  );
	write(STC8G1K08_ADDR, RIGHT_GREEN_REG, greenR);
	write(STC8G1K08_ADDR, RIGHT_BLUE_REG,  blueR );
}
●17.HR8833 モータードライバ

STC8G1K08からのPWM制御信号を受けモーターを回転させます
#include "STC8G1K08.h"
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	STC8G1K08 stc8(&Wire);
#elif defined (ARDUINO_ARCH_RP2040)
	STC8G1K08 stc8(&Wire1);
#endif

void setup()
{
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	Wire.begin();
#elif defined (ARDUINO_ARCH_RP2040)
	Wire1.setSDA(2);
	Wire1.setSCL(3);
	Wire1.begin();
#endif

	delay(5000);
	stc8.motor_pwm(   0,  0); // stop
	stc8.motor_pwm(  70, 70); // advanced
	delay(1000);
	stc8.motor_pwm( -70,-70); // back
	delay(1000);
	stc8.motor_pwm(  70,-70); // spin left
	delay(1000);
	stc8.motor_pwm( -70, 70); // spin right
	delay(1000);
	stc8.motor_pwm(  70, 30); // turn left
	delay(1000);
	stc8.motor_pwm(  30, 70); // turn right
	delay(1000);
	stc8.motor_pwm(   0,  0); // stop
}

void loop() {}
●4.LED

RGB LEDはアノード・コモンなのでRGB値の反転補正が必要です。
STC8G1K08からのPWM制御信号により、RGB LEDを光らせます

#include "STC8G1K08.h"
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	STC8G1K08 stc8(&Wire);
#elif defined (ARDUINO_ARCH_RP2040)
	STC8G1K08 stc8(&Wire1);
#endif

void setup()
{
#if defined (ARDUINO_BBC_MICROBIT_V2)
	Wire.begin();
#elif defined (ARDUINO_ARCH_RP2040)
	Wire1.setSDA(2);
	Wire1.setSCL(3);
	Wire1.begin();
#endif

	stc8.led_pwm(0,0); // BLACK
}

void loop()
{
	stc8.led_pwm(0xFF0000,0xFF0000); delay(1000);  // RED
	stc8.led_pwm(0x00FF00,0x00FF00); delay(1000);  // GREEN
	stc8.led_pwm(0x0000FF,0x0000FF); delay(1000);  // BLUE
	stc8.led_pwm(0x00FFFF,0x00FFFF); delay(1000);  // CYAN
	stc8.led_pwm(0xFF00FF,0xFF00FF); delay(1000);  // DARK RED
	stc8.led_pwm(0xFFFF00,0xFFFF00); delay(1000);  // YELLOW
	stc8.led_pwm(0xFFFFFF,0xFFFFFF); delay(1000);  // WHITE
}
●3. Photoresistor


光強度が増加すると抵抗が減少し、アナログポートの電圧が上昇します。 一方、光強度が減少すると抵抗が増加し、アナログポートの電圧が低下します。 この電圧変化を評価してロボットカーを制御します。
下記のコードではロボットカーは光源に向かって走って行きます。
#include "STC8G1K08.h"
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	STC8G1K08 stc8(&Wire);
	#define CDS_LEFT_PIN    1
	#define CDS_RIGHT_PIN   0
#elif defined (ARDUINO_ARCH_RP2040)
	STC8G1K08 stc8(&Wire1);
	#define CDS_LEFT_PIN    27
	#define CDS_RIGHT_PIN   26
#endif

unsigned short avgLeft  = 0;
unsigned short avgRight = 0;

unsigned short CDS_L;
unsigned short CDS_R;

void setup()
{
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	Wire.begin();
#elif defined (ARDUINO_ARCH_RP2040)
	Wire1.setSDA(2);
	Wire1.setSCL(3);
	Wire1.begin();
#endif

	for (int i = 0; i < 20; i++) {
		avgLeft  += analogRead(CDS_LEFT_PIN);
		avgRight += analogRead(CDS_RIGHT_PIN);
	}
	avgLeft  /= 20;
	avgRight /= 20;
}

void loop()
{
	CDS_L = analogRead(CDS_LEFT_PIN);
	CDS_R = analogRead(CDS_RIGHT_PIN);

	if ((CDS_L >= (avgLeft * 1.2)) && (CDS_R < avgRight)) {
		stc8.motor_pwm(70,-70); // spin left
	} else if ((CDS_L < avgLeft) && (CDS_R >= (avgRight * 1.2))) {
		stc8.motor_pwm(-70,70); // spin right
	} else if ((CDS_L > (avgLeft * 1.2)) && (CDS_R > (avgRight * 1.2))) {
		stc8.motor_pwm(70,70); // advanced
	} else {
		stc8.motor_pwm(0,0); // stop
	}
}
●7. Line Tracking Sensor



黒線は赤外線信号を吸収し、白い部分は赤外線信号を反射します。 LM393コンパレータは黒線が検知されるとHIGHを、白い部分ではLOWを出力します。
HIGHが出力されると、LED(D2あるいはD3)は消灯し、LOWが出力されると点灯します。


TCRT5000センサが黒線上にあるときに消灯、白紙部分にあるときに点灯するように可変抵抗を回して調整します。
左側のセンサが黒線上にあるので、左側LEDは消灯、右側センサは白紙上にあるので右側LEDは点灯(緑)しています。
#include "STC8G1K08.h"
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	STC8G1K08 stc8(&Wire);
	#define TCRT5K_LEFT_PIN  13
	#define TCRT5K_RIGHT_PIN 12
#elif defined (ARDUINO_ARCH_RP2040)
	STC8G1K08 stc8(&Wire1);
	#define TCRT5K_LEFT_PIN  20
	#define TCRT5K_RIGHT_PIN 19
#endif

uint8_t sensor_L;
uint8_t sensor_R;

void setup()
{
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	Wire.begin();
#elif defined (ARDUINO_ARCH_RP2040)
	Wire1.setSDA(2);
	Wire1.setSCL(3);
	Wire1.begin();
#endif

	Serial.begin(115200);

	pinMode(TCRT5K_LEFT_PIN,  INPUT_PULLUP);
	pinMode(TCRT5K_RIGHT_PIN, INPUT_PULLUP);
}

void loop()
{
	sensor_L = digitalRead(TCRT5K_LEFT_PIN);
	sensor_R = digitalRead(TCRT5K_RIGHT_PIN);
	Serial.print("sensor_L:");
	Serial.println(sensor_L);
	Serial.print("sensor_R:");
	Serial.println(sensor_R);

	// When both side sensors are on the black line
	if ((sensor_L == 1) && (sensor_R == 1)) {
		stc8.motor_pwm(100,100); // advanced

	// If the right sensor is on the black line and
	// the left sensor is on the white paper, turn right.
	} else if ((sensor_L == 0) && (sensor_R == 1)) {
		stc8.motor_pwm(-100,100); // spin right

	// If the right sensor is on the white paper and
	//  the left sensor is on the black line, turn left.
	} else if ((sensor_L == 1) && (sensor_R == 0)) {
		stc8.motor_pwm(100,-100); // spin left

	// If both side sensors are off the black line
	} else {
		stc8.motor_pwm(   0,  0); // stop
	}
}
LM393
LM393は2つの電圧を比較し、どちらが大きいかを判定してデジタル出力する「電圧コンパレータIC」で、使い方は2つの入力ピン(IN+, IN-)に比較したい電圧を入れ、反転入力(IN-)の電圧が非反転入力(IN+)より高ければ出力がLow(GNDに近い)、IN+が高ければ出力がHigh(VCCに近い)となり、センサーのしきい値検出やアナログ信号のデジタル変換(ADC)に使われます。
電源(VCC/GND)と2つの入力、そして出力(OUT)の基本的な接続で動作し、出力はオープンコレクタのためプルアップ抵抗が必要な場合が多いです。

●5.Ultrasonic Sensor (SRF05)

Specifications:
Working voltage: 3-5.5V(DC)
Working current: 50mA/100mA normally is 65mA
Maximum power 0.5W
Maximum detection distance: about 3m
Blind spotless then 4cm
Sensing angle: no more than 15 degrees




RobTillaart/SRF05
SRF05ライブラリはHC-SR04と互換性があります
下記のコードはロボットカーが前進し、壁から30cmまで接近すると、くるっと左に回り再度前進します。 壁から15㎝まで近づくと後退します。
#include "STC8G1K08.h"
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	STC8G1K08 stc8(&Wire);
	#define TRIG_PIN 14
	#define ECHO_PIN 15
#elif defined (ARDUINO_ARCH_RP2040)
	STC8G1K08 stc8(&Wire1);
	#define TRIG_PIN 21
	#define ECHO_PIN 22
#endif

#include "SRF05.h"
SRF05 SRF(TRIG_PIN, ECHO_PIN);

void setup()
{
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	Wire.begin();
#elif defined (ARDUINO_ARCH_RP2040)
	Wire1.setSDA(2);
	Wire1.setSCL(3);
	Wire1.begin();
#endif

	Serial.begin(115200);
	SRF.setCorrectionFactor(1.035);
	SRF.setModeAverage(10);
}

int  cm;

void loop()
{
	cm = SRF.getMillimeter() / 10;
  Serial.print(cm);
  Serial.print("cm : ");

	if (cm <= 15) {
		Serial.println("Fall Back");
		stc8.motor_pwm( -70,-70); // back
	} else if ( (cm > 15) && (cm <= 30) ) {
		Serial.println("Spin Left");
		stc8.motor_pwm(  70,-70); // spin left
	} else if ( (cm > 30) && (cm <= 80) ) {
		Serial.println("Go Advanced");
		stc8.motor_pwm(100,100); // advanced
	} else {
		Serial.println("Stop");
		stc8.motor_pwm(0,0); // stop
	}
  delay(100);
}
このコードでは壁に衝突してしまうこともあるので、ロボットカーの速度を調整、 あるいは接近距離による判断基準を変更する必要があります。

●12.IR Remote Control



Arduino-IRremote/Arduino-IRremote
srcディレクトリ内のコードと、examples/ReceiveDumpのサンプルコードを編集して使います

/examples/ReceiveDump/PinDefinitionsAndMore.h 336行目:
#define IR_RECEIVE_PIN 2
   ↓
#define IR_RECEIVE_PIN 16

/examples/ReceiveDump/ReceiveDump.ino (全面書換え)
#include "PinDefinitionsAndMore.h"
#include <IRremote.hpp>

void printRawData(uint32_t raw)
{
	for (int step = 16; step >=0; step-=8) {
		uint8_t hex = (raw>>step)&0xFF;
		if (hex & 0xF0) {
			Serial.print(hex>>4, HEX);
		} else {
			Serial.print("0");
		}
		if (hex & 0x0F) {
			Serial.print((hex & 0x0F), HEX);
		} else {
			Serial.print("0");
		}
	}
}

void setup()
{
	Serial.begin(115200);
#if defined (ARDUINO_BBC_MICROBIT_V2)
	IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
#elif defined (ARDUINO_ARCH_RP2040)
	IrReceiver.begin(28, ENABLE_LED_FEEDBACK);
#endif
}

void loop()
{
	uint32_t rawCode, rawData;

	if (IrReceiver.decode()) {  // Grab an IR code
//	IrReceiver.printIRResultShort(&Serial);
		Serial.print(F(" Address=0x"));
		Serial.print(IrReceiver.decodedIRData.address, HEX);
		Serial.print(F(", Command="));
		Serial.print(IrReceiver.decodedIRData.command);
		Serial.print(F(", Raw-Data=0x"));
		rawCode = IrReceiver.decodedIRData.decodedRawData;
		rawData  = (rawCode <<  8) & 0xFF0000;
		rawData |= (rawCode >>  8) & 0x00FF00;
		rawData |= (rawCode >> 24) & 0x0000FF;
		printRawData(rawData);
		Serial.println("");
		delay(50);
		IrReceiver.resume();  // Prepare for the next IR frame
	}
}
$ pio device monitor -p /dev/ttyACM0 -b 115200

Address=0x0, Command=70, Raw-Data=0xFF46B9
Address=0x0, Command=68, Raw-Data=0xFF44BB
Address=0x0, Command=64, Raw-Data=0xFF40BF
Address=0x0, Command=67, Raw-Data=0xFF43BC
Address=0x0, Command=21, Raw-Data=0xFF15EA
Address=0x0, Command=22, Raw-Data=0xFF16E9
Address=0x0, Command=25, Raw-Data=0xFF19E6
Address=0x0, Command=13, Raw-Data=0xFF0DF2
Address=0x0, Command=12, Raw-Data=0xFF0CF3
Address=0x0, Command=24, Raw-Data=0xFF18E7
Address=0x0, Command=94, Raw-Data=0xFF5EA1
Address=0x0, Command=8, Raw-Data=0xFF08F7
Address=0x0, Command=28, Raw-Data=0xFF1CE3
Address=0x0, Command=90, Raw-Data=0xFF5AA5
Address=0x0, Command=66, Raw-Data=0xFF42BD
Address=0x0, Command=82, Raw-Data=0xFF52AD
Address=0x0, Command=74, Raw-Data=0xFF4AB5

リモコンが押されたときに取得されるCommandコードを元にロボットカーを制御することが可能です

●8.IOポート

IOポートは左側 P10,P9,P8,P7、右側 P5,P4,P3,P2 が引き出されています

micro:bit V2 のエッジコネクタ


micro:bit V2ロボットで使用しているポートと空ポートの一覧です
Pxx番号端子機能ROBOT CAR
0A0, LEFT PAD Photoresistor(right)
1A1, MIDDLE PADPhotoresistor(left)
2A2, RIGHT PAD P2
3A3, COL3 P3
4A4, COL1 P4
5BTN A P5
6COL4
7COL2 P7
8NFC2, GPIO1 P8
9NFC1, GPIO2 P9
10A5, COL5 P10
11BTN B
12Accessbility TCRT5K(right)
13SCK TCRT5K(left)
14MISO TRIG
15MOSI ECHO
16GPIO3 IR Receiver
173.3V
183.3V
19SCL STC8G1K08
20SDA STC8G1K08
赤文字にある8つのポートが使用可能です

●16.I2C拡張ポート

I2Cソケットも実装されているので、空ポートも合わせると十分拡張ボードとして使用できます

●ブザー

Arduino言語でオンボード・ブザーを制御できなかったので、外付けで圧電スピーカーをP2に取り付けました
// The micro:bit v2 has a speaker connected to pin 0
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	#define PIN_BUZZER    2
	#define PIN_PUSH_BTN  PIN_BUTTON_A
#elif defined (ARDUINO_ARCH_RP2040)
	#define PIN_BUZZER    6
	#define PIN_PUSH_BTN  11
#endif

void setup()
{
	pinMode(PIN_BUZZER,   OUTPUT);
#if defined (ARDUINO_BBC_MICROBIT_V2) 
	pinMode(PIN_PUSH_BTN, INPUT_PULLUP);
#elif defined (ARDUINO_ARCH_RP2040)
	pinMode(PIN_PUSH_BTN, INPUT);
#endif
}

void beep(int hz, int ms)
{
	long loop = (ms / 1000) * hz;
	long us = 500000 / hz;
	// tone(SPEAKER_PIN, 262, 1000);
	// 1000Hz (Period 1ms = 1000us) -> HIGH 500us, LOW 500us
	for (long lng = 0; lng < loop; lng++) {
		digitalWrite(PIN_BUZZER, HIGH);
		delayMicroseconds(us);
		digitalWrite(PIN_BUZZER, LOW);
		delayMicroseconds(us);
	}
}

void loop() {
  // When button A is pressed, LOW is output.
#if defined (ARDUINO_BBC_MICROBIT_V2) 
  if (digitalRead(PIN_PUSH_BTN) == LOW) {
#elif defined (ARDUINO_ARCH_RP2040)
  if (digitalRead(PIN_PUSH_BTN) == HIGH) {
#endif
		beep(262,1000); // Play a 262Hz C note for 1000ms
		beep(440,1000); // Play a 440Hz A note for 1000ms
  }
}
後述の Raspberry Pi Pico では、外付けのプッシュボタンを取付けています。 このプッシュボタン・モジュールにはプルダウン回路が内蔵されています。

●補足:STC8G1K08プログラミング
$ pio boards STC8G1K08
Platform: intel_mcs51
===============================================================
ID         MCU        Frequency Flash RAM    Name
---------- ---------- --------- ----- ------ ------------------
STC8G1K08  STC8G1K08  11MHz     8KB   1.25KB Generic STC8G1K08
STC8G1K08A STC8G1K08A 11MHz     8KB   1.25KB Generic STC8G1K08A
STC8G1K08T STC8G1K08T 11MHz     8KB   1.25KB Generic STC8G1K08T

$ pio init -b STC8G1K08
Platform Manager: Installing intel_mcs51
Downloading [####################################] 100%
Unpacking [####################################] 100%
Platform Manager: intel_mcs51@2.2.0 has been installed!
Tool Manager: Installing platformio/toolchain-sdcc @ >=1.40100.0,<1.40401.0
UnknownPackageError: Could not find the package with 'platformio/toolchain-sdcc @ >=1.40100.0,<1.40401.0' requirements for your system 'linux_aarch64'

$ cat .platformio/platforms/intel_mcs51/boards/STC8G1K08.json
{
  "build": {
    "core": "naked",
    "extra_flags": "-DSTC8G1KXX -DSTC8G1K08 -DNAKED_ARCH_MCS51 -DNAKED_MCS51_STC8G1KXX",
    "f_cpu": "11059200L",
    "size_iram": 256,
    "size_xram": 1024,
    "size_code": 8192,
    "size_heap": 128,
    "mcu": "stc8g1k08",
    "cpu": "mcs51",
    "variant": "stc8g1kxx"
  },
  "frameworks": [],
  "upload": {
    "maximum_ram_size": 1280,
    "maximum_size": 8192,
    "protocol": "stcgal",
    "stcgal_protocol": "stc8",
    "protocols": [
      "stcgal"
    ]
  },
  "name": "Generic STC8G1K08",
  "url": "http://www.stcmicro.com/stc/stc8g1k08.html",
  "vendor": "STC"
}

急ぎではないので、放置します。STC8G1K08を使う機会があればそのときに検討します。

●Micro:bit Smart Robot Car を Raspberry Pi Pico で制御する
このロボットカーではSPI端子がライントラッキングセンサーと超音波センサーに利用されてしまっています。 そこでSPIを利用したい場合は、micro:bit を Raspberry Pi Pico に差し替えて利用します。


Raspberr Pi Pico W Pinouts


Picoの端子を、micro:bit V2のエッジコネクタに対応させます


Pico の裏側のパッドなどがショートしないようにポリイミドテープで絶縁しています。


秋月電子が販売しているmicro:bitユニバーサル基板の横方向スルーホール数はPicoのピン数と同じです

上部はユニバーサル基板にL型ヘッダーピンを通してPicoにハンダ付けしています。

上部ヘッダーピン   Pico         エッジコネクタ
PIN_SERIAL1_TX ←   1 GP0
PIN_SERIAL1_RX ←   2 GP1
GND            ←  GND
                    4 GP2 PIN_WIRE1_SDA → P20 STC8G1K08
                    5 GP3 PIN_WIRE1_SCL → P19 STC8G1K08
PIN_WIRE0_SDA  ←   6 GP4
PIN_WIRE0_SCL  ←   7 GP5
               ←  GND
                    9 GP6     → P2
                   10 GP7     → P3
                   11 GP8     → P4
                   12 GP9     → P5
              ←   GND
              ←   14 GP10
                   15 GP11    → P7
PIN_SPI1_MISO ←   16 GP12
PIN_SPI1_SS   ←   17 GP13
GND           ←   GND
PIN_SPI1_SCK  ←   19 GP14
PIN_SPI1_MOSI ←   20 GP15
                   21 GP16     → P8
                   22 GP17     → P9
                   GND
                   24 GP18     → P10
                   25 GP19     → P12 TCRT5K(right)
                   26 GP20     → P13 TCRT5K(left)
                   27 GP21     → P14 TRIG
                   GND
                   29 GP22     → P15 ECHO
                   RUN
                   31 GP26     → P0 Photoresistor(right)
                   32 GP27     → P1 Photoresistor(left)
                   GND
                   34 GP28     → P16 IR Receiver
                   VREF
                   3V3(OUT)    → 3V3
                   3V3_EN
                   GND       ←→ GND
                   VSYS        ← 3V3
                   VBUS(5V)
※GP26,27,28は、12bitアナログ端子です


micro:bitの3V端子は入出力として使えますが、Picoの3V3端子は出力専用です。 拡張ボード側から電力供給を受ける場合は、左側ヘッダーピン BOARDとVSYSをショートさせ、 Pico側から拡張ボードへ給電する場合は、BOARDと1つ上の3V3をショートさせます。


プルダウン回路内蔵のプッシュボタンを取り付けています。

●プロジェクトの作成

$ pio boards pico
Platform: raspberrypi
===================================================
ID   MCU    Frequency Flash RAM   Name
---- ------ --------- ----- ----- -----------------
pico RP2040 133MHz    2MB   264KB Raspberry Pi Pico
$ pio init -b pico
Resolving pico dependencies...
Platform Manager: Installing raspberrypi
Downloading [####################################] 100%
Unpacking [####################################] 100%
Platform Manager: raspberrypi@1.18.0 has been installed!
Tool Manager: Installing platformio/toolchain-gccarmnoneeabi @ ~1.90201.0
UnknownPackageError: Could not find the package with 'platformio/toolchain-gccarmnoneeabi @ ~1.90201.0' requirements for your system 'linux_aarch64'

$ vi platformio.ini
[env:pico]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
board = pico
framework = arduino
board_build.core = earlephilhower
upload_port = /media/pi/RPI-RP2/
monitor_port = /dev/ttyACM0
monitor_speed = 115200

Raspberry Pi Pico W and Pico WH

~/.platformio/platforms/raspberrypi@src-ff76a3915224135aafad379817f41edd/boards/rpipicow.json
{
    "build": {
        "arduino": {
            "earlephilhower": {
                "boot2_source": "boot2_w25q080_2_padded_checksum.S",
                "usb_vid": "0x2E8A",
                "usb_pid": "0xF00A"
            }
        },
        "core": "earlephilhower",
        "cpu": "cortex-m0plus",
        "extra_flags": "-DARDUINO_RASPBERRY_PI_PICO_W -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250  -DPICO_CYW43_SUPPORTED=1 -DCYW43_PIN_WL_DYNAMIC=1",
        "f_cpu": "133000000L",
        "hwids": [
            [
                "0x2E8A",
                "0x00C0"
            ],
            [
                "0x2E8A",
                "0xF00A"
            ]
        ],
        "mcu": "rp2040",
        "variant": "rpipicow"
    },
    "debug": {
        "jlink_device": "RP2040_M0_0",
        "openocd_target": "rp2040.cfg",
        "svd_path": "rp2040.svd"
    },
    "frameworks": [
        "arduino",
        "picosdk"
    ],
    "name": "Pico W",
    "upload": {
        "maximum_ram_size": 262144,
        "maximum_size": 2097152,
        "require_upload_port": true,
        "native_usb": true,
        "use_1200bps_touch": true,
        "wait_for_upload_port": false,
        "protocol": "picotool",
        "protocols": [
            "blackmagic",
            "cmsis-dap",
            "jlink",
            "raspberrypi-swd",
            "picotool",
            "picoprobe"
        ]
    },
    "url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
    "vendor": "Raspberry Pi"
~/.platformio/packages/framework-arduinopico/variants/rpipicow/pins_arduino.h
#pragma once

// Pin definitions taken from:
//    https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf

#include 

// LEDs
#define PIN_LED        (64u)

// Serial
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)

#define PIN_SERIAL2_TX (8u)
#define PIN_SERIAL2_RX (9u)

// SPI
#define PIN_SPI0_MISO  (16u)
#define PIN_SPI0_MOSI  (19u)
#define PIN_SPI0_SCK   (18u)
#define PIN_SPI0_SS    (17u)

#define PIN_SPI1_MISO  (12u)
#define PIN_SPI1_MOSI  (15u)
#define PIN_SPI1_SCK   (14u)
#define PIN_SPI1_SS    (13u)

// Wire
#define PIN_WIRE0_SDA  (4u)
#define PIN_WIRE0_SCL  (5u)

#define PIN_WIRE1_SDA  (26u)
#define PIN_WIRE1_SCL  (27u)

#define SERIAL_HOWMANY (3u)
#define SPI_HOWMANY    (2u)
#define WIRE_HOWMANY   (2u)

#include "../generic/common.h"
~/.platformio/packages/framework-arduinopico/variants/generic/common.h
#pragma once

#include 

#define PINS_COUNT          (30u)
#define NUM_DIGITAL_PINS    (30u)
#define NUM_ANALOG_INPUTS   (4u)
#define NUM_ANALOG_OUTPUTS  (0u)
#define ADC_RESOLUTION      (12u)
#define WIRE_INTERFACES_COUNT (WIRE_HOWMANY)

#ifdef PIN_LED
#define LED_BUILTIN PIN_LED
#endif

#ifdef __PIN_D0
static const uint8_t D0 = __PIN_D0;
#else
static const uint8_t D0 = (0u);
#endif
#ifdef __PIN_D1
static const uint8_t D1 = __PIN_D1;
#else
static const uint8_t D1 = (1u);
#endif
#ifdef __PIN_D2
static const uint8_t D2 = __PIN_D2;
#else
static const uint8_t D2 = (2u);
#endif
#ifdef __PIN_D3
static const uint8_t D3 = __PIN_D3;
#else
static const uint8_t D3 = (3u);
#endif
#ifdef __PIN_D4
static const uint8_t D4 = __PIN_D4;
#else
static const uint8_t D4 = (4u);
#endif
#ifdef __PIN_D5
static const uint8_t D5 = __PIN_D5;
#else
static const uint8_t D5 = (5u);
#endif
#ifdef __PIN_D6
static const uint8_t D6 = __PIN_D6;
#else
static const uint8_t D6 = (6u);
#endif
#ifdef __PIN_D7
static const uint8_t D7 = __PIN_D7;
#else
static const uint8_t D7 = (7u);
#endif
#ifdef __PIN_D8
static const uint8_t D8 = __PIN_D8;
#else
static const uint8_t D8 = (8u);
#endif
#ifdef __PIN_D9
static const uint8_t D9 = __PIN_D9;
#else
static const uint8_t D9 = (9u);
#endif
#ifdef __PIN_D10
static const uint8_t D10 = __PIN_D10;
#else
static const uint8_t D10 = (10u);
#endif
#ifdef __PIN_D11
static const uint8_t D11 = __PIN_D11;
#else
static const uint8_t D11 = (11u);
#endif
#ifdef __PIN_D12
static const uint8_t D12 = __PIN_D12;
#else
static const uint8_t D12 = (12u);
#endif
#ifdef __PIN_D13
static const uint8_t D13 = __PIN_D13;
#else
static const uint8_t D13 = (13u);
#endif
#ifdef __PIN_D14
static const uint8_t D14 = __PIN_D14;
#else
static const uint8_t D14 = (14u);
#endif
#ifdef __PIN_D15
static const uint8_t D15 = __PIN_D15;
#else
static const uint8_t D15 = (15u);
#endif
#ifdef __PIN_D16
static const uint8_t D16 = __PIN_D16;
#else
static const uint8_t D16 = (16u);
#endif
#ifdef __PIN_D17
static const uint8_t D17 = __PIN_D17;
#else
static const uint8_t D17 = (17u);
#endif
#ifdef __PIN_D18
static const uint8_t D18 = __PIN_D18;
#else
static const uint8_t D18 = (18u);
#endif
#ifdef __PIN_D19
static const uint8_t D19 = __PIN_D19;
#else
static const uint8_t D19 = (19u);
#endif
#ifdef __PIN_D20
static const uint8_t D20 = __PIN_D20;
#else
static const uint8_t D20 = (20u);
#endif
#ifdef __PIN_D21
static const uint8_t D21 = __PIN_D21;
#else
static const uint8_t D21 = (21u);
#endif
#ifdef __PIN_D22
static const uint8_t D22 = __PIN_D22;
#else
static const uint8_t D22 = (22u);
#endif
#ifdef __PIN_D23
static const uint8_t D23 = __PIN_D23;
#else
static const uint8_t D23 = (23u);
#endif
#ifdef __PIN_D24
static const uint8_t D24 = __PIN_D24;
#else
static const uint8_t D24 = (24u);
#endif
#ifdef __PIN_D25
static const uint8_t D25 = __PIN_D25;
#else
static const uint8_t D25 = (25u);
#endif
#ifdef __PIN_D26
static const uint8_t D26 = __PIN_D26;
#else
static const uint8_t D26 = (26u);
#endif
#ifdef __PIN_D27
static const uint8_t D27 = __PIN_D27;
#else
static const uint8_t D27 = (27u);
#endif
#ifdef __PIN_D28
static const uint8_t D28 = __PIN_D28;
#else
static const uint8_t D28 = (28u);
#endif
#ifdef __PIN_D29
static const uint8_t D29 = __PIN_D29;
#else
static const uint8_t D29 = (29u);
#endif

#if defined(PICO_RP2040) || (defined(PICO_RP2350) && PICO_RP2350A)

#ifdef __PIN_A0
static const uint8_t A0 = __PIN_A0;
#else
static const uint8_t A0 = (26u);
#endif

#ifdef __PIN_A1
static const uint8_t A1 = __PIN_A1;
#else
static const uint8_t A1 = (27u);
#endif

#ifdef __PIN_A2
static const uint8_t A2 = __PIN_A2;
#else
static const uint8_t A2 = (28u);
#endif

#ifdef __PIN_A3
static const uint8_t A3 = __PIN_A3;
#else
static const uint8_t A3 = (29u);
#endif

#elif defined(PICO_RP2350) && !PICO_RP2350A // RP2350B

#ifdef __PIN_D30
static const uint8_t D30 = __PIN_D30;
#else
static const uint8_t D30 = (30u);
#endif
#ifdef __PIN_D31
static const uint8_t D31 = __PIN_D31;
#else
static const uint8_t D31 = (31u);
#endif
#ifdef __PIN_D32
static const uint8_t D32 = __PIN_D32;
#else
static const uint8_t D32 = (32u);
#endif
#ifdef __PIN_D33
static const uint8_t D33 = __PIN_D33;
#else
static const uint8_t D33 = (33u);
#endif
#ifdef __PIN_D34
static const uint8_t D34 = __PIN_D34;
#else
static const uint8_t D34 = (34u);
#endif
#ifdef __PIN_D35
static const uint8_t D35 = __PIN_D35;
#else
static const uint8_t D35 = (35u);
#endif
#ifdef __PIN_D36
static const uint8_t D36 = __PIN_D36;
#else
static const uint8_t D36 = (36u);
#endif
#ifdef __PIN_D37
static const uint8_t D37 = __PIN_D37;
#else
static const uint8_t D37 = (37u);
#endif
#ifdef __PIN_D38
static const uint8_t D38 = __PIN_D38;
#else
static const uint8_t D38 = (38u);
#endif
#ifdef __PIN_D39
static const uint8_t D39 = __PIN_D39;
#else
static const uint8_t D39 = (39u);
#endif
#ifdef __PIN_D40
static const uint8_t D40 = __PIN_D40;
#else
static const uint8_t D40 = (40u);
#endif
#ifdef __PIN_D41
static const uint8_t D41 = __PIN_D41;
#else
static const uint8_t D41 = (41u);
#endif
#ifdef __PIN_D42
static const uint8_t D42 = __PIN_D42;
#else
static const uint8_t D42 = (42u);
#endif
#ifdef __PIN_D43
static const uint8_t D43 = __PIN_D43;
#else
static const uint8_t D43 = (43u);
#endif
#ifdef __PIN_D44
static const uint8_t D44 = __PIN_D44;
#else
static const uint8_t D44 = (44u);
#endif
#ifdef __PIN_D45
static const uint8_t D45 = __PIN_D45;
#else
static const uint8_t D45 = (45u);
#endif
#ifdef __PIN_D46
static const uint8_t D46 = __PIN_D46;
#else
static const uint8_t D46 = (46u);
#endif
#ifdef __PIN_D47
static const uint8_t D47 = __PIN_D47;
#else
static const uint8_t D47 = (47u);
#endif

#ifdef __PIN_A0
static const uint8_t A0 = __PIN_A0;
#else
static const uint8_t A0 = (40u);
#endif

#ifdef __PIN_A1
static const uint8_t A1 = __PIN_A1;
#else
static const uint8_t A1 = (41u);
#endif

#ifdef __PIN_A2
static const uint8_t A2 = __PIN_A2;
#else
static const uint8_t A2 = (42u);
#endif

#ifdef __PIN_A3
static const uint8_t A3 = __PIN_A3;
#else
static const uint8_t A3 = (43u);
#endif

#ifdef __PIN_A4
static const uint8_t A4 = __PIN_A4;
#else
static const uint8_t A4 = (44u);
#endif

#ifdef __PIN_A5
static const uint8_t A5 = __PIN_A5;
#else
static const uint8_t A5 = (45u);
#endif

#ifdef __PIN_A6
static const uint8_t A6 = __PIN_A6;
#else
static const uint8_t A6 = (46u);
#endif

#ifdef __PIN_A7
static const uint8_t A7 = __PIN_A7;
#else
static const uint8_t A7 = (47u);
#endif

#endif


static const uint8_t SS = PIN_SPI0_SS;
static const uint8_t MOSI = PIN_SPI0_MOSI;
static const uint8_t MISO = PIN_SPI0_MISO;
static const uint8_t SCK = PIN_SPI0_SCK;

static const uint8_t SDA = PIN_WIRE0_SDA;
static const uint8_t SCL = PIN_WIRE0_SCL;

Program RP2040 in Arduino
In this guide you'll learn how to install Earle Philhower's Arduino core for RP2040 devices, arduino-pico. This core supports a bunch of different RP2040 boards. Supported boards at time of writing (there's probably more now)
〇Raspberry Pi Pico
〇Adafruit Feather RP2040
〇Adafruit ItsyBitsy RP2040
〇Adafruit Macropad RP2040
〇Adafruit QTPy RP2040
〇Adafruit STEMMA Friend RP2040
〇Adafruit Trinkey RP2040 QT
〇Arduino Nano RP2040 Connect
〇SparkFun ProMicro RP2040
〇Generic (configurable flash, I/O pins)
This core makes it easy to use Arduino with all your favorite RP2040 boards so you can create fast projects using them.

You can find the documentation for the Earle Philhower Arduino core at https://arduino-pico.readthedocs.io/en/latest/

●Installing the Earle Philhower core
The first step to getting the Earle Philhower core to run on your RP2040 device is to install it.
Using this core with PlatformIO

●余談:夜間照明
このロボットカーは電池ボックスを基板に直付けではなく、電池ボックスからの電源ケーブルを基板上のXHコネクタに接続するようになっています。


自作のUSB-XHケーブルです。USBケーブルから給電することで基板上のRGB LEDを夜間照明に利用することもできます。

●さらに高機能へ


上部ヘッダ   Nano ESP32     エッジコネクタ
3:SCK    ←   1 D13/SCK
5:3V3    ←   2 3V3(OUT)  → 3V3
              3 GPIO46 B0
              4 GPIO1  A0/DAC0
              5 GPIO2  A1        → P0 Photoresistor(right)
              6 GPIO3  A2        → P1 Photoresistor(left)
              7 GPIO4  A3        → P7
              8 GPIO11 A4/SDA    → P20 STC8G1K08
              9 GPIO12 A5/SCL    → P19 STC8G1K08
             10 GPIO13 A6        → P12 TCRT5K(right)
             11 GPIO14 A7        → P13 TCRT5K(left)
             12 VBUS(OUT)
             13 GPIO0  B1
             14 GND       → GND
             15 VIN(IN)   ← 3V3
Qwiic:TX ←  16 GPIO43 D1/TX0
Qwiic:RX ←  17 GPIO44 D0/RX0
4:RST    ←  18 RESET
8:GND    ←  19 GND
             20 GPIO5  D2        → P2
             21 GPIO6  D3        → P3
             22 GPIO7  D4        → P4
             23 GPIO8  D5        → P5
7:DC     ←  24 GPIO9  D6        
6:SS     ←  25 GPIO10 D7
             26 GPIO17 D8        → P14 TRIG
             27 GPIO18 D9        → P15 ECHO
             28 GPIO21 D10       → P16 IR Receiver
2:MOSI    ← 29 GPIO38 D11/MOSI
1:MISO    ← 30 GPIO47 D12/MISO

$ pio boards 'NANO ESP32'
========================================================================
ID                  MCU      Frequency  Flash  RAM    Name
------------------  -------  ---------  -----  -----  ------------------
arduino_nano_esp32  ESP32S3  240MHz     16MB   320KB  Arduino Nano ESP32
環境設定ファイルを生成します
$ pio init -b arduino_nano_esp32

arduino_nano_esp32.json で"-DBOARD_HAS_PIN_REMAP" の記述を削除してESP32スタイルのGPIO番号での指定を有効にします。

~/.platformio/platforms/espressif32/boards/arduino_nano_esp32.json
"extra_flags": [
  "-DARDUINO_NANO_ESP32",
  "-DBOARD_HAS_PIN_REMAP", ← 削除
  "-DBOARD_HAS_PSRAM",^

~/.platformio/packages/framework-arduinoespressif32/variants/arduino_nano_nora/pins_arduino.h
#if defined(BOARD_HAS_PIN_REMAP) && !defined(BOARD_USES_HW_GPIO_NUMBERS)
// Arduino style definitions (API uses Dx)
static constexpr uint8_t D0         = 0; // also RX
static constexpr uint8_t D1         = 1; // also TX
......
#else
// ESP32-style definitions (API uses GPIOx)
static constexpr uint8_t D0         = 44; // also RX
static constexpr uint8_t D1         = 43; // also TX
......

$ vi platformio.ini
[env:arduino_nano_esp32]
platform = espressif32
board = arduino_nano_esp32
framework = arduino
board_build.partitions = default_16MB.csv
build_flags =
        -mfix-esp32-psram-cache-issue
        -DCORE_DEBUG_LEVEL=4
board_build.arduino.memory_type = qio_opi
board_build.f_flash = 80000000L
board_build.flash_mode = dio
monitor_speed = 115200
upload_protocol = dfu
upload_port = /dev/ttyACM0
●DFU(Device Firmware Update)モードでアップロードできない場合の対処策

Arduino Nano ESP32互換機は製品によってDFU(Device Firmware Update)モードでアップロードできない場合があります。
$ pio run -e arduino_nano_esp32 -t upload
dfu-util: No DFU capable USB device available

その際には、ESP32 DOWNLOADERを介するとアップロードが可能になります。
Downloader   NANO ESP32
GND ─ GND
G0 ─ GPIO0:B1
EN ─ RST
TXD ─ GPIO44:RX0
RXD ─ GPIO43:TX0
3.3V ─ VIN

$ vi platformio.ini
upload_protocol = dfu
  ↓
upload_protocol = esptool
;upload_protocol = dfu

........
Checking size .pio/build/arduino_nano_esp32/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   9.4% (used 30656 bytes from 327680 bytes)
Flash: [          ]   4.5% (used 292693 bytes from 6553600 bytes)
Building .pio/build/arduino_nano_esp32/firmware.bin
esptool.py v4.9.0
Creating esp32s3 image...
Merged 2 ELF sections
Successfully created esp32s3 image.
Configuring upload protocol...
AVAILABLE: cmsis-dap, dfu, esp-bridge, esp-builtin, esp-prog, espota, esptool, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa
CURRENT: upload_protocol = esptool
Looking for upload port...
Using manually specified: /dev/ttyACM0
Uploading .pio/build/arduino_nano_esp32/firmware.bin
esptool.py v4.9.0
Serial port /dev/ttyACM0
Connecting....
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 8MB (AP_3v3)
Crystal is 40MHz
MAC: xx:xx:xx:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00003fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x00057fff...
SHA digest in image updated
Compressed 14032 bytes to 9808...
Writing at 0x00000000... (100 %)
Wrote 14032 bytes (9808 compressed) at 0x00000000 in 0.3 seconds (effective 373.8 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 146...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (146 compressed) at 0x00008000 in 0.0 seconds (effective 1563.9 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 2494.9 kbit/s)...
Hash of data verified.
Compressed 293056 bytes to 167702...
Writing at 0x00010000... (9 %)
Writing at 0x0001b94e... (18 %)
Writing at 0x00024795... (27 %)
Writing at 0x00029e7f... (36 %)
Writing at 0x0002f315... (45 %)
Writing at 0x0003469d... (54 %)
Writing at 0x00039d90... (63 %)
Writing at 0x0004269c... (72 %)
Writing at 0x0004ae71... (81 %)
Writing at 0x0005048b... (90 %)
Writing at 0x0005601c... (100 %)
Wrote 293056 bytes (167702 compressed) at 0x00010000 in 3.9 seconds (effective 596.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

●単なる電力供給車として使う
単4電池3本搭載のロボットカーは降圧回路を経由して、micro:bitエッジコネクタに 3.3V を供給しています。 そこで、3.3V駆動のESP32マイコンへの電力供給車として使ってしまいます。


Adafruit QT Py ESP32-S2の5V端子は外部電源からの電圧入力として使用することもできますが、電源への逆流防止にショットキーダイオードを経由する必要があります。 また5V端子からUSBポートに電源を供給することはできません。保護ダイオードが内蔵されており、5VがUSBコネクタに供給されるのを防いでいます。

micro:bitユニバーサル基板の前面にはQT-Py ESP32-S2とAdafruit 320x240 IPS TFT(ST7789)を取り付けています

QT Py ESP32-S2のGNDと3.3V端子のみをエッジコネクタに接続しています。 当初、エッジコネクタの3.3Vとの間に1N5817ショットキーバリアダイオードを取り付けていましたが、これにより、0.4V程度の電圧降下が発生します。 QT Py 3.3V端子入力電圧が3Vを多少下回っても動作しますが、周辺機器を接続すると不安定になります。 そこで、ジャンパーピンをショートさせる方式に変更しました。 QT Py のUSB端子から給電する場合は忘れずにピンを外します。


裏側はこんな感じです


Adafruit IPS TFT に実装されているmicrSDカードスロットは読み取り用なので、別途、 Adafruit microSD Card BFF を取り付けています
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
2019.12.13 モバイルバッテリーによる瞬間停電対策
2020.01.01 1280x800 HDMI MONITOR
2020.01.12 micro:bitをコマンドラインで使う
2020.02.04 サーマルプリンタを使う
2020.04.10 電卓を制御して数字を表示する
2020.08.03 Seeeduino XIAO
2020.08.09 LGT8F328P - Arduino clone
2020.09.18 電流計測モジュール INA219
2021.02.16 癒しの電子回路
2021.03.06 疑似コンソール
2021.08.08 電子ペーパー
2021.09.04 AVRマイコン・ATTiny85
2021.09.25 pH測定
2021.11.13 NTP時刻取得と活用
2021.11.27 GPS情報取得
2021.12.11 GR-KURUMI
2021.12.25 ATMEGA328P 3.3V/8MHz
2022.01.11 AS-289R2 プリンタシールド
2022.01.25 TM1637 & ATtiny85
2022.02.22 Raspberry Pi Zero 小道具
2022.03.01 ATTinyCore
2022.03.18 Adafruit QT Py + XIAO Expansion board
2022.07.31 サーマルプリンター番外編:通信筒
2023.01.01 FTP Server & SPI Flash SD
2023.02.01 LPC810(ARM Cortex-M0+)
2023.02.15 IchigoJam互換機
2023.03.01 Telnet
2023.04.26 USBメモリをUART接続で利用する
2023.05.14 焦電型赤外線モーションセンサー
2023.07.01 文字化けしないキーボード
2023.08.01 Bluetoothサーマルプリンター
2023.08.12 LattePanda 2G/32GB
2023.09.04 SI-3012KS
2023.12.01 疑似コンソール(C言語編)
2023.12.16 昭和レトロ・温度湿度時刻計
2023.12.25 二酸化炭素濃度監視
2024.01.23 なんちゃってmicro:bit
2024.02.07 オリジナル micro:bit
2024.02.23 ESP32 OTA
2024.03.08 TELNETサーマルプリンター
2024.05.08 ESP32 PROGRAM SELECTOR
2024.05.23 統合開発環境とQwiic
2025.01.24 赤外線リモコン
2025.03.25 QRCode SCANNER
2025.04.08 Keyestudio 328 WiFi Plus
2025.08.23 NanoPi NEO3
2025.09.24 I2C接続microSDモジュール
2025.10.08 UNO 3.3V@8MHz
2026.01.29 micro:bit & Pico 拡張ボード

たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」 「一念発起して何かを始めても、いつも三日坊主で終わってしまう」 「色んなことを先延ばしにしたまま、時間だけが過ぎていく」 そこで本書では、そんな著者が独自に開発した、 まったく新しい目標達成メソッド「100日デザイン」について、 その知識と技術を、余すところなくご紹介します。

まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。 ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。

今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。

ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。 29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!

【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。 基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。

Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説! 500以上のサンプルを掲載。実行結果も確認。 全24章の包括的なチュートリアル。

ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS… 全WEB媒体で効果バツグン! カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術

小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。

Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード

電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)

Copyright © 2011-2027 Sarako Tsukiyono All rights reserved®.