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
