Hallo! Ich habe ein Problem mit den Werten, ausgelesen von einem Energiezähler SDM630-Modbus mit Hilfe eines UNO's.
Die Kommunikation steht, es wurde alles so aufgebaut wie hier beschrieben: https://www.ob121.com/doku.php?id=de:project:modbus_rtu_uno_master_sw_serial
Wenn ich nun jedoch das Register "POWERTOTAL 0x0034 //W" auslese, dann bekomme ich bei Null Last eine 0 zurück, was ja auch stimmt. Bei 24 Watt Last jedoch den Wert 16830. Ich sitze nun schon seit Stunden und finde den Fehler nicht. Wo könnte der liegen? Anbei mein Testprogramm (Beispiel aus public domain - angepasst an meine Bedürfnisse):
#include <ModbusRtu.h>
#include <SoftwareSerial.h>
// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;
#define SSerialTxControl 10
SoftwareSerial mySerial(2, 3);//Create a SoftwareSerial object so that we can use software serial. Search "software serial" on Arduino.cc to find out more details.
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* port : serial port
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus master(0); // this is master and RS-232 or USB-FTDI via software serial
/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram;
unsigned long u32wait;
void setup() {
Serial.begin(9600);//use the hardware serial if you want to connect to your computer via usb cable, etc.
master.begin( &mySerial, 9600, SSerialTxControl );
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 = 4; // function code (this one is registers read)
telegram.u16RegAdd = 0x0034; // start address in slave
telegram.u16CoilsNo = 1; // 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() + 2000;
Serial.println(au16data[0]); //Or do something else!
Serial.println("----------------------");
delay(2000);
}
break;
}
}
Das sind Fließkommawerte, keine Ganzzahlen. Wenn du deine 16830 in hexadezimalen Zahlen schreibst, ist das 0x41BE. Das ist der erste Teil einer IEEE754-float-Darstellung. Du musst noch ein weiteres Register lesen, um auf die vollen 32 Bit zu kommen. Nehmen wir an, da stünden nur Nullen drin, bekommst du 0x41BE0000, und das ist die Darstellung des Wertes 23,75.
Danke für die schnelle Antwort!
Da ich ein Arduino - Neuling bin, kannst du mir bitte verraten wie ich das mache?
Wenn ich also zwei Registerwerte habe, zum Beispiel au16data[0] und au16data[1],
wie bekomme ich da meinen Wert ? Danke und Sorry ...
Wow! Du bist ja schnell unterwegs!
Wie gesagt, bin ich ein kompletter Anfänger ....
Was mache ich mit dieser Fehlermeldung:
C:\Users\meki01\Documents\Arduino\Strommessung_MODBUS_ORIG\Strommessung_MODBUS_ORIG.ino: In function 'void loop()':
Strommessung_MODBUS_ORIG:93:8: error: 'class HardwareSerial' has no member named 'printf'; did you mean 'print'?
Serial.printf("%8.2f\n", overlay.wert);
^~~~~~
print
exit status 1
'class HardwareSerial' has no member named 'printf'; did you mean 'print'?
Nimmst du auch Aufträge an?
Wenn ich dir den Zähler schicke und du mir ein passendes Programm für einenn UNO oder NANO schreibst .... Was würde mich das kosten?
LG, M