reaper7 / SDM_Energy_Meter

reading SDM72 SDM120 SDM220 SDM230 SDM630 modbus energy meters from arduino (esp8266, esp32, avr)
240 stars 97 forks source link

SDM_energy_meter library adapter for ORNO_energy_meter #43

Closed oussama415 closed 4 years ago

oussama415 commented 4 years ago

Hello, please I would like to adapt the SDM energy-meter library for my OR-WE-517 meter, I downloaded it, I modified the SDM.h file by modifying the addresses which correspond to the quantities that I want to measure this is SDM.h :

SDM.h ` //------------------------------------------------------------------------------

ifndef SDM_h

define SDM_h

//------------------------------------------------------------------------------

include

include "SDM_Config_User.h"

if defined ( USE_HARDWARESERIAL )

include

else

include

endif

//------------------------------------------------------------------------------ //DEFAULT CONFIG (DO NOT CHANGE ANYTHING!!! for changes use SDM_Config_User.h): //------------------------------------------------------------------------------

if !defined ( SDM_UART_BAUD )

define SDM_UART_BAUD 9600 //default baudrate

endif

if !defined ( DERE_PIN )

define DERE_PIN NOT_A_PIN //default digital pin for control MAX485 DE/RE lines (connect DE & /RE together to this pin)

endif

if defined ( USE_HARDWARESERIAL )

if !defined ( SDM_UART_CONFIG )

#define SDM_UART_CONFIG                 SERIAL_8N1                          //default hardware uart config 

endif

if defined ( ESP8266 ) && !defined ( SWAPHWSERIAL )

#define SWAPHWSERIAL                    0                                   //(only esp8266) when hwserial used, then swap uart pins from 3/1 to 13/15 (default not swap)

endif

if defined ( ESP32 )

#if !defined ( SDM_RX_PIN )
  #define SDM_RX_PIN                    -1                                  //use default rx pin for selected port
#endif
#if !defined ( SDM_TX_PIN )
  #define SDM_TX_PIN                    -1                                  //use default tx pin for selected port
#endif

endif

else

if defined ( ESP8266 ) || defined ( ESP32 )

#if !defined ( SDM_UART_CONFIG )
  #define SDM_UART_CONFIG               SWSERIAL_8N1                        //default softwareware uart config for esp8266/esp32 :::::::
#endif

endif

// #if !defined ( SDM_RX_PIN ) || !defined ( SDM_TX_PIN ) // #error "SDM_RX_PIN and SDM_TX_PIN must be defined in SDM_Config_User.h for Software Serial option)" // #endif

if !defined ( SDM_RX_PIN )

#define SDM_RX_PIN                      -1

endif

if !defined ( SDM_TX_PIN )

#define SDM_TX_PIN                      -1

endif

endif

if !defined ( MAX_MILLIS_TO_WAIT )

define MAX_MILLIS_TO_WAIT 500 //default max time to wait for response from SDM !!!!

endif

//------------------------------------------------------------------------------

define FRAMESIZE 9 //size of out/in array !!!!!!!!!

define SDM_REPLY_BYTE_COUNT 0x08 //:: 0x04 //number of bytes with data !!!!!!

define SDM_B_01 0x01 //BYTE 1 -> slave address (default value 1 read from node 1) !!!!!!!

define SDM_B_02 0x03 //::: //BYTE 2 -> function code (default value 0x04 read from 3X input registers) !!!!!! ::::::::

                                                                            //BYTES 3 & 4 (BELOW)

//ORNO registers

define ORNO_L1_VOLTAGE 0x000E //V /////////////

define ORNO_L2_VOLTAGE 0x0010 //V /////////////

define ORNO_L3_VOLTAGE 0x0012 //V /////////////

define ORNO_L1_CURRENT 0x0016 //A /////////////

define ORNO_L2_CURRENT 0x0018 //A /////////////

define ORNO_L3_CURRENT 0x001A //A /////////////

define ORNO_FREQUENCY 0x0014 //HZ /////////////

define SDM_B_05 0x00 //BYTE 5 !!!!!!

define SDM_B_06 0x02 //BYTE 6 !!!!!!!!!

//------------------------------------------------------------------------------

define SDM_ERR_NO_ERROR 0 //no error

define SDM_ERR_CRC_ERROR 1 //crc error

define SDM_ERR_WRONG_BYTES 2 //bytes b0,b1 or b2 wrong

define SDM_ERR_NOT_ENOUGHT_BYTES 3 //not enough bytes from sdm

define SDM_ERR_TIMEOUT 4 //timeout

//------------------------------------------------------------------------------ class SDM { public:

if defined ( USE_HARDWARESERIAL ) //hardware serial

if defined ( ESP8266 ) // on esp8266

SDM(HardwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN, int config = SDM_UART_CONFIG, bool swapuart = SWAPHWSERIAL);

elif defined ( ESP32 ) // on esp32

SDM(HardwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN, int config = SDM_UART_CONFIG, int8_t rx_pin = SDM_RX_PIN, int8_t tx_pin = SDM_TX_PIN);

else // on avr

SDM(HardwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN, int config = SDM_UART_CONFIG);

endif

else //software serial

if defined ( ESP8266 ) || defined ( ESP32 ) // on esp8266/esp32

SDM(SoftwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN, int config = SDM_UART_CONFIG, int8_t rx_pin = SDM_RX_PIN, int8_t tx_pin = SDM_TX_PIN);

else // on avr

SDM(SoftwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN);

endif

endif

virtual ~SDM();

void begin(void);
float readVal(uint16_t reg, uint8_t node = SDM_B_01);                       //read value from register = reg and from deviceId = node
uint16_t getErrCode(bool _clear = false);                                   //return last errorcode (optional clear this value, default flase)
uint16_t getErrCount(bool _clear = false);                                  //return total errors count (optional clear this value, default flase)
uint16_t getSuccCount(bool _clear = false);                                 //return total success count (optional clear this value, default false)
void clearErrCode();                                                        //clear last errorcode
void clearErrCount();                                                       //clear total errors count
void clearSuccCount();                                                      //clear total success count

private:

if defined ( USE_HARDWARESERIAL )

HardwareSerial& sdmSer;

else

SoftwareSerial& sdmSer;

endif

if defined ( USE_HARDWARESERIAL )

int _config = SDM_UART_CONFIG;

if defined ( ESP8266 )

bool _swapuart = SWAPHWSERIAL;

elif defined ( ESP32 )

int8_t _rx_pin = -1;
int8_t _tx_pin = -1;

endif

else

if defined ( ESP8266 ) || defined ( ESP32 )

int _config = SDM_UART_CONFIG;

endif

int8_t _rx_pin = -1;
int8_t _tx_pin = -1; 

endif

long _baud = SDM_UART_BAUD;
int _dere_pin = DERE_PIN;
uint16_t readingerrcode = SDM_ERR_NO_ERROR;                                 //4 = timeout; 3 = not enough bytes; 2 = number of bytes OK but bytes b0,b1 or b2 wrong, 1 = crc error
uint16_t readingerrcount = 0;                                               //total errors counter
uint32_t readingsuccesscount = 0;                                           //total success counter
uint16_t calculateCRC(uint8_t *array, uint8_t num);
void flush();                                                               //read serial if any old data is available
void dereSet(bool _state = LOW);                                            //for control MAX485 DE/RE pins, LOW receive from SDM, HIGH transmit to SDM

};

endif //SDM_h`

