Display wrong value

Hello,

I’m currently working on my EPEVER charge controller project, part of this project is to display a “energy generated by Solar”. I was able to get the value to display on Blynk or serial monitor BUT the value does not display correct number.

For example, the actual value from device shown 1.82 kWh but the output from serial monitor show 614

What did I do wrong?
Did I missed anything?

Below is the register value (full data sheet from HERE)

Commercial Photography

and here is the code that display wrong value for Consumed Energy Daily

void AddressRegistry_3304() {
  result = node.readInputRegisters(0x3304, 2);
  if (result == node.ku8MBSuccess)
  {
   CEtoday = ((((long)node.getResponseBuffer(0x05) << 16 | node.getResponseBuffer(0x00)) / 100000000.0f));
    if (debug == 1) {
      Serial.print("DAILY_ENERYGY_CONSUMED: ");
      Serial.println(CEtoday);
    }

    } else {
    rs485DataReceived = false;
  }
}

Please note that other value like “Generate or Consumed” energy MONTH or YEAR are all display correct value.

Here is the code for Consumed Energy Monthly which is display CORRECT value

 void AddressRegistry_3306() {
  result = node.readInputRegisters(0x3306, 2);
  if (result == node.ku8MBSuccess)
  {
    CEmonth = ((long)node.getResponseBuffer(0x07) << 16 | node.getResponseBuffer(0x00)) / 100.0f;
    if (debug == 1) {
      Serial.print("CONSUMED_ENERGY_MONTH: ");
      Serial.println(CEmonth);
    }

    } else {
    rs485DataReceived = false;
  }
}

This is a non Blynk related question.

However I don’t know why you’re /100000000.0f on the first part of your code.

I think the issue is with reading the buffer, you should node.getResponseBuffer(1) since you’re only reading 2 registers each time.

The second code working is just a coincidence I think, because the number may not be too big to use the extra 16bits.

Hi,

I am reading floats via RS485 ModBus so it is similar, I suggest to try code like this:

  {
      union { uint16_t u[2]; unsigned long r; } meterdata;
      meterdata.u[0] = node.getResponseBuffer(1);  meterdata.u[1] = node.getResponseBuffer(0);
      Serial.print(meterdata.f);
  }

Note the data is stored according to your datasheet in Little-Endian format, so I think your code has the registers the wrong way around?

Also for some reason with my meter / library I have to request one address lower than desired - but if yours is working for some registers then that is unlikely to be the case.

Hi ldb,
thank you for your response.
the " /10000000000.0f " is for decimal that I play around with.

After changing the code as your recommended, I get the output of 0.00 which is NOT the right number from controller itself.

 void AddressRegistry_3304() {
  result = node.readInputRegisters(0x3304, 2);
  if (result == node.ku8MBSuccess)
  {
   CEtoday = (long)node.getResponseBuffer(1) / 100.0f;
//   CEtoday = ((((long)node.getResponseBuffer(0x05) << 16 | node.getResponseBuffer(0x00)) / 100.0f));
    if (debug == 1) {
      Serial.print("DAILY_ENERYGY_CONSUMED: ");
      Serial.println(CEtoday);
    }

    } else {
    rs485DataReceived = false;
  }
}

That’s not what I meant, should be something like:
CEtoday = ((node.getResponseBuffer(1) << 16) | node.getResponseBuffer(0)) / 100.0f;

Edit:
is CEtoday declared as Float?

Hi ldb,
it works :+1:. I can see the correct value now.
Thank you, thank you and thank you :pray:

Do you know why i’m getting a garbage at the beginning of the line as shown below?

Commercial Photography

This is probably due different Baud rate or using Serial.println as the Serial Print will be on the Same TX/RX pins unless you use the Software Serial to Debug