AutoMecUA / AutoMec-AD

Autonomous RC car with the help of ROS Noetic and ML.
GNU General Public License v3.0
15 stars 2 forks source link

Create a bluetooth interface to start the car #207

Open PedroMS3 opened 1 year ago

PedroMS3 commented 1 year ago

In the competition there is time frame where the car must start moving after a bluetooth signal is sent, coincident with the greenlight a luminous signal, the purpose of this issue is to create an bluetooth interface to accomplish this objective

andrefdre commented 1 year ago

Code needed to run the Servo driver

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define ESCMIN  1000 // This is the 'minimum' pulse length count of the ESC
#define ESCMAX  1960 // This is the 'maximum' pulse length count of the ESC
#define SERVOMIN  500 // This is the 'minimum' pulse length count of the steer Servo
#define SERVOMAX  2500 // This is the 'maximum' pulse length count of the steer SErvo
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

void setup() {
  // PCA9685 board
  pwm.begin(); // Begins comunnication
  pwm.setOscillatorFrequency(26315700); // This frequency can be tuned to adjust the generated pwm wave
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

}

void loop(){
// Convert from angle to ms between 0 and 180 to the ms min and ms max
  int escms = map(90, 0, 180, ESCMIN, ESCMAX);   // scale it to use it with the servo library (value between 0 and 180)
  pwm.writeMicroseconds(ESC, escms);  // Generates the PWM wave
}
Carolf27 commented 1 year ago

We tried to move the car forward with a phone via bluetooth with this code:

#include "BluetoothSerial.h"

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define ESCMIN  1000 // This is the 'minimum' pulse length count of the ESC
#define ESCMAX  1960 // This is the 'maximum' pulse length count of the ESC
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
#define ESC 0 // Defines the chanel for the esc

//#define USE_PIN // Uncomment this to use PIN during pairing. The pin is specified on the line below
const char *pin = "1234"; // Change this to more secure PIN.
int value = 20;

String device_name = "ESP32-BT-Slave";

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

BluetoothSerial SerialBT;
String message = "";
char incomingChar;

// Initializes the pwm board generator
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

int potValue;  // value from the analog pin

void setup() {
  Serial.begin(115200);
  SerialBT.begin(device_name); //Bluetooth device name
  Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());
  //Serial.printf("The device with name \"%s\" and MAC address %s is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str(), SerialBT.getMacString()); // Use this after the MAC method is implemented
  #ifdef USE_PIN
    SerialBT.setPin(pin);
    Serial.println("Using PIN");
  #endif

   // Read received messages (LED control command)
  if (SerialBT.available()){
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n'){
      message += String(incomingChar);
    }
    else{
      message = "";
    }
    Serial.write(incomingChar);  
  }

  // PCA9685 board
  pwm.begin(); // Begins comunnication
  pwm.setOscillatorFrequency(26315700); // This frequency can be tuned to adjust the generated pwm wave
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

}

void loop() {

   // Read received messages (LED control command)
  if (SerialBT.available()){
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n'){
      message += String(incomingChar);
    }
    else{
      message = "";
    }
    Serial.write(incomingChar);  
  }

  // Check received message and control output accordingly
  if (message =="on"){
    Serial.println("ON");
     // Convert from angle to ms between 0 and 180 to the ms min and ms max
    value = 90;
    Serial.print(value);

  }
  else if (message =="off"){
    value = 0;
    Serial.println("OFF");
    Serial.print(value);

  }
  Serial.print(value);
  int escms = map(value, 0, 180, ESCMIN, ESCMAX);   // scale it to use it with the servo library (value between 0 and 180)
  pwm.writeMicroseconds(ESC, escms);  // Generates the PWM wave
  //delay(20);
}

Note: This code is not commented but @Carolf27 will do that when possible

Resultof using this code: The car responded to the "off" button.

Carolf27 commented 1 year ago

This is the code used with comments.

To run this code you need to install the BluetoothSerial and the Adafruit PWM Servo Driver Library libraries installed in Arduino IDE.

You also need to install the Serial Bluetooth Terminal app installed in your phone.

#include "BluetoothSerial.h"

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define ESCMIN  1000 // This is the 'minimum' pulse length count of the ESC
#define ESCMAX  1960 // This is the 'maximum' pulse length count of the ESC
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
#define ESC 0 // Defines the chanel for the esc

