출처
micro:Maqueen - BLE RC Car 제어 (App Inventor)
pulse-combined.zip
micro:Maqueen을 안드로이드 폰으로 제어하기 위해서 micro:bit는 BLE로 구현하고, 안드로이드개발은 App Inventor를 이용해서 개발했습니다.
micro:bit의 BLE 개발은 이전 게시물의 내용을 참고 하시면 됩니다.
micro:bit - BLE 서버
Maqueen 제어용 상수
#define MOTOR_M1 0
#define MOTOR_M2 1
#define MOTOR_ALL 2
#define MOTOR_CW 0x0
#define MOTOR_CCW 0x1
#define MOTOR_ADDRESSS 0x10 << 1
Maqueen 모터 제어 - 100 스피드로 앞으로 전진
char buf[]={0x00,0x0,100};
uBit.i2c.write(MOTOR_ADDRESSS, buf, 3, true);
micro:bit - main.cpp 소스
#include "MicroBit.h"
#include "MicroBitUARTService.h"
MicroBit uBit;
MicroBitUARTService *uart;
MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
#define MOTOR_M1 0
#define MOTOR_M2 1
#define MOTOR_ALL 2
#define MOTOR_CW 0x0
#define MOTOR_CCW 0x1
#define MOTOR_ADDRESSS 0x10 << 1
int connected = 0;
void motorRun(int index, char direction, char speed) {
//char buf[]={0x00,0x0,100};
//uBit.i2c.write(MOTOR_ADDRESSS, buf, 3, true);
if (index == MOTOR_M1) {
char buf[]={0x00,direction,speed};
i2c.write(MOTOR_ADDRESSS, buf, 3);
}
if (index == MOTOR_M2) {
char buf[]={0x02,direction,speed};
i2c.write(MOTOR_ADDRESSS, buf, 3);
}
if (index == MOTOR_ALL) {
char buf[]={0x00,direction,speed};
i2c.write(MOTOR_ADDRESSS, buf, 3);
buf[0] = 0x02;
i2c.write(MOTOR_ADDRESSS, buf, 3);
}
}
void motorStop(int motors) {
if (motors == MOTOR_M1) {
char buf[]={0x00,0x0,0};
i2c.write(MOTOR_ADDRESSS, buf, 3);
}
if (motors == MOTOR_M2) {
char buf[]={0x02,0x0,0};
i2c.write(MOTOR_ADDRESSS, buf, 3);
}
if (motors == MOTOR_ALL) {
char buf[]={0x00,0x0,0};
i2c.write(MOTOR_ADDRESSS, buf, 3);
buf[0] = 0x02;
i2c.write(MOTOR_ADDRESSS, buf, 3);
}
}
//
void centerMotor(char direction, char speed) {
motorRun(MOTOR_ALL, direction, speed);
}
//
void rightMotor(char direction, char speed) {
motorRun(MOTOR_M1, direction, speed);
}
//
void leftMotor(char direction, char speed) {
motorRun(MOTOR_M2, direction, speed);
}
// BLE 접속 이벤트
void onConnected(MicroBitEvent e) {
uBit.display.scroll("C");
connected = 1;
// my client will send ASCII strings terminated with the colon character
ManagedString eom(":");
while (connected == 1) {
ManagedString msg = uart->readUntil(eom);
//uBit.display.scroll(msg);
char command = msg.charAt(0);
//uBit.display.scroll(command);
if (command == 'S') {
motorStop(MOTOR_ALL);
} else {
int speed = 100;
ManagedString s = msg.substring(2, msg.length());
speed = atoi(s.toCharArray());
//uBit.display.scroll(speed);
char direction = MOTOR_CW;
if (msg.charAt(0) == 'F') {
direction = MOTOR_CW;
} else if (msg.charAt(0) == 'B') {
direction = MOTOR_CCW;
}
if (msg.charAt(1) == 'C') {
centerMotor(direction, speed);
} else if (msg.charAt(1) == 'L') {
leftMotor(direction, speed);
} else if (msg.charAt(1) == 'R') {
rightMotor(direction, speed);
}
}
}
}
// BLE 접속 해지 이벤트
void onDisconnected(MicroBitEvent e) {
uBit.display.scroll("D");
connected = 0;
motorStop(MOTOR_ALL);
}
// 메인 함수
int main() {
// micro:bit 초기화.
uBit.init();
// BLE 접속 상태 변경 리스터 등록
uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, onConnected);
uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, onDisconnected);
// Note GATT table size increased from default in MicroBitConfig.h
// #define MICROBIT_SD_GATT_TABLE_SIZE 0x500
uart = new MicroBitUARTService(*uBit.ble, 32, 32);
uBit.display.scroll("AVM");
/*
motorRun(MOTOR_ALL, MOTOR_CW, 100);
wait(3);
motorStop(MOTOR_ALL);
*/
// If main exits, there may still be other fibers running or registered event handlers etc.
// Simply release this fiber, which will mean we enter the scheduler. Worse case, we then
// sit in the idle task forever, in a power efficient sleep.
release_fiber();
}
App Inventor 소스 (안드로이드)
microbit_ble_rccar.zip
App Inventor 디자인

App Inventor 블럭

실행결과