I have an arduino uno hooked up as a slave to an arduino mega. The uno's job is to collect data from sensors and send it in csv string values. The format is something like "A01,706". Here is the tutorial I used as a basis.
Literally, this is the code for the slave arduino currently
The master logs from an OBD2 system which can be slow so the main loop has an idle subset of code for 20ms
while (millis() - start < OBD_MIN_INTERVAL) {
obd.dataIdleLoop();
}
The idle loop calls code to log an accelerometer and GPS unit. I added in the following code (from the tutorial mentioned above) to read from the slave
If I put this code in an isolated loop outside the rest of my code, I receive the data from the slave properly. But put in my code posted above I get something like "A01,93A0<93A3"
I'm getting that something is missing characters and it's just reading things out of order, but I'm not sure why. Does anyone have insight that could help me?
The code is pretty badly organized and things are very messy. I've attached it below. It's based on the freematics.com obd2 logger that I've added extra functionality. I'm trying to get this second arduino to externally grab data and send it to be logged with the main arduino mega.
There is a lot of code and, in particular, your loop() function is very long which makes it hard to figure out.
You have not told us where, in that program, this gets produced
But put in my code posted above I get something like "A01,93A0<93A3"
It looks to me like the recvWithStartEndMarkers() function missed a closing > and that could just as easily be due to an error in the program that is sending the data.
If the problem is within the posted program it is likely due to the fact that the recvWith... function is not called often enough to empty the Serial Input buffer and data has been lost by the USART.
Edit to add ...
Using a much higher baud rate might help (assuming an individual message is less than 64 bytes) because a single call to recvWith... would be likely to find more data waiting for it. 500,000 baud should work fine if you are using HardwareSerial on the Uno. If using SoftwareSerial on the Uno I believe 38400 baud should work.
Where the bad data is produced? you mean the slave or the bad string is displayed? The first code snippet in my original post is literally the code in the slave arduino. The only other code is the 9600 baud rate in the setup.
The bad data is displayed via "lcd.print(receivedChars);" which is the print to a UTFT display.
I could definitely see the possibility of the receive function not being called enough. But wouldn't a high baud rate cause more issues not fewer? I think I'm missing something very basic about this concept. Wouldn't the higher rate cause the buffer to fill faster? My code wouldn't get it to it any faster.
protomor:
I know. I really need to clean stuff up >_<
Where the bad data is produced? you mean the slave or the bad string is displayed? The first code snippet in my original post is literally the code in the slave arduino. The only other code is the 9600 baud rate in the setup.
The bad data is displayed via "lcd.print(receivedChars);" which is the print to a UTFT display.
I could definitely see the possibility of the receive function not being called enough. But wouldn't a high baud rate cause more issues not fewer? I think I'm missing something very basic about this concept. Wouldn't the higher rate cause the buffer to fill faster? My code wouldn't get it to it any faster.
The "baud rate" is the bit rate, not the character rate. When using async, the character rate is controlled by the sender. The sender may use all the available time to send characters, or may use only part of the available time.
Although, now that I look at it, I'm just tossing the whole character array into the print function with no thought of the index for the terminating character. But I'm not entirely sure that would be an issue.
protomor:
The first code snippet in my original post is literally the code in the slave arduino.
That code will send so much data that it will completely overwhelm the Serial system - it will probably block its own output as well as the input on the Mega. At least for testing add delay(500); into loop().
And make that change before you start experimenting with any other part of the problem.
Also I am not familiar with sprintf(). Will it put a terminating '\0' after the '>' ?
I just make output with a series of prints like
I think it makes more sense now. The serial buffer gets filled independent of any of my code. So if too much gets pushed to it, it'll overflow and start spitting out junk. I raised the baud rate to 38400 and put in a 50ms delay between loops and things seem to be mostly resolved.
The incoming buffer will fill, causing incoming data to be discarded. That does not mean that anything is "spitting out junk". It means that the data read from the buffer will be incomplete, which could look like junk.
I raised the baud rate to 38400
That means that data will come in faster.
and put in a 50ms delay between loops
That means that it will take longer to get around to reading data.
It appears that you have made the situation worse, not better.
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
const int potPin = 2; // select the input pin for the potentiometer
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
//Serial.begin(38400);
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
int val = 0; // variable to store the value coming from the sensor
void loop() {
char buf[32];
val = analogRead(potPin); // read the value from the sensor
//sprintf(buf, "<A01,%d>", val);
//Serial.println(buf);
Serial.print("<A01,");
Serial.print(val);
Serial.println('>');
Serial.println("<B03,100>");
delay(50);
}
Interestingly enough, the log file looks perfect except for one blip on first connection. Then the rest are fine. (the first number is ms since last update)
But if I'm still doing this wrong, I'd like to fix it and do it properly.
Well, I read back through the whole thread. I couldn't find anywhere where anyone said "Post some of your code". Everyone said post ALL of your code.
It looks to me like you are doing something early on that takes a bunch of time, and the serial buffer has overflowed. After that, you appear to be reading serial data fast enough.
I did post all of my code. It's in post #3 for the master. All of my slave code is in post #13. Do you want all the library code?
I don't get why all of the code would be slow 2 seconds after load up and then be fine. If it was just slow loading at first, that would make sense and would easily be fixable. I'm literally piggy backing on the GPS logging logic since I know that works.
protomor:
But it's not exactly on startup. It's a few lines in. I just added an exception for anything with a duplicate start character.
I don't know exactly what you mean by the first 2 sentences. Perhaps it depends on which unit starts first? I meant the start of communication rather than the start of the program.
But from the last sentence it sounds like you have a satisfactory solution.