//#define USE_PIN // Uncomment this to use PIN during pairing. The pin is specified on the line below
const char *pin = "1234"; // Change this to more secure PIN.
int value = 20;

String device_name = "ESP32-BT-Slave";

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

BluetoothSerial SerialBT;
String message = "";
char incomingChar;

// Initializes the pwm board generator
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

int potValue;  // value from the analog pin

void setup() {

  Serial.begin(115200);
  // ---
  // BLUETOOTH CONNECTION
  // ---

  SerialBT.begin(device_name); //Bluetooth device name to connect in serial bluetooth terminal

  Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());

  #ifdef USE_PIN
    SerialBT.setPin(pin);
    Serial.println("Using PIN");
  #endif

  // Read received messages (LED control command)
  // Messages sent from the terminal
  if (SerialBT.available()){
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n'){
      message += String(incomingChar);
    }
    else{
      message = "";
    }
    Serial.write(incomingChar);  
  }

  // ---
  // SERVO CONNECTION
  // ---

  // PCA9685 board
  pwm.begin(); // Begins comunnication
  pwm.setOscillatorFrequency(26315700); // This frequency can be tuned to adjust the generated pwm wave
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

}

void loop() {

  // ---
  // READING INCOMING MESSAGES
  // ---

  // Read received messages (LED control command)
  // Messages sent from the terminal
  if (SerialBT.available()){
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n'){
      message += String(incomingChar);
    }
    else{
      message = "";
    }
    Serial.write(incomingChar);  
  }

  // ---
  // MOVE OR STOP THE CAR TRHOUGH BLUETOOTH MESSAGES
  // ---

  // Check received message and control output accordingly
  // In this case the received messages comes from clicking the buttons on the termminal
  // By clicking on the on ON button ESP receives a message saying "on" and with the OFF button the message receivid is "off"
  if (message =="on"){
    // if it's on we want to move the car forward
    Serial.println("ON");
    // Convert from angle to ms between 0 and 180 to the ms min and ms max
    value = 90;
    Serial.print(value);

  }
  else if (message =="off"){
    // if it's f we want to move the car to stop
    value = 50;
    Serial.println("OFF");
    Serial.print(value);

  }

  // ---
  // SET THE SERVO VALUE
  // ---

  Serial.print(value);
  int escms = map(value, 0, 180, ESCMIN, ESCMAX);   // scale it to use it with the servo library (value between 0 and 180)
  pwm.writeMicroseconds(ESC, escms);  // Generates the PWM wave
  //delay(20);
}
Carolf27 commented 1 year ago

How to run Serial Bluetootj terminal Initial page: WhatsApp Image 2023-11-08 at 15 15 52

From the initial page go to the up left corner to open the menu. Click on Devices to conect to the Esp. WhatsApp Image 2023-11-08 at 15 15 53

The device name should appear. Click on the name and begin connection. In this case the name is "ESP32-BT-Slave". WhatsApp Image 2023-11-08 at 15 15 54 (2)

Now you need to configure the buttons. We will use the M1 and M2. Make a long press on each one to open the button's configuration menu. Fill each one like this: WhatsApp Image 2023-11-08 at 15 15 54 (1) WhatsApp Image 2023-11-08 at 15 15 54

Now if you click on the buttons the message "on" and "off" will be sent to the esp so that the car moves forward or stop. You can also send messages to the arduino serial through the bar on the botton in the initial page.

Carolf27 commented 1 year ago

Code needed to run the Servo driver

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define ESCMIN  1000 // This is the 'minimum' pulse length count of the ESC
#define ESCMAX  1960 // This is the 'maximum' pulse length count of the ESC
#define SERVOMIN  500 // This is the 'minimum' pulse length count of the steer Servo
#define SERVOMAX  2500 // This is the 'maximum' pulse length count of the steer SErvo
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

void setup() {
  // PCA9685 board
  pwm.begin(); // Begins comunnication
  pwm.setOscillatorFrequency(26315700); // This frequency can be tuned to adjust the generated pwm wave
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

}

