RS485 – a jednak działa!
Kto by się spodziewał, że rozwiązanie dużego problemu, jakim jest odległość dzieląca urządzenie podłączone na SPI do kontrolera głównego, można znaleźć dość prosto i szybko. Na etapie tworzenia interfejsu do zarządzania funkcjami mikrokontrolera Arduino napotkałem długi na ok 20 metrów problem. Baza jest w garażu a ekran dotykowy FT811 jest w domu a magistrala SPI nie działa na duże ogległości. Nie wiem jak duże nie działa, wiem że działa na ok 30 cm.
RS-485 – standard transmisji danych niedość, że prosty to jeszcze tani i szybki. Sam moduł kosztuje mniej niż 10PLN, jego prostota oprogramowania zachęca do skorzystania. Sprawa sprowadza się do dodania drugiego Arduino – w moim przypadku NANO – które będzie sterować wyświetlaczem i modułem RS-485 i będzie umiejscowione w mieszkaniu, pod ekranem dotykowym. Wyświetlacz podłączony na SPI do NANO na małą odległość więc działa, a komunikację pomiędzy NANO w mieszkaniu a głównym kontrolerem w garażu zapewniają dwa moduły RS-485 (po jednym przy każdnym arduino) połączone dwoma żyłami A i B. Polecenia wywoływane z wyświetlacza trafiają do NANO a ten wysyła i pobiera dane z MEGA poprzez RS485 i tak się komunikują.
Niestety Fritzing nie posiada wbudowanego modułu 485 i takiego nigdzie nie znalazłem więc nie będzie rysunku, jest jedynie opis podłączeń.
Arduino Master:
DI -> pin 11
RO -> pin 10
DE+RE ->pin np.3
GND -> GND
VCC -> 5V
Arduino Slave:
DI -> pin 11
RO -> pin 10
DE+RE ->pin np.3
GND -> GND
VCC -> 5V
Oba RS-485 są połączone ze sobą dwoma kablami A->A oraz B->B.
Kod przykładu dla Slave
#define SSerialRX 10 #define SSerialTX 11 #define SSerialTxControl 3 #define RS485Transmit HIGH #define RS485Receive LOW SoftwareSerial RS485Serial(SSerialRX, SSerialTX); int byteReceived; void setup() { Serial.begin(9600); pinMode(SSerialTxControl, OUTPUT); digitalWrite(SSerialTxControl, RS485Receive); RS485Serial.begin(4800); } void loop() { if (Serial.available()) { byteReceived = Serial.read(); digitalWrite(SSerialTxControl, RS485Transmit); RS485Serial.write(byteReceived); delay(20); digitalWrite(SSerialTxControl, RS485Receive); } if (RS485Serial.available()) { byteReceived = RS485Serial.read(); Serial.write(byteReceived); delay(20); } }
Kod przykładu dla Master
#define SSerialRX 10 #define SSerialTX 11 #define SSerialTxControl 3 #define RS485Transmit HIGH #define RS485Receive LOW SoftwareSerial RS485Serial(SSerialRX, SSerialTX); int byteReceived; void setup(){ Serial.begin(9600); Serial.println("Serial Start"); pinMode(SSerialTxControl, OUTPUT); digitalWrite(SSerialTxControl, RS485Receive); RS485Serial.begin(4800); } void loop(){ if (RS485Serial.available()){ byteReceived=(RS485Serial.read()-96); delay(20); if(byteReceived>0){ digitalWrite(SSerialTxControl, RS485Transmit); Serial.println(byteReceived); if(byteReceived==1){ RS485Serial.println("+"); }else{ RS485Serial.println("_"); } delay(20); digitalWrite(SSerialTxControl, RS485Receive); } } }
W tym przykładzie w odpowiedzi na wpisanie w monitor szeregowy jednego z kontorlerów uzyskamy odpowiedź „+” lub „-„. Jeżeli wyślemi literę „a” uzyskamy + a jakąkolwiek inna to „-„.
Opublikowano: 23 sierpnia, 2016 przez Pan z Pogodna