Hi, I try to read data from the UART.
When I hook up my logic analyzer I get the expected Responses, but when I read this Response with my arduino, I only get the first, second and last Byte of the ~ 20 Byte Long Response.
Is this due to the fact I dont read fast enought from the UART?
int MDBSerial::read()
{
unsigned char resh, resl;
int count = 0;
resh = UCSR1B;
resl = UDR1;
return 1;
}
This can't be right. Read the data into two local variables, then return 1 no matter what was read and the two variables get destroyed when they go out of scope at the end. So the data that you read will always be lost. All you get from this function is a 1 letting you know that it did in fact read something.
I think that if you want help with this you're going to have to post a lot more of the code. Like all of it. Or at least a complete example that compiles and demonstrates the issue.
Same with this function:
int MDBSerial::GetResponse()
{
while (available())
{
read();
}
return 1;
}
You read the data and throw it away and then return a 1 no matter what you read. How is that supposed to get the response? Perhaps a better name for this function would have been, throwResponseAway().
And that is what you call a complete program that compiles and demonstrates the issue? I get undefined reference to setup and undefined reference to loop at the very least.
Complete code. Compiles. Demonstrates the problem. If you find yourself about to post anything less than that, just stop because you are wasting your time.
I only get the first, second and last Byte of the ~ 20 Byte Long Response.
Is this due to the fact I dont read fast enought from the UART?
Probably. The UART only contains two bytes of buffering. If you try to use the same "wait long enough for the whole command to be received, and then read it one byte at a time", it will fail with symptoms similar to what you describe.
should never read more than two bytes, since your "available" function is only accessing the hardware status.
The Arduino code (which you can look at, don't forget) uses interrupts to fill a ~64byte software buffer, and available() returns the number of characters in the software buffer...
westfw:
The Arduino code (which you can look at, don't forget) uses interrupts to fill a ~64byte software buffer, and available() returns the number of characters in the software buffer...
Speaking of, why not use the already built in libraries for doing this?
Hi, thanks for your answers.
So what is the right way to test if there is data available on the UART? there must be a way to check that.
I dont use an existing solution, since they suck at my data Format, which is 1 start, 9 data and 1 stop bit.
Found nothing that would work for this specific Setup.
Sorry for the messy code, but this is a very early testing library for my project, that was also a reason why I kept the code in the start post as short as possible.
So what is the right way to test if there is data available on the UART?
The WAY that you're testing is fine. But if you're receiving more than 2 bytes of response with no interrupts, you need to do it OFTEN.
Now that you've posted CoinChanger.cpp, and I've looked at it, I'm not sure how
I only get the first, second and last Byte of the ~ 20 Byte Long Response
can be an accurate description of the behavior.
As far as I can tell, you don't have any inappropriate code that would be preventing you from reading the UART fast enough. Instead, you have what I'll call "too fast" code; it looks like you're thinking that once a message starts to arrive, you can read the whole message with that "while(available())" loop, and wind up with the whole message in your buffer. But in fact the message is dribbling in slowly at about 1 byte per millisecond (at 9600bps), and the loop runs MUCH faster than that. So the code should be aborting out of GetResponse() after only the first character or so, rather than waiting for the entire message. (or is there echoing of the SendCommand() data involved?)
But that doesn't explain the symptom you describe...
I think you need "idle timeout" code in GetResponse(); it should continue to receive characters and not return until several byte-times have gone by without seeing any additional traffic. It'd be easier if there was a definite end-of-message character... I found some other MDB coin-changer arduino code that looks like:
// wait for the answer
case 5:
// Wait for 24 bytes to be received
if(Serial1.available() < 24) {
return;
}
You can't delay() or wait for 24 bytes to be available (that requires the ISR-based Arduino code), but if there are always 24bytes in the response, you can certainly wait until 24 bytes have been received!
Or you can do the timeout, something like:
starttime= millis();
while (starttime + 50 > millis()) { // wait for a 50ms gap
if (available()) {
buffer[*count++] = read();
starttime = millis(); // reset timeout
}
}