728x90
M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.
출처
- Take Control Over Lego Power Functions - Hackster.io
- Tutorial: Controlling Power Functions trains – Arduino Lego Trains
- 몽상가 :: Google Voice Kit(RPI) 으로 레고 모터 제어 #3: Lego Servo제어
- Arduino-LPF/ at master · thordreier/Arduino-LPF · GitHub
- 기술 여행자 (ArsViator): ESP32 PWM 사용하기
- M5-ProductExampleCodes/Module/LEGO_PLUS/firmware_328p/m5_lego at master · m5stack/M5-ProductExampleCodes · GitHub
M5Stack : Lego RC CAR (BLE 통신)
배선
M5Stack 아두이노 소스 : BLE 서버, L298N 모터 드라이버 모듈 제어
M5Stack 아두이노 소스
#include <M5Stack.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
// Motor A
int motor1Pin1 = 21;
int motor1Pin2 = 22;
int enable1Pin = 26;
// Motor B
int motor1Pin1B = 16;
int motor1Pin2B = 17;
//
int defaultDutyCycle = 210;
// Setting PWM properties
const int freq = 10000;
const int pwmChannel = 0;
const int resolution = 8;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
void clearLCD() {
M5.Lcd.clear(BLACK);
M5.Lcd.setCursor(0, 0);
}
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
clearLCD();
M5.Lcd.println("connect");
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
clearLCD();
M5.Lcd.println("disconnect");
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onRead(BLECharacteristic *pCharacteristic) {
M5.Lcd.println("read");
pCharacteristic->setValue("Hello World!");
}
// BLE 클라이언트로 명령르 받았을때 호출
void onWrite(BLECharacteristic *pCharacteristic) {
M5.Lcd.println("write");
std::string value = pCharacteristic->getValue();
// 정지명령을 받았을 때
if (value.at(0) == 'S') {
stopMotor();
return;
}
// 속도값 추출
int dutyCycle = defaultDutyCycle;
//M5.Lcd.println(value.substr(2).c_str());
if(sscanf(value.substr(2).c_str(), "%d", &dutyCycle) != 1)
dutyCycle = defaultDutyCycle;
if (value.at(0) == 'F') {
forwardMotor(dutyCycle);
} else if (value.at(0) == 'B') {
backwardMotor(dutyCycle);
}
if (value.at(1) == 'C') {
centerMotor();
} else if (value.at(1) == 'L') {
leftMotor();
} else if (value.at(1) == 'R') {
rightMotor();
}
M5.Lcd.println(value.c_str());
}
};
// 뒤바뀌가 정지하고, 앞바퀴가 가운데로 설정
void stopMotor() {
// Stop the DC motor
Serial.println("Motor stopped");
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
centerMotor();
}
// 앞바퀴가 가운데로 설정
void centerMotor() {
// Stop the DC motor
Serial.println("Motor center");
digitalWrite(motor1Pin1B, LOW);
digitalWrite(motor1Pin2B, LOW);
}
// 뒤바뀌가 정방향으로 설정
void forwardMotor(int dutyCycle) {
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
ledcWrite(pwmChannel, dutyCycle);
}
// 뒤바뀌가 역방향으로 설정
void backwardMotor(int dutyCycle) {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, HIGH);
ledcWrite(pwmChannel, dutyCycle);
}
// 앞바뀌가 오른쪽으로 설정
void rightMotor() {
digitalWrite(motor1Pin1B, LOW);
digitalWrite(motor1Pin2B, HIGH);
}
// 앞바뀌가 왼쪽으로 설정
void leftMotor() {
digitalWrite(motor1Pin1B, HIGH);
digitalWrite(motor1Pin2B, LOW);
}
void setup() {
Serial.begin(115200);
M5.begin();
M5.setWakeupButton(BUTTON_A_PIN);
M5.Lcd.setTextSize(2);
M5.Lcd.println("BLE start.");
m5.Speaker.mute();
// sets the pins as outputs:
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(enable1Pin, OUTPUT);
pinMode(motor1Pin1B, OUTPUT);
pinMode(motor1Pin2B, OUTPUT);
// configure LED PWM functionalitites
ledcSetup(pwmChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(enable1Pin, pwmChannel);
BLEDevice::init("m5-stack");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->addDescriptor(new BLE2902());
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
if(M5.BtnA.wasPressed()) {
M5.powerOFF();
} else if(M5.BtnC.wasPressed()) {
clearLCD();
}
if (deviceConnected) {
if(M5.BtnB.wasPressed()) {
M5.Lcd.println("Button B pressed!");
pCharacteristic->setValue("Button B pressed!");
pCharacteristic->notify();
}
}
M5.update();
}
App Inventor : 안드로이드 어플 제작
App Inventor 디자인
App Inventor - 전역변수 선언 (BLE 서비스, 특성 UUID은 미리 설정)
App Inventor - BLE로 문자열 전달하는 함수 만들기 (메시지를 받아서 BLE 모듈로 호출)
App Inventor - 버튼을 누르고 있는데 터치 다운, 누리고 있다가 띄었을 때 터치 업 이벤트 발생시 위에서 구현 한 함수 호출
App Inventor 블럭 소스
실행 영상
M5Stack 물품 구매는 <네이버 검색/쇼핑에서 M5StackKorea>를 검색하시거나, M5Stack 공식 파트너인 <위즈네트 쇼핑몰: Shop.wiznet.io> 으로 접속하세요.
728x90