I hope somebody can guide me, I am not an expert, but I have some knowledge about programming.
I am writing a simple program using Arduino Uno, and I comunicate it with a serial machine. This machine expects some bytes, to send its answer. The serial communication uses Parity EVEN at 19200. The question is, if there is a way to read data in serial port, but not using a terminator; the examples I saw shows that when you read a line for example, you expect an '\n' to know that there is new data...
...
void iniciaSerial(){
Serial.begin(19200,SERIAL_8E1);
}
void serialEvent() {
//How Can I read for example 20 bytes, NOT EXPECTING ANY TERMINATOR
}
...
You can only do without a terminator if you know exactly how many bytes you are expecting or as AWOL says you wait for a length of time to see if the data has stopped coming.
Any way what is wrong with a terminator?
This machine is really old, it does not send an 'enter' as terminator, and its termination is not always the same.
Now, when I send some bytes, its answer is fast, so I think 1 or 2 seconds could be enough to read those answer bytes; but how many bytes are as answer, I am not sure...
Would be possible to read for example for 3 seconds without knowing how many bytes will come? Would you please teach how to do that if it's possible?
All that you said is correct, but... Do you have really sure that, for example the length of the message is not on of the firsts bytes that you receive? It don't seams logic to me having a machine like that. What I would do (if I had written the communication program for that machine) will be 1 of 3 things:
terminator;
constant length;
variable length, but with a defined protocol (and in this case 1 of the header bytes will be the length of the message).
As I told, I am not sure about the length, I think the length could be the same; I do not have the machine right now, tomorow nigh I will have it again. But in these last 3 day I was knowing it...
About variable length on the header, I think is not like that.
If the answer bytes have the same length always, would you please teach me how¿
It could really help if you tell what kind of machine it is, and if you could find any datasheet.
Maybe the lenght of the answer will be variable, depending on which command was sent, no? For example one command expect an answer of 4 bytes, another command could expect an answer of 32 bytes, whatever...
To read a constant lenght... Basically something like this:
const uint8_t ANSWER_LENGTH = 20;
uint8_t answer[ANSWER_LENGTH];
uint8_t answer_index = 0;
void loop()
{
if ( Serial.available() > 0 ) // if there is something in the serial buffer
{
answer[ answer_index++ ] = Serial.read(); //read one byte
if ( answer_index == ANSWER_LENGTH - 1 ) // if there are 20 bytes in the answer array
{
answer_index = 0; //reset index for next answer
//process answer here
}
}
}
This is really crappy but should get you started...
Outside of your if statement, independent of every other condition, check if it's been long enough:
if (millis() - lastByteReceivedTime >= timeout)
{
processInput(buffer, length);
}
*Note that this is an explanation of the logic and process, not example code that can be used. Variables have to be declared in the proper scope, statements need to be declared and functions need to be implemented.
Correct. It's an old machine, it's not common, there is no much information about it. But it send its data when you send some bytes. I hope I can try reading with that example using timeout. If somebody has more ideas, that would be great.
Very simple serial echo test code. Does your device serial connection use TTL or rs232? Not sure how to handle the parity issue.
//zoomkat 6-29-14 Simple serial echo test
//type type text in serial monitor and send
String readString;
void setup() {
Serial.begin(9600);
Serial.println("Simple serial echo test"); // so I can keep track of what is loaded
}
void loop() {
while (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the String readString
delay(2); //slow looping to allow buffer to fill with next character
}
if (readString.length() >0) {
Serial.println(readString); //so you can see the captured String
readString="";
}
}
To my mind the key thing is whether there is a significant gap between the messages sent from the device to the Arduino. if there is one of the following strateges should work.
If there is long delay (several seconds or more) or if you can control when the device sends stuff (for example pressing a button on the device) ....
check whether Serial.available() > 0
if it is then read everything while Serial.available > 0
If the delay between messages is short (perhaps only the length of time it takes to send one or two bytes) you would need to measure the time between characters being received and discard the received characters until you detect the gap. That way you will know that you are starting at the beginning of a valid message and you can continue reading until you find the next gap. That technique proved successful in this Thread
Therr was a delay, the machine will come to me in 4 or 5 hours. I think I only need to read its answer bytes in some seconds, I will use some code that was posted to probe... And also I will check if answer bytes has always the same length for other type of solution besides time, right?