venerdì 8 luglio 2016

RS485 + FTDI232 + Arduino test di linea

Per un nuovo progetto  in questi giorni ho dovuto testare il funzionamento di una connessione RS485 attraverso un cavo lungo più di 100 metri.

Se cercate un po' in giro ci sono tanti tutorial sul funzionamento di questo metodo di trasmissione. Anche io non ho fatto altro che leggere qualche tutorial in giro e poi costruire il semplice circuito composto da 2 moduli RS485 che si parleranno a distanza attraverso il cavo.

La teoria dice che circuiti come quello riportato nello schema qui sotto possono raggiungere i 1200 metri senza problemi di decadimento della comunicazione, ma considerato che il progetto e' particolarmente importante in termini di sicurezza, e' stato fondamentale per me poter mettere sotto stress la comunicazione per poter controllare il regolare funzionamento anche sulla tratta di circa 100 metri di cui ho necessità.


Come si può vedere nello schema sia in testa che in fondo al cavo sono previsti dei carichi, che nel nostro caso sono già inseriti nel modulo che ho scelto per questo progetto.
Infatti nel modulino della LC Electronics di cui riporrto lo schema qui a fianco, ci sono già tutte le resistenze che servono per il corretto funzionamento del circuito.
Durante i test ho anche potuto sperimentare che il modulo e' anche molto sensibile alle sovratensioni, infatti prolungati periodi di sovra alimentazione anche di solo 1 volt in piu' hanno provocato la rottura del Max232 che e' l'integrato contenuto nel circuito del modulo.










Dopo aver fatto i primi test collegando un adattatore seriale USB-TTL come interfaccia tra il pc ed il modulo RS485, utilizzando un FTDI232, poi ho scelto di costruire un sistema basato su Arduino che si preoccupi di mantenere sempre viva la comunicazione e che segnali eventuali anomalie, nel caso la comunicazione non andasse a buon fine.

Il circuito e' molto semplice, dal FTDI232 prendiamo la alimentazione per il modulo collegando VCC e GND , nel caso del MASTER i due PIN  DE  ed RE devono essere collegati anch'essi a GND, mentre DI ed RO  rispettivamente a TX  ed RX della seriale.
DI -- TX   ed    RO -- RX

Per il modulo scelto per essere SLAVE (quello che trasmette l'informazione) si dovra' solamente collegare i PIN  DE ed RE a Vcc anziche' a GND

DE+RE --- GND (master), in questo modo abbiamo ottenuto un circuito che consente di trasmettere solamente in un verso l'informazione ( da Master a Slave ) che vengono definiti appunto scegliendo di mettere allo stato BASSO  DE ed RE  per il Master ed allo stato ALTO per lo Slave.
Per le prime prove va bene, ovviamente, ma per poter testare meglio in tutti e due i "sensi di marcia", per non fare lo switch degli stati a mano, ho preferito montare un circuito basato su Arduino.

Ho quindi montato il circuito che dal lato master invia un messaggio contenente un carattere (1), poi si mette in ascolto,  se riceve un carattere stabilito come ACK (7) fa lampeggiare il suo LED collegato al PIN13, altrimente ripete l'invio del messaggio.

Dal lato Slave, il modulo sta sempre in ascolto, quando riceve un messaggio stabilito (1) si mette in trasmissione, mandando un segnale convenzionale (7) per confermare l'avvenuta ricezione, e poi torna subito in ricezione per attendere il nuovo messaggio.

Prendendo l'alimentazione dei moduli RS485 direttamente da Arduino, ho lasciato fare lo switch degli stati al PIN 3  ed ho utilizzato questi due programmini per gestire la comunicazione:

**************************************

// software per lo SLAVE



void setup() {
  Serial.begin(57600);
  pinMode(3, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(3,LOW);
  digitalWrite(13,LOW);
}

void loop() {
 while (Serial.available()) {
    digitalWrite(3,LOW);
    delay(1);
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == '1') {
           
     // fai quello che devi fare
    digitalWrite(3,HIGH);
    delay(10);
    Serial.print(7);
    delay(1);
    digitalWrite(3,LOW);
 
   
    }else{
   
        // fai quello che devi fare se non e' arrivato il carattere giusto
    for(int i=1 ; i=10 ; i++){
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
    delay(100);
    }
    }
  }

}

 ***********************************************************


// software per lo MASTER



void setup() {
  Serial.begin(57600);
  pinMode(3, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(3,HIGH);
  digitalWrite(13,LOW);
}

void loop() {
 // while (Serial.available()) {
 
    digitalWrite(3,HIGH);
    delay(10);
    Serial.println(1);
    delay(1);
 
      digitalWrite(3,LOW);
      delay(1);
      char c = Serial.read();  //gets one byte from serial buffer
      if (c == '7') {

        // fai quello che devi fare
   // Serial.print("sentito il ACK");
      lampeggia();
   

 
      }
   
    }

  }
void lampeggia(){
  for(int i=1 ; i<3 i="" p="">    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
    delay(100);
  }
}
















Nessun commento: