Our Website uses cookies so that we can provide a better service. Continue to use the site as normal if you are happy with this. Cookie policy here
Close

Sezione Didattica:

Seriale tra Arduino, PLC Siemens S7-1200 e Dallas DS 18BS20


L’applicazione descritta in questo documento è a puro scopo didattico.
L’autore e plcforum.it non assumono responsabilità per danni e inconvenienti, a cose e/o a persone, derivanti da un suo uso improprio.


Quando si realizzano applicazioni con dispositivi a logica programmabile come i PLC e si ha la necessità di leggere un discreto numero di sensori di temperatura, è necessario l’utilizzo di moduli specifici di tipo proprietario (cioè che possono essere utilizzati solo con quel tipo di apparecchiatura Hardware), come i moduli per le PT 100, per le termocoppia ecc
In commercio si trovano anche sonde di temperatura e moduli convertitori per uso generico (quindi non proprietario), proprio perché “generici”, forniscono in uscita un segnale di tipo analogico.

Tale segnale normalmente è compreso in una di queste tre gamme:

  • 0-20 mA
  • 4-20 mA
  • 0-10 Volt

In questo ultimo caso è indispensabile che il PLC sia dotato e/o integrato di ingressi di tipo analogico compatibili con il tipo di “segnale” che viene erogato dal modulo convertitore ad esso connesso.
Se il numero di sensori di temperatura, di cui si ha necessità acquisire il valore, è limitato (ad esempio 3-4 sensori), l’acquisto dei moduli su indicati, siano essi di tipo proprietario e/o generici da associare ad eventuali ingressi analogici già presenti a bordo della CPU, non rende eccessivamente gravosa la spesa da sostenere.
Ma, se il numero dei sensori è significativo, i costi per l’acquisto dell’Hardware diventano (a mio parere) sproporzionati, soprattutto se l’applicazione che si vuole realizzare è di natura hobbistica.
Una soluzione low-cost è quella di utilizzare come sensori di temperatura i DS 18B20 della Dallas: sensori che, oltre ad essere molto precisi e stabili nella lettura, hanno un range di lettura abbastanza ampio che va da -55°C a +125°C, con una risoluzione programmabile massima ed impostata di default a 12 bit, e tra l’altro (cosa fondamentale) un costo irrisorio (pochi euro cadauno).
Tali sensori lavorano su BUS con il protocollo 1WIRE della Dallas.


Essendo sensori su bus hanno (cosa molto fondamentale) una semplicità di cablaggio notevole: basta collegarli tutti in parallelo.
(vedi schema in figura 3)
Per poter collegare questi sensori al PLC è necessario che quest’ultimo sia dotato di porta seriale RS232 oppure RS485.
In questo esempio prendiamo in considerazione un PLC Siemens della serie S7 1200 con modulo aggiuntivo per la porta seriale RS232.

Il plc usato non ha una porta seriale nativa a bordo, pertanto è da integrare.
Essendo questa applicazione versatile, la si può utilizzare senza alcun costo aggiuntivo su tutte quelle CPU che hanno già la porta seriale nativa a bordo, tipo il TWIDO, S7 200 ecc.

Perché Arduino:
Ciò che necessità per poter leggere i dati dai sensori di temperatura DS18B20, è un’interfaccia che si faccia carico di leggere/interrogare i sensori di temperatura mediante il bus 1Wire per poi inviarli alla porta seriale RS232 del PLC.
L’idea iniziale era quella di utilizzare l’apposito adattatore/convertitore della Dallas RS232 <> 1Wire (il DS9097U), ma, oltre alla difficoltà nel reperirlo ad un buon prezzo, era anche necessario scrivere il protocollo di comunicazione, che avrebbe richiesto un complesso lavoro di programmazione.
Eliminata la scelta del convertitore DS9097U, l’alternativa più economica rimanente era l’uso o di un microcontrollore della famiglia dei PIC oppure il mitico Arduino.
Ho immediatamente escluso il PIC perché per utilizzarlo era necessario realizzare il PCB su cui alloggiarlo e tutto il resto della circuiteria necessario al suo funzionamento; altro motivo della sua esclusione è perché molto spesso gli hobbisti che non hanno molta dimestichezza con la autocostruzione dei PCB avrebbero potuto trovare difficoltà nel mettere in pratica quanto qui descritto.
L’Arduino viene già venduto assemblato e funzionante ad un costo decisamente contenuto. (Circa 18/20 euro alla stesura dell’articolo).

Figura 2: Arduino mini e pinout
    