void loop(){
// Convert from angle to ms between 0 and 180 to the ms min and ms max
  int escms = map(90, 0, 180, ESCMIN, ESCMAX);   // scale it to use it with the servo library (value between 0 and 180)
  pwm.writeMicroseconds(ESC, escms);  // Generates the PWM wave
}

@andrefdre from wich file did you get this code? Because now we can make the car go forward and backwards and we want to use the steering servo to make it go left and right and i don't know what is its channel

andrefdre commented 1 year ago

I took that code from the code we have in the car. It's in the dev branch inside Prometheus_bringup

Carolf27 commented 12 months ago

After getting the car to move forward and backwards we got the car to go left and right by changing the servo dir angle. This is the code final code:

#include "BluetoothSerial.h"

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define ESCMIN  1000 // This is the 'minimum' pulse length count of the ESC
#define ESCMAX  1960 // This is the 'maximum' pulse length count of the ESC
#define SERVOMIN  500 // This is the 'minimum' pulse length count of the steer Servo
#define SERVOMAX  2500 // This is the 'maximum' pulse length count of the steer SErvo
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
#define ESC 0 // Defines the chanel for the esc
#define dir 1 // Defines the channel of the steer servo

//#define USE_PIN // Uncomment this to use PIN during pairing. The pin is specified on the line below
const char *pin = "1234"; // Change this to more secure PIN.
int value = 90;
int direction = 90;

String device_name = "ESP32-BT-Slave";

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it                                                                                                       
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

BluetoothSerial SerialBT;
String message = "";
char incomingChar;

// Initializes the pwm board generator
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

int potValue;  // value from the analog pin

void setup() {

  Serial.begin(115200);
  // ---
  // BLUETOOTH CONNECTION
  // ---

  SerialBT.begin(device_name); //Bluetooth device name to connect in serial bluetooth terminal

  Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());

  #ifdef USE_PIN
    SerialBT.setPin(pin);
    Serial.println("Using PIN");
  #endif

  // Read received messages (LED control command)
  // Messages sent from the terminal
  if (SerialBT.available()){
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n'){
      message += String(incomingChar);
    }
    else{
      message = "";
    }
    Serial.write(incomingChar);  
  }

  // ---
  // SERVO CONNECTION
  // ---

  // PCA9685 board
  pwm.begin(); // Begins comunnication
  pwm.setOscillatorFrequency(26315700); // This frequency can be tuned to adjust the generated pwm wave
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

}

void loop() {

  // ---
  // READING INCOMING MESSAGES
  // ---

  // Read received messages (LED control command)
  // Messages sent from the terminal
  if (SerialBT.available()){
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n'){
      message += String(incomingChar);
    }
    else{
      message = "";
    }
    Serial.write(incomingChar);  
  }

  // ---
  // MOVE OR STOP THE CAR TRHOUGH BLUETOOTH MESSAGES
  // ---

  // Check received message and control output accordingly
  // In this case the received messages comes from clicking the buttons on the termminal
  // By clicking on the on ON button ESP receives a message saying "on" and with the OFF button the message receivid is "off"
  if (message =="off"){
    // if it's on we want to move the car forward
    // Convert from angle to ms between 0 and 180 to the ms min and ms max
    value = 90;

  }
  else if (message =="speed"){
    // if it's f we want to move the car to stop
    value = value + 10;

  }
  else if (message =="slow"){
    // if it's f we want to move the car to stop
    value = value - 10;

  }
  else if (message =="right"){
    // if it's f we want to move the car to stop
    direction = direction - 30;

  }
  else if (message =="left"){
    // if it's f we want to move the car to stop
    direction = direction + 30;

  }

  // ---
  // SET THE SERVO VALUE
  // ---

  Serial.print(value);
  int escms = map(value, 0, 180, ESCMIN, ESCMAX);   // scale it to use it with the servo library (value between 0 and 180)
  pwm.writeMicroseconds(ESC, escms);  // Generates the PWM wave
  //delay(20);

   // ---
  // SET THE SERVO DIRECTION
  // ---

  int dirms = map(direction, 0, 180, SERVOMIN, SERVOMAX);   // scale it to use it with the servo library (value between 0 and 180)
  pwm.writeMicroseconds(dir, dirms);
}

With this code we can speed up and slow down the car, we can make it turn to left and right and we can make it stop, with a smartphone via bluetooth.