I am a novice Arduino enthusiast. Learning as I go.
I am working on a simple project of a Bluetooth controlled tank. I am having issues with serial transfer of the data from the transmitter to the tank (receiver). I have read the Serial tutorial that many people suggest. It is very good, but I guess I am not applying it correctly or something. Anyway, maybe someone can point my obvious mistake.
I am using two Arduino Nano. One for the transmitter and the other for the receiver. On the transmitter side I am using two joysticks to generate the direction and throttle data and the output to be sent via serial are two integers that control the speed of the left track (speedL) and the right track (speedR). I am trying to send these using two HC-05s set as slave (receiver) and master (transmitter). These two I have verified are connected together as I followed the pairing process and the light blinking is the right pattern for paired.
The receiver has two DC motors connected through an Adafruit tb6612 driver. The motor/driver connection works well as I have tested via serial form the computer when connected directly.
To minimize the length of this post, I have written a test code just to troubleshoot receiving the data through BT so I will post that one below. Once I figure that one I can use that in my more length receiver code
My issues have to do (I guess) with how I am sending and receiving the data with both codes (transmitter/receiver). I will post them below and hopefully someone will see the obvious mistake.
Transmitter Code
#include <SoftwareSerial.h>
int throttle; //mapped variable of y axis on left joystick
int speedL; // Resultant speed for left motor
int speedR; // Resultant speed for right motor
int yRight; // Measured input from y-axis on right joystick
int xRight; // Measured input from x-axis on right joystick
int yLeft; // Measured input from y-axis on left joystick
int MFactor; // mapped variable for direction input - yRight. Can only be -1 (rev), 0 (static) and 1 (forward)
long LSFactor; //mapped variable for motor speed and direction multiplier to achieve left turn
long RSFactor; //mapped variable for motor speed and direction multiplier to achieve right turn
// pin definition for joystick inputs
#define yLpin A1
#define yRpin A2
#define xRpin A3
SoftwareSerial Myserial(4, 3); // RX | TX
void setup()
{
Myserial.begin(9600); // Bluetooth serial communication
Serial.begin(9600);
Serial.println("Code starting");
}
void loop() {
yRight = analogRead(A2); // Read Joysticks X-axis
yLeft = analogRead(A1); // Read Joysticks Y-axis
xRight = analogRead(A3); // Read Joysticks Y-axis
//control logic with central buffer
//left joystick controlling throttle intensity
if (yLeft >= 530)
{
throttle=0;
}
else
{
throttle = map(yLeft, 520, 0, 0, 255); //only using center-top range of left y-axis to control throttle
}
//right throttle controlling direction (y-axis) and moderation of motor intensity to achieve turning
//y-axis right joystick controlling direction
if ((yRight < 530)&&(yRight>500))
{
MFactor=0; //no movement
}
else if (yRight <= 500)
{
MFactor=1; //forward
}
else
{
MFactor=-1; //backward
}
// x-axis right joystick controlling speed moderation for both motors based on turning input.
//Using 100 range to get around limitation of map function of ony using integer math. At the resutant equation will divide by 100 to
//achieve fractional input as required
if ((xRight < 540)&&(xRight>490)) //defines a central buffer box where no turning is inferred to account for joystick variability around center
{
LSFactor=100; //100 means no change on direction
RSFactor=100;
}
else if (xRight>=540) //joystick tilted right - right turning intensity based on how much the joystick is tilted
{
LSFactor=100; //no change on left motor
RSFactor=map(xRight, 540, 1023, 100, -100); //mapped right motor factor from all forward (100) to all backward (-100 achieves turn in place)
}
else // any other condition means left turn
{
RSFactor=100; //no change on right
LSFactor=map(xRight, 0, 490, -100, 100); //mapped left motor factor from all forward (100) to all backward (-100 achieves turn in place)
}
//Resultand speed calculation based on throttle intensity (left joystick) and moderation factors
//(Mfactor - forward/backward) and turning factors (LSFactor - left turn, RSFactor - right turn)
//dividing by 100 to return to fractional input by the turning factors
speedL = throttle*MFactor*LSFactor/100;
speedR = throttle*MFactor*RSFactor/100;
/* Serial output when connected to PC for debugging
Serial.print(speedL);
Serial.print(" ");
Serial.println(speedR);
delay(50);
*/
//Bluetooth transfer
sendBluetoothData (speedL, speedR);
delay (200);
}
void sendBluetoothData(int speedL, int speedR) {
if (speedL <-255 || speedL > 255){
return; // invalid data range
}
else if (speedR <-255 || speedR > 255){
return; // invalid data range
}
Myserial.write('<');
Myserial.write(speedL);
Myserial.write(',');
Myserial.write(speedR);
Myserial.write('>');
}
Test Receiver Code
#include<SoftwareSerial.h>
SoftwareSerial Myserial(3, 4);//Rx, Tx
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
int SpeedL = 0;
int SpeedR = 0;
boolean newData = false;
int dataNumber = 0; // new for this version
void setup() {
// put your setup code here, to run once:
Myserial.begin(9600); // Bluetooth serial communication
Serial.begin(9600);
Serial.print("Test Code");
Serial.println();
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
Serial.println("We have serial");
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
SpeedL = atoi(strtokIndx);
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
SpeedR = atoi(strtokIndx); // convert this part to an integer
}
//============
void showParsedData() {
Serial.print("SpeedL ");
Serial.println(SpeedL);
Serial.print("SpeedR ");
Serial.println(SpeedR);
}
Thanks in advance for the help.