Lug 192012
 

Mi è stato chiesto di trovare il modo di fornire una reportistica (anche via WEB) sull’andamento della produzione dei diversi campi fotovoltaici installati in azienda e mi sono  così scontrato per la prima volta con il MODBUS su RS485.

Infatti i contatori piombati collegati all’uscita degli inverter sono compatibili con il protocollo di cui sopra.

Dovendo memorizzare i dati di produzione e visualizzarli in tempo reale la scelta è caduta ovviamente sul flessibilissimo ambiente LAMP e per semplicità ho deciso di utilizzare direttamente il nostro server intranet che ne è già provvisto.

Per connettermi al bus RS485 nel quadro elettrico che è distante dalla sala CED ho utilizzato un collaudatissimo MOXA Nport collegato alla rete IP e configurato con i suoi  driver LINUX (sempre disponibili ed aggiornati sul sito del produttore).  

E per ottenere i dati?

Navigando su internet si trova una grande quantità di software a pagamento per la gestione/interrogazione modbus, ma niente che consenta facilmente l’uso con PHP.

Senza perdermi d’animo ho letto un po’ di specifiche (il protocollo è ben documentato) ed ho capito che per un normale sistema di interrogazione multislave e con un singolo master la realizzazione era alla portata anche di un programmatore scarso come me 😉

Con qualche complicazione in più è possibile programmare anche sistemi più complessi  a patto di tenere ben presenti le regole sul timing della trasmissione.

Dopo aver testato la funzionalità del BUS con l’insostituibile modpoll mi sono avventurato nella scrittura delle poche linee di codice necessarie per interrogare il dispositivo e ottenere il valore contenuto in alcuni registri (p. es il contatore globale dei kW prodotti).

Come in altre situazioni per la gestione della porta seriale ho utilizzato l’utilissima classe PHP SERIAL

L’unica difficoltà nella compilazione del frame di richiesta è stata la generazione dei due bytes di CRC finali. Infatti PHP comprende una funzione per la CRC, ma a 32 bit non a 16.

Non avendo voglia di scrivere di persona il codice (gran brutta bestia la pigrizia…) ho provato ad utilizzare funzioni trovate su internet, ma non ho mai ottenuto la risposta dal dispositivo, mentre calcolando la CRC a mano con alcuni strumenti online  il frame di risposta arrivava puntuale. Alla fine mi sono imbattuto in una funzione specifica per modbus inserita da un utente nei commenti  della documentazione su PHP.net (grazie  roberto at spadim dot com dot br!!! ).

Con questa implementazione il problema è stato totalmente risolto!

Il passo successivo è stato la realizzazione della parte più banale, cioè l’acquisizione dei dati ad intervalli prefissati (via cron), la memorizzazione nel database, la generazione dei grafici di report e l’esportazione in foglio di calcolo 🙂

Produzione fotovoltaico

Il progetto è ormai in funzione da diverso tempo senza avere mai dato il minimo problema.

La soddisfazione più grande è stata quella di realizzarlo praticamente a costo zero ancora una volta grazie ai flessibilissimi strumenti offerti dal mondo opensource e dai deliziosi personaggi che lo popolano, sempre pronti a fornire aiuto a chi ne ha bisogno.

Proprio in quest’ottica pubblico volentieri il codice realizzato, casomai a qualcuno servisse e non avesse voglia di riscoprire l’acqua calda….

N.B. : si tratta solo di uno script di TEST. In ambiente di produzione si consiglia di aggiungere qualche controllo in più.


deviceSet("/dev/ttyr03");
$serial->confBaudRate(9600);
$serial->confParity('none');
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl('none');
$serial->deviceOpen();
if($serial->_dState!=2)die("porta chiusa\n");//se è chiusa stoppa il pgm.

$modbus_address=1;
$function_code=3; //03h read
$indirizzo_lettura="003E";//indirizzo HEX della lettura (Contatore energia) da tabella Pg 8
$numeroregistri=2;//in realtà è numero di word da leggere (sono 4 bytes consecutivi)

$high_byte=hexdec(substr($indirizzo_lettura,0,2));
$low_byte=hexdec(substr($indirizzo_lettura,2));

//frame di richiesta da trasmettere al dispositivo. Manca solo la CRC da aggiungere in fondo
$messaggio=array($modbus_address,$function_code,$high_byte,$low_byte,0,$numeroregistri);