and this is read data code :

read_data.ino

`

include "SDM.h"

define ID_note 1

define de_pin 3

if defined ( USE_HARDWARESERIAL )

SDM sdm(Serial, 9600, de_pin);

else

include

SoftwareSerial swSerSDM(SDM_RX_PIN, SDM_TX_PIN); //10-rx, 11-tx
SDM sdm(swSerSDM, 9600, de_pin);

endif

void setup() { Serial.begin(9600);
sdm.begin();
}

void loop() {

Serial.println("..............................");

Serial.print("Voltage: "); Serial.print(sdm.readVal(ORNO_L3_VOLTAGE ), ID_note);
Serial.println("V");

delay(50);

Serial.print("Current: "); Serial.print(sdm.readVal(ORNO_L3_CURRENT ), ID_note);
Serial.println("A");

delay(50);

Serial.print("Power: "); Serial.print(sdm.readVal(ORNO_FREQUENCY ), ID_note);
Serial.println("W"); delay(50);

Serial.print(sdm.getErrCode());

delay(1000);
}`

this is an example of monitoring for my energy-meter, baudrait is 9600, Even, 8, 1

exm

i get always nan value on serial monitor

Voltage: nanV Current: nanA Power: nanW 4.............................. Can you help me please !

reaper7 commented 4 years ago

Sorry but I can't help you too much...

look at the frame you send using the original program (WRITE): wr1

and compare with this: https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.cpp#L82

first byte is a node id and looks good == 0x01,

third and fourth byte looks good too, because they specify the register number we want to read (0x00, 0x0e),

fifth and sixth byte looks good too, your program and this library sends 0x00 and 0x02

but note the second byte ! ! ! My lib send 0x04 value at this position (read from 3X input registers): https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.h#L76

but Your program reads values from another register (holding registers), and send 0x03 value as second byte...

so...try to change defined SDM_B_02 value from 0x04 to 0x03 at: https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.h#L76

oussama415 commented 4 years ago

i think i have a problem with configuration how can i modify configuration like this ex2

reaper7 commented 4 years ago

in SDM_Config_User.h uncomment and / or modify the appropriate values in the right places depending on whether you use hardware or software serial

#define SDM_UART_BAUD                       9600

#if defined ( USE_HARDWARESERIAL )
#define SDM_UART_CONFIG                   SERIAL_8E1         //if hardware serial (parity EVEN)
#else
#define SDM_UART_CONFIG                   SWSERIAL_8E1   //if software serial (parity EVEN)
#endif
reaper7 commented 4 years ago

closed due to inactivity

max321321231 commented 4 years ago

hey @oussama415 ,

I have the same problem as you, did you find a solution?

CSchoch commented 4 years ago

I've done that already. You can check out: Its not based on that library and only reads the MeterData https://github.com/CSchoch/OR_WE_Energy_Meter