SML Reader for smart home energymeter

Hi Guys,

I found an example code for a IR-Device reading the information of the enerymeter here on Github

which I could change to work with my energy meter which is from another brand.

But there is something wrong with the units. e.g. if i have an energyconsumtion of 53.5W the programm gives out 535W.

part of the code which searches for the sequence and handles the convertion is this part:

// Extracts the decimal power value from a valid sml message
unsigned long sml_get_power(unsigned char message[], unsigned int len){
  unsigned char sml_powerseq[] = {
    0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01,
    0x01, 0x62, 0x1B, 0x52, 0xFF, 0x55
  }; // SML power sequence (Wirkleistung)
  const unsigned int sml_powerval_size = 4; // Size of value containing power in SML message (4 bytes = long)
  union {
    unsigned char raw[sml_powerval_size];
    unsigned long val;
  } power;
  unsigned char* pch;

  // Search sml_powerseq in message
  pch = find_sequence(message, len, sml_powerseq, sizeof(sml_powerseq));
  if (pch != NULL) {
    // Move pointer pch to raw power value
    pch = pch + sizeof(sml_powerseq);

    // Extract power by copying its values to union 'power'
    for (unsigned int i = 0; i < sml_powerval_size; i++){
      power.raw[i] = pch[i];
    }

    byteswap(power.raw, sizeof(power.raw)); // Swap endianness
    Serial.print("Current power (W): ");
    Serial.println(power.val);
    return power.val;
  }

this code is far above my knowledge. Could someone help me to get the right units, or tell me how to convert it to another value which can be divided by 10?

Thx guys

try replacing these portions of the code

unsigned long sml_get_power(unsigned char message[], unsigned int len){

and

Serial.println(power.val);
return power.val;

with:

float sml_get_power(unsigned char message[], unsigned int len){

and

float calcPower =  power.val/10.0;   
Serial.println(calcPower);
return calcPower;

respectively

hope that helps...

it is often awkward to deal with floating-pt numbers used to represent values with fractions. the values are scaled up by 10, 100 and integers used to represent then.

sml_get_power () returns an integer

does the value simply need to be divided by 10?

Yes, I think so. as described the output is 535W instead of 53.5W which would be correct.

I will try this. Thank you. Will tell you if it has worked.

I decided to chance your recommendation to

float calcPower =  power.val * 0.1;
    Serial.print("Current power (W): ");
    Serial.println(calcPower);
    return power.val;

because I wanted the original values to stay as they were...just to not mess up with other parts in the code and it worked perfectly. Thank you!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.