I am controlling a vehicle, I call it a rover, via Xbee series 1 wifi modules. I have a control box with 2 thumb joysticks sending the rover's servo position. I also have a communications check to make sure the rover is not outside of the wifi range. All that is I send the millis() value to the rover. The rover reads the value and if it stays the same I've lost communications, the rover stops
In the rover I have a Xbee series one connected to Serial1 on a mega. I use the Serial port, serial not serial1, just to display data on the serial monitor. I'm also trying to have a GPS module on the rover. I got the GPS monitor from Adafruit and have used thier example successfully to read the GPS. This I've added to my code. The GPS module is connected to serial2. The baud rates are set as
Serial 115200 to serial monitor
Serial1 9600 to Xbee
Serial2 9600 to GPS
The problem is if I set serial to 115200 the communications value I'm reading from serial1 is affected but if I set serial to 9600 it is not. My assumption, and this is probably the problem, is that one should not affect the other. Does each serial port have it's own buffer?
Here is my code, the line in setup just above where it says "Rover GPS Program Started!" is the line I have to comment out to make it work.
Thanks
John
// Rover controlled by Wifi with GPS and Compass
// add Libraries
#include <Servo.h>
#include <LiquidCrystal.h>
#include <Adafruit_GPS.h>
// temporary array for parsing data from controller
const byte numChars = 64;
char receivedChars[numChars];
char tempChars[numChars];
// variables to hold the parsed data from controller
int Throttle_Ref = 0;
int Steering_Ref = 0;
int ThrottleOutValue =0;
int SteeringOutValue =0;
unsigned long Comm_Time = 0;
unsigned long Comm_Time_2 =0;
int Comm_Delay_Time = 1000;
int index = 0;
boolean newData = false;
// Assign channel out pins
const int Throttle_OUT_PIN = 8;
const int Steering_OUT_PIN = 7;
// GPS hardwired serial port
#define GPSSerial Serial2
Adafruit_GPS GPS(&GPSSerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO false
// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
Servo servoThrottle;
Servo servoSteering;
// initialize the lcd library with the numbers of the interface pins
LiquidCrystal lcd(33, 34, 35, 36, 37, 38);
// Variables to convert GPS NMEA values to signed degrees
uint32_t timer = millis();
float deg; //Will hold positin data in simple degree format
float degWhole; //Variable for the whole part of position
float degDec; //Variable for the decimal part of degree
float E_Long; // Google Earth format of longitude
float E_Lat; // Google Earth format of latitude
//============
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
// Define pin mode
servoThrottle.attach(Throttle_OUT_PIN);
servoSteering.attach(Steering_OUT_PIN);
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
// also spit it out
// Serial.begin(115200);
Serial.println("Rover GPS Program Started!");
// 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
GPS.begin(9600);
// This line turns on RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// Set the update rate
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
delay(1000); // Allow GPS to setup
} // end void setup
//============
void loop() {
// call GPS subrouine
// GPS_Control();
// Read data from controller
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(); // Split data into separate variables
newData = false;
}
showParsedData(); // Send data to serial monitor
// Clear Serial Buffer
while (Serial.available() > 0) {
Serial.read();
}
// Confirm communications to controller
// Send reference value to servos
if (index < 20){ // index to count scans
index++;
}
if (index >= 20){ // every 20 scans set Comm_Time to Comm_Time_2
Comm_Time_2 = Comm_Time;
index = 0;
}
if ((Comm_Time != Comm_Time_2)&& index > 3){ // If comm not lost set servo refences from controller
servoThrottle.write(Throttle_Ref);
servoSteering.write(Steering_Ref);
}
if ((Comm_Time == Comm_Time_2)&& index > 3) { // if comm is lost set throlle to stop, steering to one side
Throttle_Ref = 90;
Steering_Ref = 0;
servoThrottle.write(Throttle_Ref);
servoSteering.write(Steering_Ref);
}
// Covert Latitude and Longitude to Google earth Format, signed degrees
degWhole=float(int(GPS.longitude/100)); //gives me the whole degree part of Longitude
degDec = (GPS.longitude - degWhole*100)/60; //give me fractional part of longitude
deg = degWhole + degDec; //Gives complete correct decimal form of Longitude degrees
if (GPS.lon=='W') { //If you are in Western Hemisphere, longitude degrees should be negative
deg= (-1)*deg;
} // end if
E_Long = deg; // Google Earth Longitude
degWhole=float(int(GPS.latitude/100)); //gives me the whole degree part of latitude
degDec = (GPS.latitude - degWhole*100)/60; //give me fractional part of latitude
deg = degWhole + degDec; //Gives complete correct decimal form of latitude degrees
if (GPS.lat=='S') { //If you are in Southern hemisphere latitude should be negative
deg= (-1)*deg;
} // end if
E_Lat = deg; // Google Earth Latitude
// ******* Print to LCD display *******
lcd.setCursor(0, 0);
lcd.print("Lat = ");
lcd.print(E_Lat, 6); // lcd.print(GPS.lat);
lcd.setCursor(0, 1);
lcd.print("Lon = ");
lcd.print(E_Long, 6); // lcd.print(GPS.lon);
} // end of loop
//============
void recvWithStartEndMarkers() { // reads variables from controller
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial1.available() > 0 && newData == false) {
rc = Serial1.read();
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
Throttle_Ref = atoi(strtokIndx); // Throttle reference
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
Steering_Ref = atoi(strtokIndx); // Steering reference
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
Comm_Time = atoi(strtokIndx); // Watch Dog Communication Pulse
}
//============
void showParsedData() { // print to serial monitor
// uncomment to debig data from controller
Serial.print("Throttle Reference ");
Serial.print(Throttle_Ref);
Serial.print("\t Steering Reference ");
Serial.print(Steering_Ref);
Serial.print("\t Comm Time ");
Serial.print(Comm_Time);
Serial.print("\t Comm Pulse 2 ");
Serial.print(Comm_Time_2);
Serial.print("\t Index ");
Serial.println(index);
}