#define SSerialTxControl 3 //RS485 Direction control #define RS485Transmit HIGH #define RS485Receive LOW #define Pin13LED 13 /*-----( Declare objects )-----*/ /*-----( Declare Variables )-----*/ int byteReceived; int byteSend; void setup() /****** SETUP: RUNS ONCE ******/ { // Start the built-in serial port, probably to Serial Monitor Serial.begin(19200); pinMode(Pin13LED, OUTPUT); pinMode(SSerialTxControl, OUTPUT); digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver // Start the software serial port, to another device Serial1.begin(19200); // set the data rate }//--(end setup )--- void loop() /****** LOOP: RUNS CONSTANTLY ******/ { digitalWrite(Pin13LED, HIGH); // Show activity if (Serial.available()) { byteReceived = Serial.read(); digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit Serial1.write(byteReceived); // Send byte to Remote Arduino digitalWrite(Pin13LED, LOW); // Show activity delay(10); digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit } if (Serial1.available()) //Look for data from other Arduino { digitalWrite(Pin13LED, HIGH); // Show activity byteReceived = Serial1.read(); // Read received byte Serial.write(byteReceived); // Show on Serial Monitor delay(10); digitalWrite(Pin13LED, LOW); // Show activity } }
druhy
#include <SoftwareSerial.h> SoftwareSerial mySerial(3, 4); // RX, TX #define SSerialTxControl 9 int byteReceived; int byteSend; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); pinMode(SSerialTxControl, OUTPUT); mySerial.begin(9600); digitalWrite(SSerialTxControl, LOW); } void loop() { if (mySerial.available()) { byteReceived = mySerial.read(); Serial.write(byteReceived); // Send byte to Remote Arduino } if (Serial.available()) { byteReceived = Serial.read(); digitalWrite(SSerialTxControl, HIGH); // Enable RS485 Transmit mySerial.write(byteReceived); // Send byte to Remote Arduino delay(10); digitalWrite(SSerialTxControl, LOW); // Disable RS485 Transmit } }
Toto je sice hezký ukázkový kód pro RS485 komunikaci, ale neřeší praktický problém přepínání linky vysílání/příjem (RS485 Direction control). Pokud bude rychlost seriové linky jenom 9600 a bude se posílat větší počet bytů, např. nějaký text, tak delay(10) může být kratší než bude trvat odeslání dat ze seriového výstupního bufferu a linka bude přepnuta z vysílání na příjem ještě před odesláním všech dat. Nejjednodušší učebnicové řešení je použít pro čekání funkci Serial.flush().
Tím ale vznikne velké blokování procesorového času. Otázka tedy zní – jak spolehlivě poznat, že již byla fyzicky odeslána všechna data z výstupního bufferu seriového portu? Ideální by byla tato kontrola ve smyčce loop() a na ni navázáno přepnutí RS485 linky do módu příjem.