M5STACK BugC
2026.07.04

メルカリで購入した電子工作用パーツに、M5STACK BugC が含まれていたので遊んでみました

発売当時は、M5StickC別売りで本体価格1892円でした。
BugC
BugCは、M5StickCと互換性のあるプログラマブルロボットベースです。
ベース基板には、4つのモーターとLEDを制御するSTM32F030F4マイクロコントローラが搭載されており、
I2Cプロトコル(0x38)を通じて制御します。
基板裏側には16340バッテリーホルダーが付いています。
・リモートコントロール
・プログラマブル
・4wayモータードライバー
・4 x ギアードモーター
・2 x RGB LED
・シンプルでコンパクトなデザイン
・バッテリーホルダー搭載
・全方向への柔軟な動作が可能
・モーターの仕様
・定格電圧:DC3.7V
・定格回転数:15000~2000rpm
・定格電流:50mA
・失速電流: 70mA
・絶縁抵抗: 10MΩ
バッテリーの充電は、M5StickCを接続してUSBによる給電を行います

後継機種のBUGC2は、StickC Plus2 同梱で、SWITCH SCIENCE にて 9856円で販売されています。
●Pinouts

基板にはM5StickCに合わせて8ピンヘッダーがあり、右側のピンがGNDです。

BugCは、通常M5StickCを被せて使用しますが、I2C端子を持つマイコンであれば制御可能です。
〇Seeed Studio XIAO ESP32S3
うぷ主はM5ライブラリのような移植性の低いコードは避けています。
ここでは、XIAO ESP32-S3 を使いました。


BugCの制御基板です。M5StickCに合わせた8ピンヘッダーがあり、左側筐体先頭部分にLEDが2つあります。

まずはユニバーサル基板裏側に8ピン・メスソケット、その右に8ピンヘッダーをはんだ付けして、この2つのパーツの各ピンを平行にはんだで連結しています。

マイコンとヘッダーピンはジャンプワイヤーで繋げています。
空中に浮いているのは3.7V、16340リチウムイオン電池を5Vに昇圧するモジュールです。
BugC | | ESP32S3 |
GND | -------------- | GND |
xxxxxx | | |
SCL | -------------- | SCL |
xxxxxx | | |
SDA | -------------- | SDA |
BAT | -- 3.7V→5V -- | 5V |
3.3V | -------------- | 3.3V |
xxxxxx | | |

BugCにマイコン基板を挿した様子です
●搭載リチウムイオン電池16340(3.7V)の充電

BugCには、16340バッテリー(750mAh)1個が同梱されています

リチウムイオン電池充電モジュールをBugC基板のGND,BAT端子に繋いで充電します。
充電中は電源スイッチをオンにします。
●BugCが動く仕組み
M5Stackカフェ