//lo stinghifichiamo per la trasmissione su seriale
$stringamessaggio="";
for($p=0;$psendMessage($stringamessaggio);

//dormitina per dare tempo di rispondere. Secondo timing protocollo MODBUS è OK
sleep(.5);

$result='';
while($r=$serial->ReadPort()){
//per rendere più solido inserire controllo TIMEOUT
$result=$result.$r;
usleep(100000);
}

//Se è andata bene....abbiamo il frame di risposta!
for($p=0;$p MSW)
//cioè in ordine di significatività 5 6 3 2
$lettura= pow(256,3)*$resarray[5]+pow(256,2)*$resarray[6]+$resarray[3]*256+$resarray[4];

$lettura=$lettura/10;//è * 10 come da dispensa dispositivo
echo "Contatore kW: $lettura\n";
?>

Ecco la funzione per il calcolo della CRC16 compatibile con modbus.

Un enorme grazie all’utente roberto at spadim dot com dot br


  10 Risposte a “MODBUS facile con PHP”

  1. Ciao Fabrizio,
    mi trovo nella tua stessa situazione, devo creare una presentazione di un impianto fotovoltaico e metterci i dati di potenza in tempo reale, con protocollo modbus di 2 analizzatori di rete Ducati. Non sono un esperto di programmazione, ma ho bisogno di un tuo aiuto.
    La mia mail: XXXXXXXXX
    Grazie
    Ciao

    • Ciao Gaetano,

      Non conosco i dispositivi Ducati in specifico, ma sulla nostra gestione interna (abbiamo anche l’analisi dei consumi per reparto/linea) utilizziamo dispositivi Contrel (MODBUS su ethernet) Gavazzi (MODBUS su RS485) e PowerOne (xml su http)
      In genere non è un grosso problema “ottenere” i dati.

      Ma un progetto fatto come si richiede anche:

      1) una SOLIDA memorizzazione su base temporale per analisi successive.
      2) reportistica grafica e non (p. es possibilità di esportare i dati richiesti in excell)

      Per il punto 1) abbiamo utilizzato un database MySQL.
      Tieni presente che memorizziamo anche parametri elettrici di tipo diverso come fase, THD, potenza attive e reattiva etc. etc. per tracciare eventuali problemi, quindi un buon database relazionale è fondamentale.

      Per il punto 2) ho creato un po’ di report interattivi sul WEB interno, ma sincronizzati anche all’esterno su un altro server per dar modo a chi è interessato di interrogare la situazione in tempo reale.
      Inoltre ho creato la possibilità di esportare il report su excell.

      Il progetto è ormai concluso da diversi mesi e non ha evidenziato alcun malfunzionamento, a parte il guasto di un dispositivo prontamente sostituito.

      La realizzazione di quanto sopra, non è particolarmente complessa, ma richiede comunque qualche competenza nel campo della programmazione.

      Se hai bisogno di una mano fammi sapere in maniera più specifica che tipo di aiuto ti serve!

      Ciao a presto

  2. Ottimo articolo interessante. Mi sto imbattendo ora con la lettura di dispositivi modbus tramite php. Proverò nei prossimi giorni il tuo codice su i dispositivi che ho in cabina. Vi aggiornerò sul risultato. Utilissimo articolo. Grazie

  3. Ciao Fabrizio,
    Per monitorare i parametri elettrici di una linea ho preso spunto dal tuo codice per realizzare senza grossi problemi la registrazione su database MySql dei parametri provenienti da un dispositivo modbus collegato in seriale RS485.
    Il problema che ho e’ legato alla visualizzazione grafica dei dati sia realtime che storica (trend), non ho problemi nell’esportare i dati su excel. Tu cos’hai utilizzato per la visualizzazione grafica?

    Grazie.

    Alessio.

    • Ho usato JpGraph.
      Non perché sia il migliore, ma avevo già le librerie sottomano (una vecchia licenza) ed ho fatto copia-incolla :).
      E’ottimo, ma per uso commerciale è a pagamento.
      Se fai una ricerca ci sono tanti altri strumenti simili open-source.

  4. Ciao, navigando in rete in cerca di informazioni, mi sono imbattuto in questo articolo.
    Avrei bisogno di un aiuto per la realizzazione di un progetto.
    Possiamo sentirci in qualche modo e metterci in contatto?

    Ciao Fabiano

  5. grazie grazie grazie!!!!!!!!! lo userò sicuramente, ma al momento devo ancora chiarire dei dubbi sul modbus!!!!!!

  6. Qualcuno di voi utilizza windows con apache e php. Purtroppo la class non è implementata nella funziona di lettura?

Lascia un commento a piergiorgio Annulla commento

Puoi usare questi tag e attributi HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)