HOME | Raspberry Pi | ビジネス書籍紹介 | 2026-02-21 (Sat) Today's Access : 385 Total : 1297191. Since 10 Sep. 2019

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プロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
2022.05.27 まずはロボットカーでお勉強
2022.06.10 第1回テスト環境構築
2022.07.02 第2回テレメトリ通信
2024.06.23 第3回 機体制御 雑談
2024.07.23 第4回 慣性センサ
2025.02.22 第5回 自作シリアル・プロポ
2025.03.10 簡易二足歩行ロボット
2025.04.24 第6回 自作TELNET・プロポ
2025.10.23 M5STACK BugC

たいていのことは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®.