Energy meter Eastron SDM120C lettura tramite RS485 Modbus

Salve,

sto tentando da parecchio tempo, senza grossi risultati, di comunicare tramite RS 485 MODBUS con l' energy meter in oggetto di cui allego il manuale . Ho letto e riletto le caratteristiche del protocollo Modbus e a grandi linee ho capito come funziona, sono riuscito anche a stabilire una comunicazione con relativa risposta dal dispositivo tramite software di controllo, Modbus Tester a questo link

formatting link

parametro che mi serve con Arduino. Ho trovato alcune librerie RS485 ma purtroppo come capita spesso sono poco o nulla commentate/spiegate in maniera chiara limitandosi a qualche esempio striminzito...

modificarlo alle mie esigenze. Grazie in anticipo

PS: link ai manuali

formatting link
formatting link

--
Franco
Reply to
Franzthepanz
Loading thread data ...

io non ho nulla di pronto e collaudato, ma se mi dici tu cosa stai usando e dove ti sei bloccato, forse una mano riesco a dartela. il protocollo modbus di per se e' una cosa semplicissima:

- invii la richiesta

- attendi la risposta non ci sono stati logici da rispettare, o sequenze di comandi da seguire, a meno che non sia il dispositivo a ad averne bisogno, a livello di protocollo e' un semplice botta e risposta..

Reply to
alfio

Dopo aver strapazzato l'unico neurone rimasto, alfio il 24/09/2015 ha pensato bene di dire:

Gentilissimo !

inviare una stringa esadecimale ed aspettare la risposta sempre in esadecimale.

Come dicevo esistono delle librerie che fanno questo ma sono criptiche... non so con quale piede partire.

--
Franco
Reply to
Franzthepanz

Mi serve un codice funzionante con Arduino da compilare poi sull'ESP8266

caccia ai fantasmi nel poco tempo disponibile...

Voto per tenere pubblica la discussione :-) PaoloC

PS: hai controllato che su Arduino usi il baudrate giusto?

Reply to
PaoloC

Dopo aver strapazzato l'unico neurone rimasto, PaoloC il 25/09/2015 ha pensato bene di dire:

Si, riesco a comunicare correttamente tramite sw per la creazione/ricezione di pacchetti

serve un "assist" per partire...

Se vuoi utilizzare per caso le uscite S0 e non riesci farle andare guarda questa discussione

formatting link
Ciao

--
Franco
Reply to
Franzthepanz

Speravo che si trattasse di una discussione vecchia, e invece gli sviluppi sono recentissimi!

di 3.3 kW rischiando il distacco.

Di fatto basta misurare la distanza tra gli impulsi dell'uscita standard a 1000 imp/kWh. Con un ATmega a clock bassissimo potrei alimentarlo con due stilo per un anno, senza tirare troppi cavi in giro, dato che nel quadro elettrico non ho una alimentazione a bassa tensione o una presa.

Ma se i fotoaccoppiatori sono montati al contrario, GRRRRRRR!!!!!!

Non sono registrato su quel forum e non apro le foto allegate, ma il mio

PaoloC

Reply to
PaoloC

"Franzthepanz" ha scritto nel messaggio news:mu1poc$k0h$ snipped-for-privacy@speranza.aioe.org...

e scrivere da te la tua libreria (o classe) che fa solo quello che serve a te ? immagino che cio' che hai scaricato (hai un link?) sia un bel malloppo che copra ogni possibile uso del modbus, quindi una cosa che ha una sua logica dietro da capire e che quindi proprio per questo ti blocca. se tu implementi la tua libreria da te ci metti solo quello che ti serve e saprai sicuramente come usarla.

Reply to
alfio

ecco un codice scritto di getto. e' compilabile, ma io ovviamente non posso provarlo, non ho nessun modulo modbus su cui testarlo. se vuoi/puoi provalo, dopo correggiamo insieme quello che non va.

#define MB_OK 0 #define MB_INVPARAM -1 #define MB_INVSLAVE -2 #define MB_INVANSWER -3 #define MB_CRCANSWER -4 #define MB_ERRANSWER -5 #define MB_SIZEANSWER -6

