Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Adam Mansour
Created December 18, 2015

Final Remote Controlled Car with Revised Chassis

Showcase (no instructions)34
Final Remote Controlled Car with Revised Chassis

Story

Read more

Schematics

Schematic

Code

Control Code

Arduino
#include <SPI.h>
#include "Adafruit_BLE_UART.h"

// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2     // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 9

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);


bool leftButtonDown = false;
bool rightButtonDown = false;
bool forwardButtonDown = false;
bool backwardButtonDown = false;



const int motor1Pin = 7;    // H-bridge leg 1 (pin 2, 1A)
const int motor2Pin = 6;    // H-bridge leg 2 (pin 7, 2A)
const int motor3Pin = 5;    // H-bridge leg 3 (pin 10, 3A)
const int motor4Pin = 4;    // H-bridge leg 4 (pin 15, 4A)


/**************************************************************************/
/*!
    Configure the Arduino and start advertising with the radio
*/
/**************************************************************************/

void backward() {


  digitalWrite(motor1Pin, HIGH);   // set leg 1A of the H-bridge HIGH
  digitalWrite(motor2Pin, LOW);  // set leg 2A of the H-bridge low
  digitalWrite(motor3Pin, HIGH);   // set leg 1B of the H-bridge high
  digitalWrite(motor4Pin, LOW);  // set leg 2B of the H-bridge low
  Serial.println("backward");
}


void forward() {
  digitalWrite(motor1Pin, LOW);  // set leg 1A of the H-bridge LOW
  digitalWrite(motor2Pin, HIGH);   // set leg 2A of the H-bridge high
  digitalWrite(motor3Pin, LOW);   // set leg 1B of the H-bridge low
  digitalWrite(motor4Pin, HIGH);  // set leg 2B of the H-bridge high
  Serial.println("forward");
}

void left() {

  digitalWrite(motor1Pin, LOW);  // set leg 1A of the H-bridge low
  digitalWrite(motor2Pin, LOW);   // set leg 2A of the H-bridge low
  digitalWrite(motor3Pin, HIGH);   // set leg 1B of the H-bridge high
  digitalWrite(motor4Pin, LOW);  // set leg 2B of the H-bridge low
  Serial.println("left");
}


void right() {
  digitalWrite(motor1Pin, HIGH);  // set leg 1A of the H-bridge high
  digitalWrite(motor2Pin, LOW);   // set leg 2A of the H-bridge low
  digitalWrite(motor3Pin, LOW);  // set leg 1A of the H-bridge low
  digitalWrite(motor4Pin, LOW);   // set leg 2A of the H-bridge low
  Serial.println("right");
}

void station()  {
  
  digitalWrite(motor1Pin, LOW);  // set leg 1A of the H-bridge low
  digitalWrite(motor2Pin, LOW);   // set leg 2A of the H-bridge low
  digitalWrite(motor3Pin, LOW);  // set leg 1A of the H-bridge low
  digitalWrite(motor4Pin, LOW);   // set leg 2A of the H-bridge low
  Serial.println("station");
}

void setup(void)
{ 
  Serial.begin(9600);
  while(!Serial); // Leonardo/Micro should wait for serial init
  Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Print echo demo"));

  // BTLEserial.setDeviceName("NEWNAME"); /* 7 characters max! */

  BTLEserial.begin();

//  pinMode(2, INPUT_PULLUP);
//  pinMode(9, INPUT_PULLUP);
//  pinMode(10, INPUT_PULLUP);
//  pinMode(11, INPUT_PULLUP);
//  pinMode(12, INPUT_PULLUP);
//  pinMode(13, INPUT_PULLUP);
//  // set all the other pins you're using as outputs:
//  
//  pinMode(motor1Pin, OUTPUT);
//  pinMode(motor2Pin, OUTPUT);
//  pinMode(motor3Pin, OUTPUT);
//  pinMode(motor4Pin, OUTPUT);
}

/**************************************************************************/
/*!
    Constantly checks for new events on the nRF8001
*/
/**************************************************************************/
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

char leftButtonDownSignal[] = { '!', 'B', '7', '1', '4' };
char leftButtonUpSignal[] = { '!', 'B', '7', '0', '5' };

