RS485 – a jednak działa!

arduino rs485

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

Leave a Reply