티스토리 뷰

OS/M5Stack

M5Stack : Lego RC CAR (BLE 통신)

파란크리스마스 2019. 7. 21. 23:26
728x90

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

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> 으로 접속하세요.

댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함