Hallo,
Habe mir zum testen ein SDM-220-MT ( http://bg-etech.de/download/manual/SDM220ModbusEN.pdf )
Dieser Energiemesser kommuniziert über RS485 Modbus RTU ( http://bg-etech.de/download/manual/SDM220Register.pdf )
Mein Arduino Mega soll mit diesem als Master kommunizieren. Dafür habe ich mir ein TTL zu RS485 Wandler (https://arduino-info.wikispaces.com/SoftwareSerialRS485Example ) geholt und wohl richtig verkabelt.
Es gibt verschiedene librarys.
Die einzige die ich ansatzweise zum laufen bekomme ist diese: GitHub - smarmengol/Modbus-Master-Slave-for-Arduino: Modbus Master-Slave library for Arduino
Wenn ich dort das Beispiel nehme sendet der Arduino irgendwas aber der SDM-220 antwortet nicht, was ich auch verstehen kann weil er ja noch nicht die richtigen Befehle bekommt. Aber der SDM-220 erkennt das da jemand was von ihm will , weil wenn der Arduino mit dem Sketch läuft erscheint das Modbus Symbol auf dem Display des SDM-220.
Hier mal der Sketch der soweit funktioniert:
/** * Modbus master example 1:
* The purpose of this example is to query an array of data
* from an external Modbus slave device.
* The link media can be USB or RS232.
*
* Recommended Modbus slave:
* diagslave http://www.modbusdriver.com/diagslave.html
*
* In a Linux box, run
* "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1"
* This is:
* serial port /dev/ttyUSB0 at 19200 baud 8N1
* RTU mode and address @1
*/
#include <ModbusRtu.h>
// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* u8serno : serial port (use 0 for Serial)
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus master(0,0,2); // this is master and RS-232 or USB-FTDI
/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram;
unsigned long u32wait;
void setup() {
master.begin( 9600 ); // baud-rate at 19200
master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
u32wait = millis() + 1000;
u8state = 0;
}
void loop() {
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // wait state
break;
case 1:
telegram.u8id = 1; // slave address
telegram.u8fct = 3; // function code (this one is registers read)
telegram.u16RegAdd = 1; // start address in slave
telegram.u16CoilsNo = 4; // number of elements (coils or registers) to read
telegram.au16reg = au16data; // pointer to a memory array in the Arduino
master.query( telegram ); // send query (only once)
u8state++;
break;
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 100;
}
break;
}
}
Wie gesagt der Arduino sendet 1 und 3 in Hex und der SDM-220 (slave ID 1) merkt auch das ihn da jemand was sagen will (Symbol im Display)
Ich vermute mal das ich das array au16data irgendwie füllen muss.
au16data[1] = 30001; //???
Ich versteh leider die Bezeichnungen nicht in der SDM220Register.pdf
z.B. Address Register, Start Address, Hi Byte, Lo Byte
Lese mich nun seit zwei Tagen durch das Internet und Anleitungen. Leider finde ich nichts was mir weiterhelfen könnte.
Wenn mir jemand helfen könnte wie man die au16data füllt damit der SDM-220 daten rausrückt, würde ich mich sehr freuen.
Gruß
Steffen