further experimenting with the RS485 modules leads to more problems. I try to build a custom RS485 class in order to understand the processing and handling of a multi-master bus system.
The master sends the desired char(s) "x12". The RS485 sniffer (read over a terminal program on my pc) also read 'x12'. The slave on the other hand only detects the FIRST character '120' (which equals 'x').
Why does the Serial.available() not wait for the terminator?
Can I only send one character, terminate and then the next one? (This would seem very inefficient when sending larger telegrams)
I tried sending the characters using Serial.println(c) and Serial.print(c); Serial.print('\n'). The terminator does not seem to get scanned (because its the next character which is not detected).
Serial.available() NEVER waits for ANYTHING. It tells you IF there is ANY data ready RIGHT NOW. It is YOUR job to wait, if that is what you need. Serial data arrives slowly. That is how it is.
Serial.read() function reads only one character from the serial buffer. So, this part of your code reads that character and prints it. You´will have to read and store multiple characters before printing the whole message.
I suggest you taking a look at Serial Input Basics - updated to get a clue on what to change in this part of the code.
The while loop is constantly scanning the serial line. There should not be a timing issue, since I am constantly listening. Here also only '120' is detected.
Removing the if and constantly reading results in the output
120 // for the send character(s)
-1
-1
-1
...
120
-1
-1
...
but never '49' or '50'.
Shouldnt at least sometimes the other characters appear?
Using the outlined examples I copied the code from Example_2. The problem remains the same
void loop() {
unsigned int pos = 0;
bool newData = false;
while(Serial.available()>0 && newData == false) {
Serial.print ("T "); // test if loop is triggered
byte r = Serial.read();
Serial.println(r); // test if loop is triggered
if(r != '\n') {
data[pos] = r;
pos++;
} else {
Serial.println("N"); // test path is triggered
data[pos] = '\0';
newData = true;
break;
}
}
Serial.println("O"); // outside while
if(newData) {
Serial.println(data);
}
}
The output constantly reads
T 120
T 120
...
Apparently Serial.available() becomes false after '120' is transmitted and no newline or other characters are detected over all the Serial.read() command that follows. Until the next telegram is transmitted ("x12").
Removing the debugging prints (T,O,N) does not affect the output, so it should not be a timing issue.
Serial data arrives SLOWLY. You will fine Serial.available() returns 0 for a LONG time, then will return 1. You read the ONE available character, then Serial.available() again returns 0 for a LONG time, until another character arrives. But, you've now exited your while loop, BECAUSE Serial.available returns 0, so newData is again set to false, and pos is again rsset to 0, so you're starting over from scratch each time a character is received.
See the problem? Read, and study, more of the tutorial, to understand how to properly either wait for ALL characters to arrive, or properly handle the characters one at a time, with the unavoidable delays between each character being received.
I understand that the serial communication is 'slowish'. But the telegrams are sent in 3500ms intervals.
I had bad experience with EventTriggers (which are also not recommended in the article). The other examples focus on handling the received data.
Letting the loop run until Serial becomes available again results again only in one character '120'. The else-path is never triggered.
unsigned int pos = 0;
void loop() {
bool newData = false;
while(Serial.available() > 0 && newData == false) {
// Serial.print ("T "); // test if loop is triggered
byte r = Serial.read();
if(r != '\n') {
data[pos] = r;
pos++;
} else {
Serial.println("N"); // test path is triggered
data[pos] = '\0';
newData = true;
}
}
if(newData) {
Serial.println(data);
pos = 0;
}
}
Either the other characters are flushed somehow or never sent (doubtful since the sniffer reads 'x12').
Maybe I am searching on the wrong side of the code. Since I am using two RS485 modules for the transmissions: Do I need to LOW\HIGh the external trigger after each character or can I send them all at once?
I may have found the error. Since all the Serial.read() function did not yield a consistent result I looked deeper in the RS485 library and example.
In the code I am using the transmitting telegram does not wait until transmission is completed. With the Serial.flush() (link) function, before the enable pin (active write), the transmission can securely and completely go through.