class ModBus { byte cmd[16]; byte answ[16];

int CRC ( byte *buf, int len ) { unsigned crc = 0xFFFF;

for( int pos=0 ; pos>= 1; // Shift right and XOR 0xA001 crc ^= 0xA001; } else // Else LSB is not set crc >>= 1; // Just shift right } } // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes) return crc; } int Query ( byte slave, byte function, unsigned addr, unsigned nReg,byte* val=NULL ) { cmd[0] = slave; cmd[1] = function; cmd[2] = addr>>8; cmd[3] = addr; cmd[4] = nReg>>8; cmd[5] = nReg; int len = 6; if( function==10 ) for( int i=nReg*2 ; i ; i--,len++,val++ ) cmd[len] = *val; unsigned crc = CRC( cmd,len ); cmd[len+0] = crc; cmd[len+1] = crc>>8; while( Serial.available() ) Serial.read(); Serial.write( cmd,len ); len = function==10 ? 8 : ( 5+2*nReg ); int n = Serial.readBytes( answ,len ); if( n!=len ) { if( answ[1]&0x80 ) return MB_ERRANSWER; else return MB_INVANSWER; } crc = (((unsigned)answ[len-1])

Reply to
alfio

Dopo aver strapazzato l'unico neurone rimasto, alfio il 26/09/2015 ha pensato bene di dire:

STRACUT

Ma l'hai scritto tu, DI GETTO ???? O Gesu'....

E' meglio che MI dia all'ippica :-(

Lunedi provo a caricarlo e speriamo che Arduino non mi esploda sulla scrivania.

:D :D

--
Franco
Reply to
Franzthepanz

"Franzthepanz" ha scritto nel messaggio news:mu6t5q$haf$ snipped-for-privacy@speranza.aioe.org...

si, in un paio d'ore, ecco perche' non c'e' nessuna garanzia di funzionamento :-)

la sola funzione di calcolo del CRC non e' mia. mi sono letto un mini doc sul modbus e penso che il manuale che ti hanno dato insieme al meter non sia del tutto corretto. eventualmente lo verifichiamo quando il codice iniziera' a funzionare.

aah! :(

Reply to
alfio

WOW.

Il codice compila nella IDE Arduino scegliendo ESP8266 come board ed

spazio per montare un webserver o un client che fa upload dei dati da qualche parte.

altri progetti sul tavolo e non riesco a seguire anche questo in modo costruttivo.

PaoloC

Reply to
PaoloC

Dopo aver strapazzato l'unico neurone rimasto, alfio il 26/09/2015 ha pensato bene di dire:

C:/Users/FRANCO/Desktop/Scketch di prova/2/Modtest2.ino: In member function 'int ModBus::ReadValue(byte, unsigned int, float*)':

C:/Users/FRANCO/Desktop/Scketch di prova/2/Modtest2.ino:85:28: error: invalid cast from type 'byte* {aka unsigned char*}' to type 'float'

val = *(float)(answ+3);

--
Franco
Reply to
Franzthepanz

Franco, che versione di Arduino hai usato? Io l'ho compilato con la

1.6.5, sia per un Leonardo sia per l'ESP8266 e non ho avuto errori.

[asterisco]val = [asterisco](float[asterisco])(answ+3);

sostituisci [asterisco] con * .

PaoloC

Reply to
PaoloC

Dopo aver strapazzato l'unico neurone rimasto, PaoloC il 28/09/2015 ha pensato bene di dire:

*val = *(float*)(answ+3); non mi da errori. Un piccolo problema:

Fino ad ora l' SDM lo collegavo al PC tramite convertitore RS485> USB mentre ora lo devo collegare ad Ardu... ma come e su quali pin?

--
Franco
Reply to
Franzthepanz

Per come ha scritto il codice alfio devi collegare l'adattatore RS485TTL alla seriale nativa di Arduino. Se hai solo un convertitore

485USB non credo che si possa usare, nemmeno se hai la USB nativa sull'Arduino.

Il codice di alfio andrebbe esteso un minimo per visualizzare le info su un display collegato ad Arduino, oppure con la replica dei dati su una SoftwareSerial (o Serial2 se la tua board la prevede nativamente).

Al contrario di alfio, io non so scrivere di getto codice funzionante :)

PaoloC

Reply to
PaoloC

Mentre mi sto attrezzando per provare il codice su un Arduino con adattatore MAX485, ho anche letto il protocollo dell'SDM120C e cercato qualche altro esempio.

dipende magari dall'adattatore...

e i 4 esempi forniti non mi quadrano. OK per mandare richieste per un

Mi sa che prima provo a dialogare con l'SDM120C con il PC + adattatore USB/TTL + TTL/RS485 per "sniffare" il protocollo.

PaoloC

Reply to
PaoloC

Paolo, per capire come dialogano prova ad utilizzare il seguente software gratuito

formatting link
che ho provato e che funziona correttamente facendoti vedere i pacchetti inviati e ricevuti tramite adattatore USB/TTL + TTL/RS485

Ciao

--
Franco
Reply to
Franzthepanz

"PaoloC" ha scritto nel messaggio news:mugfb6$uqp$ snipped-for-privacy@mophus.csi.it...

hai ragione, dovrebbe essere necessario collegare i pin 2 e 3 del MAX485 insieme tra loro e ad una uscita di Arduino. in Setup la dichiari OUTPUT e la setti OFF. poi nella funzione Query() prima di Serial.write metti una DigitalWrite(HIGH) , e subito dopo le 2 istruzioni Serial.flush(); DigitalWrite(LOW);

il parametro 00:02, secondo il protocollo modbus esprime il numero di registri a 16 bit consecutivi da leggere. per un registro float, cioe' 32 bit, vale sempre 2.

nella doc Eastron non mi quadra l'esempio "2.2 Read Holding Register" proprio il valore di prima, nell'esempio c'e' 0x14, 20 registri da leggere, ma la risposta e' sempre la solita con 2 registri. poi nella tabella degli "Holding Register" i primi 3 sono float, ma che senso hanno baudrate, parita', ID, e delay espressi in floating point ? i parametri seguenti, che in tabella sono dichiarati HEX e BCD, che lunghezza hanno ? nel mio codice ho supporto 16 bit.

sarebbe molto utile.

mi sono scaricato e parzialmente letto, questo manuale:

formatting link

Reply to
alfio

Avevo letto il bignamino del protocollo, quello di due pagine. Poi ieri ho stampato e riletto 10 volte il documento da 6 pagine e ho capito il significato di quella posizione.

NB: a me interessa solo leggere la potenza input istantanea per avere un allarme in casa prima che ci sia il distacco per supero.

Chiedo a Franz: che pin seriale hai collegato al DE/RE? Il mio adattatore li espone tutti, ma il softwarino polacco non mi da la

PaoloC

Reply to
PaoloC

Dopo aver strapazzato l'unico neurone rimasto, PaoloC il 01/10/2015 ha pensato bene di dire:

Io ho usato un adattatore cinese USB>RS485 ed ho solo due connettori. Il sw ti connette ad una porta COM pertanto per utilizzarlo devi avere il suddetto convertitore che la crea.

--
Franco
Reply to
Franzthepanz

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.