Il protocollo 1Wire della Dallas.
Un breve accenno sul funzionamento del protocollo 1WIRE per comprendere anche del perché necessita un adattatore/convertitore RS 232 < > 1Wire.
Il protocollo 1Wire è un protocollo Master/slave, cioè gli slave rispondono solo se interrogati dal master.
Come lascia intendere lo stesso nome 1WIRE=1FILO il funzionamento del protocollo di tipo bidirezionale è basato su un solo filo. Sul medesimo conduttore transitano sia i dati trasmessi dal master verso gli slave (TX) che quelli trasmessi dagli slave verso il master (RX).
In alcuni casi, dal medesimo conduttore (BUS) si provvede a prelevare anche l’ alimentazione necessaria per il funzionamento dei sensori.
Quindi un solo filo per alimentazione, trasmissione e ricezione dati.
Il BUS viene sempre tenuto alto: è sempre presente sul filo del BUS una tensione di 5 volt (in alcuni casi quando la distanza è consistente la tensione è di 12 volt, e poi ridotta a 5 volt, ma, questa soluzione richiede una circuiteria supplementare).
Quando avviene una trasmissione sia da parte del master che da uno slave, questa tensione viene forzata verso massa portandola a zero: in questo modo viene scritto lo “0 logico”. Per evitare che avvenga un corto quando viene scritto lo “0” logico, viene inserita una resistenza in genere da 4700 ohm detta resistenza di pull up.
Per scrivere invece “l’1 logico” i dispositivi rilasciano la linea, un po’ come se si scollegassero fisicamente. (vedi schema in figura 3)

figura 3

La porta seriale di cui Arduino è dotata è di tipo TTL, pertanto non è compatibile elettricamente con quella del PLC e/o di una qualunque altra porta seriale RS232 standard.
Per renderla compatibile è necessario interporre tra Arduino ed il PLC un adattatore/convertitore TTL<>RS232;
questo adattatore è facilmente reperibile in commercio ad un costo di una decina di euro.

Il prototipo ultimato:


Il software per Arduino:
E’ piuttosto semplice ed intuitivo. Creato con l’IDE 1.0.1, fa uso di due librerie che sono scaricabili da qui, o, comunque, facilmente reperibili in rete.
Ogni sensore DS18B20, essendo come detto un dispositivo che comunica con il master per mezzo di un protocollo su bus, è dotato di un numero espresso sotto forma esadecimale. Numero seriale che lo identifica in modo univoco all’interno della rete bus a cui appartiene.
Tale numero è scritto dal costruttore all’interno della ROM del sensore e non può essere cancellato o modificato; pertanto è fondamentale che al momento dell’acquisto insieme hai sensori venga fornito il numero del seriale per ogni sensore, altrimenti lo si dovrà acquisire leggendolo direttamente dal sensore. Questo numero va inserito all’interno de software per l’Arduino alla voce:

DeviceAddress S282F3C7E020000DB = { 0x28, 0x2F, 0x3C, 0x7E, 0x02, 0x00, 0x00, 0xDB }; // Sersore 1

L’istruzione DeviceAddress è seguita da un nome che identifica in modo univoco quel sensore all’interno del programma Arduino.
Per comodità ho utilizzato come nome il medesimo numero seriale del sensore; se lo si desidera, può essere anche sostituito assegnando ad esso un nome a voi più familiare.
Il vero numero seriale va invece inserito tra le due parentesi graffe ed espresso, ovviamente, in maniera esadecimale.
DeviceAddress S282F3C7E020000DB = { 0x28, 0x2F, 0x3C, 0x7E, 0x02, 0x00, 0x00, 0xDB }; // Sersore 1
Il nome, che identifica in modo univoco il sensore DS18B20, viene trasmesso sulla porta seriale seguito dalla temperatura rilevata dal medesimo sensore, in questo modo una volta ricevuta l’informazione nel PLC, si è in grado di identificare quale sensore sta trasmettendo l’informazione, e, nel programma utente del PLC, estrapolarne la temperatura ed associarla alla funzione che quel sensore deve assolvere.
Se l’Arduino non riceve risposta da uno slave, perché non presente, e/o si è rotto, invierà sulla porta seriale il nome del sensore non rilevato, (nel nostro caso come detto il numero seriale del sensore) seguito dalla parola ERROR, in modo che tale anomalia possa poi essere gestita all’interno del programma utente del PLC.

Serial.print("Error"); (l’istruzione che invia l’errore sulla seriale)

Se lo si desidera, si può provare a leggere le temperature inviate dai sensori connessi ad Arduino, collegandolo alla porta seriale di un PC ed utilizzando hyperterminal di windows senza l’ausilio di un PLC.

Il listato del codice per Arduino UNO:

#include 
#include

#define ONE_WIRE_BUS 2 //Pin data del sensore DS18B20 Collegato al pin 2
dell'Arduino

OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// -------------------Seriali dei sensori dallas---------------------
DeviceAddress S282F3C7E020000DB = { 0x28, 0x2F, 0x3C, 0x7E, 0x02, 0x00, 0x00,
0xDB }; // Sersore 1
DeviceAddress S28AC96380200000F = { 0x28, 0xAC, 0x96, 0x38, 0x02, 0x00, 0x00,
0x0F }; // Sensore 2
DeviceAddress S28B84D7E0200004F = { 0x28, 0xB8, 0x4D, 0x7E, 0x02, 0x00, 0x00,
0x4F }; // Sensore 3
DeviceAddress S281C713802000083 = { 0x28, 0x1C, 0x71, 0x38, 0x02, 0x00, 0x00,
0x83 }; // Sensore 4
DeviceAddress S28E99F3802000062 = { 0x28, 0xE9, 0x9F, 0x38, 0x02, 0x00, 0x00,
0x62 }; // Sensore 5
void setup(void)
{
// start porta seriale
Serial.begin(9600);
// RIchiamo la libreria
sensors.begin();
// Imposto la risoluzione dei sensori a 10 b it
sensors.setResolution(S282F3C7E020000DB, 10);
sensors.setResolution(S28AC96380200000F, 10);
sensors.setResolution(S28B84D7E0200004F, 10);
sensors.setResolution(S281C713802000083, 10);
sensors.setResolution(S28E99F3802000062, 10);
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
Serial.print("Error");
} else {
//Serial.print("C: ");
Serial.print(tempC);

Serial.print("\n");
// Per chi ne dovesse avere necessità, si può convertire il valore in Fahrenheit
// Serial.print(" F: ");
// Serial.print(DallasTemperature::toFahrenheit(tempC));
}
}


void loop(void)
{

Invio su seriale I dati ogni 50 ms
sensors.requestTemperatures();


delay(50);
Serial.print("282F3C7E020000DB:");
printTemperature(S282F3C7E020000DB);

delay(50);
Serial.print("28AC96380200000F:");
printTemperature(S28AC96380200000F);

delay(50);
Serial.print("28B84D7E0200004F:");
printTemperature(S28B84D7E0200004F);

delay(50);
Serial.print("281C713802000083:");
printTemperature(S281C713802000083);

delay(50);
Serial.print("28E99F3802000062:");
printTemperature(S28E99F3802000062);

}

Il programma per l’ S7 1200.
Il PLC S7 1200 ha il compito di leggere i dati proveniente dalla porta seriale: prelevarne la temperatura e visualizzarla su un pannello operatore KTP 400
La comunicazione è del tipo unidirezionale, cioè è solo l’Arduino ad inviare i dati verso il PLC : il PLC si preoccupa solo di ricevere i dati presenti sulla porta seriale.
Non vi è alcun controllo sulla comunicazione; come, per esempio, se la comunicazione cade o se i dati ricevuti siano integri. Ma questo è facilmente superabile.
I dati inviati verso il PLC sono di tipo ASCII.
Una volta avviato il TIA Portal ed eseguite le operazioni preliminari, è necessario in primo luogo per garantire la comunicazione procedere con la configurazione della porta seriale.
La porta seriale deve essere come mostrato in figura 5:



Il programma esempio è piuttosto semplice e banale: il tutto si svolge in un OB ciclico (OB123).
Osservando la figura 6, si nota la presenza del blocco di comunicazione punto punto “RCV_PTP” (1), necessario alla ricezione dei messaggi provenienti dalla porta seriale. I dati ricevuti, vengono inviati in una variabile di tipo stringa del blocco dati (DB2).
Mediante il parametro “LENGTH” viene ricavata la lunghezza della stringa ricevuta. Eventualmente potremo utilizzare questo dato per verificare se la stringa ricevuta (il messaggio inviato dall’Arduino) sia della lunghezza corretta.
Nel segmento successivo abbiamo l’istruzione “LEFT” (2) con la quale leggiamo 16 caratteri della nostra stringa (che contiene i dati inviati dal sensore di temperatura): appoggiamo questo dato in una variabile temporanea di tipo stringa “#Serial_sensor” per poi confrontarlo (3) ed identificarlo.
Se il confronto ha esito negativo si salta al segmento successivo per ripetere il confronto con un altro seriale.
Al contrario se il confronta ha esito positivo, vengono letti 5 caratteri “MID” (4) della stringa partendo dalla posizione 18 per estrapolarne il dato contenente la temperatura.
I caratteri letti sono 5 perché è così composto: 2 caratteri per le unità, un carattere per il punto decimale e altri due caratteri per i decimali. (Esempio 23.12). A questo punto la stringa viene convertita in numero reale STRG_REAL(5) e viene attivato il bit sensor_OK (6) per indicare che il sensore è stato letto e presento.
Se al punto 4 viene estratto il carattere “ERROR” (7) il bit sensor_OK (8) viene resettato per indicare che il sensore non è stato letto dall’Arduino.
Di seguito si può vedere come verranno rappresentati sul display i dati ricevuti. (Figura 7):



figura 3

Articolo curato da Giuseppe Signorella