char rightButtonDownSignal[] = { '!', 'B', '8', '1', '3' };
char rightButtonUpSignal[] = { '!', 'B', '8', '0', '4' };

char forwardButtonDownSignal[] = { '!', 'B', '5', '1', '6' };
char forwardButtonUpSignal[] = { '!', 'B', '5', '0', '7' };

char backwardButtonDownSignal[] = { '!', 'B', '6', '1', '5' };
char backwardButtonUpSignal[] = { '!', 'B', '6', '0', '6' };



void readSignal(char signalBytes[]) {
  for (int i = 0; i < 5; i++) {
    signalBytes[i] = BTLEserial.read();
  }
}

bool signalsEqual(char signal1[], char signal2[]) {
  for (int i = 0; i < 5; i++) {
    if (signal1[i] != signal2[i]) {
      return false;
    }
  }
  return true;
}


void loop()
{
  // Tell the nRF8001 to do whatever it should be working on.
  BTLEserial.pollACI();

  // Ask what is our current status
  aci_evt_opcode_t status = BTLEserial.getState();
  // If the status changed....
  if (status != laststatus) {
    // print it out!
    if (status == ACI_EVT_DEVICE_STARTED) {
        Serial.println(F("* Advertising started"));
    }
    if (status == ACI_EVT_CONNECTED) {
        Serial.println(F("* Connected!"));
    }
    if (status == ACI_EVT_DISCONNECTED) {
        Serial.println(F("* Disconnected or advertising timed out"));
    }
    // OK set the last status change to this one
    laststatus = status;
  }

  if (status == ACI_EVT_CONNECTED) {
    // Lets see if there's any data for us!
    if (BTLEserial.available()) {
      Serial.print("* "); Serial.print(BTLEserial.available()); Serial.println(F(" bytes available from BTLE"));
    }
    // OK while we still have something to read, get a character and print it out
    char signalBytes[5];
    if (BTLEserial.available() >= 5) {
        readSignal(signalBytes);
        
        for (int i = 0; i < 5; i++) {
          Serial.print(signalBytes [i]);
        }
        if (signalsEqual(signalBytes, leftButtonDownSignal)) {
          leftButtonDown = true;
        }
        if (signalsEqual(signalBytes, rightButtonDownSignal)) {
          rightButtonDown = true;
        }
        if (signalsEqual(signalBytes, forwardButtonDownSignal)) {
          forwardButtonDown = true;
        }
        if (signalsEqual(signalBytes, backwardButtonDownSignal)) {
          backwardButtonDown = true;
        }
        if (signalsEqual(signalBytes, leftButtonUpSignal)) {
          leftButtonDown = false;
        }
        if (signalsEqual(signalBytes, rightButtonUpSignal)) {
          rightButtonDown = false;
        }
        if (signalsEqual(signalBytes, forwardButtonUpSignal)) {
          forwardButtonDown = false;
        }
        if (signalsEqual(signalBytes, backwardButtonUpSignal)) {
          backwardButtonDown = false;
        }
    }

    // Next up, see if we have any data to get from the Serial console

    if (Serial.available()) {
      // Read a line from Serial
      Serial.setTimeout(100); // 100 millisecond timeout
      String s = Serial.readString();

      // We need to convert the line to bytes, no more than 20 at this time
      uint8_t sendbuffer[20];
      s.getBytes(sendbuffer, 20);
      char sendbuffersize = min(20, s.length());

      Serial.print(F("\n* Sending -> \"")); Serial.print((char *)sendbuffer); Serial.println("\"");

      // write the data
      BTLEserial.write(sendbuffer, sendbuffersize);
    }

  if (forwardButtonDown && !backwardButtonDown) { //forward button are pressed
    forward();
  }
  else if (rightButtonDown && !leftButtonDown) { //right button is pressed
    right();
  }

  else if (leftButtonDown && !rightButtonDown) { //left button is pressed
    left();
  }

   else if (backwardButtonDown && !forwardButtonDown) { //backward switch is pressed
    backward();
    
  }
 else if (!backwardButtonDown && !forwardButtonDown && !leftButtonDown && !rightButtonDown) { //none are pressed
    station();
    
  }
    
  }


}

Credits

Adam Mansour

Adam Mansour

10 projects • 1 follower

Comments