BugCには上の写真のように4つの小さなモーターが少し外側に向かって付いていて、モーターの軸が床に斜めに接します。
モーターを写真のような向きに回転させたとき、この足は画面の手前から奥に向かって移動します。
この独立した4つのモーターの回転方向、速度を調節して、BugCを制御します。
●Protocol I2C(0x38)
BugCのI2C制御は、モーターとオンボードLEDの2種類です
/*-------------------------------------------------------*/
| MOTOR SPEED REG | 0x00
| -------------------------------------------------------
| FRONT_LEFT_reg[0] | R/W | FRONT_LEFT SPEED
| FRONT_RIGHT_reg[1] | R/W | FRONT_RIGHT SPEED
| REAR_LEFT_reg[2] | R/W | REAR_LEFT SPEED
| REAR_RIGHT_reg[3] | R/W | REAR_RIGHT SPEED
/*-------------------------------------------------------
Wire.beginTransmission(0x38);
Wire.write(0x00);
Wire.write(FRONT_LEFT SPEED);
Wire.write(FRONT_RIGHT SPEED);
Wire.write(REAR_LEFT SPEED);
Wire.write(REAR_RIGHT SPEED);
Wire.endTransmission();
/*-------------------------------------------------------*/
| RGB LED COLOR REG | 0x10
| -------------------------------------------------------
| left/right_reg[0] | R/W | left/right control
| | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| | R | R | R | R | R | R | R | SELECT |
| | -SELECT: 0 FRONT_LEFT RGB LED
| | 1 FRONT_RIGHT RGB LED
| rgb_r_reg[1] | R/W | RED value
| rgb_g_reg[2] | R/W | Green value
| rgb_b_reg[3] | R/W | Blue value
/*-------------------------------------------------------
Wire.beginTransmission(0x38);
Wire.write(0x10);
Wire.write(0); // FRONT_LEFT RGB LED
Wire.write(Red);
Wire.write(Green);
Wire.write(Blue);
Wire.endTransmission();
Wire.beginTransmission(0x38);
Wire.write(0x10);
Wire.write(1); // FRONT_RIGHT RGB LED
Wire.write(Red);
Wire.write(Green);
Wire.write(Blue);
Wire.endTransmission();
●ソースコード
〇bugC.cpp
/*
* @Author: Sorzn
* @Date: 2019-11-22 13:38:26
* @LastEditTime: 2019-11-22 14:28:56
* @Description: M5Stack Hat BUGC Lib
* @FilePath: /M5StickC/examples/Hat/BUGC/bugC.cpp
*/
#include "bugC.h"
void BUGC::Init() {
Wire.begin(SDA, SCL);
// Wire.begin(0, 26); // M5Stick-C
}
void BUGC::Write1Byte(uint8_t address, uint8_t Register_address, uint8_t data) {
Wire.beginTransmission(address);
Wire.write(Register_address);
Wire.write(data);
Wire.endTransmission();
}
void BUGC::Write2Byte(uint8_t address, uint8_t Register_address,
uint16_t data) {
Wire.beginTransmission(address);
Wire.write(Register_address);
Wire.write(data >> 8); // MSB
Wire.write(data & 0xFF); // LSB
Wire.endTransmission();
}
void BUGC::WriteBytes(uint8_t address, uint8_t Register_address, uint8_t *data,
size_t size) {
Wire.beginTransmission(address);
Wire.write(Register_address);
for (int i = 0; i < size; i++) {
Wire.write(*(data + i));
}
Wire.endTransmission();
}
uint8_t BUGC::ReadBytes(uint8_t address, uint8_t subAddress, uint8_t count,
uint8_t *dest) {
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
uint8_t i = 0;
if (Wire.endTransmission(false) == 0 &&
Wire.requestFrom(address, (uint8_t)count)) {
while (Wire.available()) {
dest[i++] = Wire.read();
}
return true;
}
return false;
}
//*******************************************************//
// if speed > 0; clockwise rotation
void BUGC::BugCSetSpeed(uint8_t pos, int8_t speed) {
speed = (speed > 100) ? 100 : speed;
speed = (speed < -100) ? -100 : speed;
Write1Byte(BUGC_ADDR, pos, speed);
}
void BUGC::BugCSetAllSpeed(int8_t speed_0, int8_t speed_1, int8_t speed_2,
int8_t speed_3) {
int8_t speed_out[4] = {speed_0, speed_1, speed_2, speed_3};
for (uint8_t i = 0; i < 4; i++) {
speed_out[i] = (speed_out[i] > 100) ? 100 : speed_out[i];
speed_out[i] = (speed_out[i] < -100) ? -100 : speed_out[i];
}
WriteBytes(BUGC_ADDR, 0x00, (uint8_t *)speed_out, 4);
}
void BUGC::BugCSetColor(uint32_t color_left, uint32_t color_right) {
uint8_t color_out[4];
color_out[0] = 0;
color_out[1] = (color_left & 0xff0000) >> 16;
color_out[2] = (color_left & 0x00ff00) >> 8;
color_out[3] = (color_left & 0x0000ff);
WriteBytes(BUGC_ADDR, 0x10, color_out, 4);
color_out[0] = 1;
color_out[1] = (color_right & 0xff0000) >> 16;
color_out[2] = (color_right & 0x00ff00) >> 8;
color_out[3] = (color_right & 0x0000ff);
WriteBytes(BUGC_ADDR, 0x10, color_out, 4);
}
〇bugC.h
/*
* @Author: Sorzn
* @Date: 2019-11-22 13:38:31
* @LastEditTime: 2019-11-22 14:33:56
* @Description: M5Stack Hat BUGC Lib
* @FilePath: /M5StickC/examples/Hat/BUGC/bugC.h
*/
#ifndef __BUG_C_H
#define __BUG_C_H
#include "Arduino.h"
#include "Wire.h"
#define BUGC_ADDR 0x38
#define FRONT_LEFT 0
#define FRONT_RIGHT 1
#define REAR_LEFT 2
#define REAR_RIGHT 3
class BUGC {
public:
void Init();
/**
* @description: Set BugC single motor speed
* @param pos: 0 ~ 3
* @param speed: -100 ~ 100
* @return:
*/
void BugCSetSpeed(uint8_t pos, int8_t speed);
/**
* @description: Set BugC motor speed
* @param speed_0: -100 ~ 100
* @param speed_1: -100 ~ 100
* @param speed_2: -100 ~ 100
* @param speed_3: -100 ~ 100
* @return:
*/
void BugCSetAllSpeed(int8_t speed_0, int8_t speed_1, int8_t speed_2,
int8_t speed_3);
/**
* @description: Set BugC sk6812 color
* @param color_left: (r << 16) | (g << 8) | b
* @param color_right: (r << 16) | (g << 8) | b
* @return:
*/
void BugCSetColor(uint32_t color_left, uint32_t color_right);
private:
void Write1Byte(uint8_t address, uint8_t Register_address, uint8_t data);
void Write2Byte(uint8_t address, uint8_t Register_address, uint16_t data);
void WriteBytes(uint8_t address, uint8_t Register_address, uint8_t* data,
size_t size);
uint8_t ReadBytes(uint8_t address, uint8_t subAddress, uint8_t count,
uint8_t* dest);
};
#endif
〇bugC.ino
#include "bugC.h"
BUGC BugC;
#define BUGC_ADDR 0x38
#define BUGC_LED_REG 0x10
#define BUGC_LED_LEFT 0x00
#define BUGC_LED_RIGHT 0x01
#define WAIT 20
void color(int velocity) {
uint8_t R, G, B;
velocity = velocity % 255;
if (velocity < 85) {
R = 255 - velocity * 3;
G = 0;
B = velocity * 3;
} else if (velocity < 170 ) {
velocity -= 85;
R = 0;
G = velocity * 3;
B = 255 - velocity * 3;
} else {
velocity -= 170;
R = velocity * 3;
G = 255 - velocity * 3;
B = 0;
}
Wire.beginTransmission(BUGC_ADDR);
Wire.write(BUGC_LED_REG);
Wire.write(BUGC_LED_LEFT);
Wire.write(R);
Wire.write(G);
Wire.write(B);
Wire.endTransmission();
Wire.beginTransmission(BUGC_ADDR);
Wire.write(BUGC_LED_REG);
Wire.write(BUGC_LED_RIGHT);
Wire.write(R);
Wire.write(G);
Wire.write(B);
Wire.endTransmission();
delay(WAIT);
}
void shou_led() {
int i = 0;
while(1) {
color(i);
if ((++i) == 255) i = 0;
}
}
void stop() {
BugC.BugCSetColor(0x100000, 0x100000); // RED
BugC.BugCSetAllSpeed(0, 0, 0, 0);
delay(1000);
}
void forward(float speed) {
int8_t leftF = 100 * speed;
int8_t rightF = -60 * speed;
int8_t leftR = 100 * speed;
int8_t rightR = -60 * speed;
BugC.BugCSetColor(0x000010, 0x000010); // BLUE
BugC.BugCSetAllSpeed(leftF, rightF, leftR, rightR);
delay(1000);
}
void back(float speed) {
int8_t leftF = -90 * speed;
int8_t rightF = 80 * speed;
int8_t leftR = -90 * speed;
int8_t rightR = 80 * speed;
BugC.BugCSetColor(0x101000, 0x101000); // YELLOW
BugC.BugCSetAllSpeed(leftF, rightF, leftR, rightR);
delay(1000);
}
void forward_left(float speed) {
int8_t leftF = 0 * speed;
int8_t rightF = -100 * speed;
int8_t leftR = 0 * speed;
int8_t rightR = -50 * speed;
BugC.BugCSetColor(0x001000, 0x000000); // GREEN
BugC.BugCSetAllSpeed(leftF, rightF, leftR, rightR);
delay(1000);
}
void forward_right(float speed) {
int8_t leftF = 100 * speed;
int8_t rightF = 0 * speed;
int8_t leftR = 50 * speed;
int8_t rightR = 0 * speed;
BugC.BugCSetColor(0x000000, 0x001000); // GREEN
BugC.BugCSetAllSpeed(leftF, rightF, leftR, rightR);
delay(1000);
}
void back_left(float speed) {
int8_t leftF = 0 * speed;
int8_t rightF = 50 * speed;
int8_t leftR = 0 * speed;
int8_t rightR = 100 * speed;
BugC.BugCSetColor(0x001000, 0x000000); // GREEN
BugC.BugCSetAllSpeed(leftF, rightF, leftR, rightR);
delay(1000);
}
void back_right(float speed) {
int8_t leftF = -50 * speed;
int8_t rightF = 0 * speed;
int8_t leftR = -100 * speed;
int8_t rightR = 0 * speed;
BugC.BugCSetColor(0x000000, 0x001000); // GREEN
BugC.BugCSetAllSpeed(leftF, rightF, leftR, rightR);
delay(1000);
}
void rotate_left(float speed) {
int8_t all = -30 * speed;
BugC.BugCSetColor(0x001000, 0x000000); // GREEN
BugC.BugCSetAllSpeed(all, all, all, all);
delay(1000);
}
void rotate_right(float speed) {
int8_t all = 30 * speed;
BugC.BugCSetColor(0x000000, 0x001000); // GREEN
BugC.BugCSetAllSpeed(all, all, all, all);
delay(1000);
}
void setup() {
delay(10000);
BugC.Init();
stop();
forward(0.8);
back(0.8);
rotate_left(0.8);
rotate_right(0.8);
forward_left(0.8);
forward_right(0.8);
back_left(0.8);
back_right(0.8);
stop();
while (1);
}
void loop() {}
実際に動かしてみると、
モーターの個体差、筐体の重心のズレなどにより接地圧が異なり、推進力にバラツキが生じます。
そのため、プログラムではモーターごとの補正を行っています。
M5StickCを使えば実装している6軸(加速度、ジャイロ)センサにより、ある程度の姿勢制御が可能かとは思いますが、
制御プログラムの作成にはかなり時間が掛かると思います。
●開発環境
ソースコードのビルドには、PlatformIOを使用しています。
Arduino開発環境構築 PlatformIO
|
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
Arduinoで学ぶ組込みシステム入門(第2版)
●Arduinoを使って組込みシステム開発を理解する
・ハードウェアやソフトウェアなどの基礎知識/
・設計から実装までを系統的に説明するモデルベース開発/
・Arduinoを用いた実際の開発例
最新 使える! MATLAB 第3版
◆◆すぐに「使える!」 全ページフルカラー!◆◆
・MATLAB R2022bに対応し、解説もより詳しく!/
・コマンド・スクリプトの例が豊富で、動かして学べる!/
・超基本から解説。これから使いはじめる人にぴったり!/
・全編フルカラー、スクリーンショットも豊富!
Amazon Web Services基礎からのネットワーク&サーバー構築改訂4版
1.システム構築をインフラから始めるには/
2.ネットワークを構築する/
3.サーバーを構築する/
4.Webサーバーソフトをインストールする/
5.HTTPの動きを確認する/
6.プライベートサブネットを構築する/
7.NATを構築する/
8.DBを用いたブログシステムの構築/
9.TCP/IPによる通信の仕組みを理解する
C言語は第二の母国語: 独学学生時代から企業内IT職人時代に培った、独立のための技術とノウハウ 平田豊著
学生時代から独学でプログラミングをはじめ、企業内でデバイスドライバを開発し、そして独立後もたくさんのアプリケーション開発や技術書制作に携わってきた著者。その筆者が大事に使い続ける「C言語」の“昔と今”について、気づいたことや役立つ知識、使ってきたツールなどについて、これまで記してきたことを整理してまとめました。
本書では、現役プログラマーだけでなく、これからプログラミングを学ぶ学生などにも有益な情報やノウハウを、筆者の経験を元に紹介しています。
1冊ですべて身につくJavaScript入門講座
・最初の一歩が踏み出せる! 初心者に寄り添うやさしい解説
・最新の技術が身につく! 今のJavaScriptの書き方・使い方
・絶対に知っておきたい! アニメーションとイベントの知識
・プログラミングの基本から実装方法まですべて学べる
図解! Git & GitHubのツボとコツがゼッタイにわかる本
ソフトウェア開発では欠かすことのできないGit、GitHub。
これからGit、GitHubを使いたいという入門者の方でも、実際に手を動かしながら使い方を学べます。
C自作の鉄則!2023 (日経BPパソコンベストムック)
メーカー製のパソコンはスペックが中途半端で、自分が本当に欲しい機種がない――。そう思っている人には、ぜひ自作パソコンをお薦めします。自作パソコンのパーツは進化が速く、しかも驚くほど種類が豊富。価格も性能も、幅広く用意されているため、満足度100%の“自分だけの1台”を手に入れることができます。
Interface 2023年6月号
特集:第1部 フィルタ設計 基礎の基礎/
第2部 係数アプリや波形観測アプリで合点!FIR&IIRフィルタ作り/
第3部 配布プリント基板で体験!マイコンで動くフィルタ作り
日経Linux 2023年5月号
【特集 1】 AI時代の最強フリーソフト ~ 25のやりたいを実現!
【特集 2】 AWS、Azureのうまみを無料で体感!面倒なことはクラウドに任せよう
【特集 3】 新しいRaspberry Pi Cameraで遊んでみよう
【特集 4】 Linuxで旧型PCを復活! 1kg切るモバイルPCを「ChromeOS Flex」でChromebook化
ラズパイマガジン2022年秋号
特集:5大人気ボード 電子工作超入門
「半導体不足で在庫が不足し、電子工作のボードがなかなか買えない…」。そんな今にふさわしい特集を企画しました。5種の人気ボードにすべて対応した電子工作の入門特集です。「GPIO」や「I2C」を使った電子パーツの制御方法は、どのボードでも同じです。手に入れられたボードを使って、今こそ電子工作を始めましょう。
地方で稼ぐ! ITエンジニアのすすめ
学歴、理系の知識、専門スキル……全部なくてもITエンジニアになれる!
地方でも高収入でやりがいをもって働ける!ITエンジニアの魅力を一挙大公開
Raspberry Piのはじめ方2022
本書は、ラズパイやPicoの買い方やインストール、初期設定といった基本から、サーバー、電子工作、IoT、AIといったラズパイならではの活用方法まで、1冊でお届けします。
ラズパイをこれから始める方向けに、全36ページの入門マンガ「女子高生とラズベリーパイ」も巻末に掲載。これを読むだけでラズパイがどんなものなのか、すぐに分かって触れるようになります。
ハッカーの学校 IoTハッキングの教科書
生活にとけこみ、家電機器を便利にするIoT技術。
Webカメラなど、便利の裏側に潜むセキュリティの危険性をハッキングで検証。
専門家がパケットキャプチャからハードウェアハッキングまで、その攻撃と防御を徹底解説。
本書は2018年7月に刊行された「ハッカーの学校IoTハッキングの教科書」に一部修正を加えた第2版です。
攻撃手法を学んで防御せよ! 押さえておくべきIoTハッキング
本書は、経済産業省から2021年4月にリリースされた、IoTセキュリティを対象とした『機器のサイバーセキュリティ確保のためのセキュリティ検証の手引き』の『別冊2 機器メーカに向けた脅威分析及びセキュリティ検証の解説書』をもとに、IoT機器の開発者や品質保証の担当者が、攻撃者の視点に立ってセキュリティ検証を実践するための手法を、事例とともに詳細に解説しました。
ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS…
全WEB媒体で効果バツグン!
カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術
プログラマーは世界をどう見ているのか 西村博之著
イーロン・マスク(テスラ)、ジェフ・べゾス(Amazon)、ラリー・ペイジ(Google)…etc.
世界のトップはなぜプログラマーなのか?
ニーア オートマタ PLAY ARTS改 <ヨルハ 二号 B型 DX版> PVC製 塗装済み可動フィギュア
「NieR:Automata」より、ヨルハ二号B型こと2BがPLAY ARTS改に新たに登場!
高級感の感じられるコスチュームや髪の質感、洗練されたボディバランス、細かなデティールに至るまでこだわり抜かれた逸品。
DX版には通常版のラインナップに加え2Bの随行支援ユニット ポッド042などをはじめ“純白の美しい太刀"白の約定やエフェクトパーツ、自爆モードを再現できる換装用ボディパーツ、シーンに合わせて変えられる顔パーツ2種も付属する豪華な仕様に。
作中のあらゆるシーンを再現することが可能なファン必見の一品となっている。
Newtonライト2.0 ベイズ統計
ベイズ統計は,結果から原因を推定する統計学です。AIや医療などの幅広い分野で応用されています。その基礎となるのは18世紀に考えだされた「ベイズの定理」です。
この本では,ベイズ統計学のきほんをやさしく紹介していきます。
白光(HAKKO) ダイヤル式温度制御はんだ吸取器 ハンディタイプ FR301-81
無水エタノールP 500mlx2個パック(掃除)
ケイバ(KEIBA) マイクロニッパー MN-A04
サンハヤト SAD-101 ニューブレッドボード
白光(HAKKO) HEXSOL 巻はんだ 精密プリント基板用 150g FS402-02
[Amazon限定ブランド]【指定第2類医薬品】PHARMA CHOICE 解熱鎮痛薬 解熱鎮痛錠IP 100錠
|