emonTx v3.4 rms voltage in USA, and raw Tx data units?

Hi, I am trying to breakdown everything that the emonTx is doing in order to translate the raw data that it transmits to a RFM69CW on my raspi. I am in the USA.

I have two questions:


When connecting to my emonTx for debug I get:

emonTx V3.4 Discrete Sampling V2.80
No EEPROM config
RFM69CW Node: 8 Freq: 433Mhz Group: 210
POST.....wait 10s
'+++' then [Enter] for RF config mode
CT 1 Cal 90.90
CT 2 Cal 90.90
CT 3 Cal 90.90
CT 4 Cal 16.67
RMS Voltage on AC-AC  is: ~249V
AC-AC detected - Real Power measure enabled
assuming pwr from AC-AC (jumper closed)
USA mode active
Vcal: 130.00
Phase Shift: 1.70
CT 1 detected
CT 2 detected
CT 3 detected
CT 4 detected
No temperature sensor

It appears that the emonTx is assuming that I am NOT in USA somewhere to determine my AC-AC Vrms (because it is reported as 249V, but it should be ~125V). Am I right that this is incorrect? How do I fix it?

I have looked through some of the EmonLib code, but I do not see where the actual calculations are performed - it very nicely abstracted :wink:


This piece really has multiple questions, but what I’m driving toward is converting the raw emonTx transmitted data into watts from the CT’s.

From the debug code above, are the CT1 and CT2 values reported in watts (in the last line)? Where is that calculation performed? (Could it also be assuming 230V system?) The values are in the expected neighborhood ( a few hundred watts).

What are the units of the raw data transmitted from the emonTx?
When I convert some typical raw values from the the emonTx CT1 I get nowhere near the neighborhood that I would expect. For example: [203 255] → 203+256*255 = 65,483 W. My little house is not consuming 65kW! (and that is only one feed). Am I doing something wrong? How do I translate the data?!



There is a DIP switch to set the USA voltage.[quote=“nicklaws, post:1, topic:3480”]
I have looked through some of the EmonLib code, but I do not see where the actual calculations are performed - it very nicely abstracted

You don’t need to touch emonLib. The voltage is an input parameter when initialising the class instance.[quote=“nicklaws, post:1, topic:3480”]
What are the units of the raw data transmitted from the emonTx?

Engineering values - in some cases multiplied by 10 or 100 to preserve decimal information whilst still sending the data as a 2-byte integer. If you look at the sketch, you’ll see the multipliers where the values are assigned to the structure members.

No, but it might be twice what you expect at twice the voltage! Remember, your voltage calibration is totally wrong, so the powers will be too. P = V × I. Also remember that the power is signed.

It is set to USA. So how is RMS Voltage on AC-AC is: ~249V calculated for the debug output?

Still wondering where the debug output gets the ct values of -307 (for example).

I have a master’s degree in engineering. I am looking for SI units: watts for example.

Even double is way too high (see comment in original post that a few hundred watts is what I’m expecting, Maybe a few kW, but not dozens of kW).

And I’m a Chartered Electrical Engineer.

Have you looked at the source code in the sketch? The sketches do get updated from time to time, but there’s no mechanism to give notice of the changes, so I don’t necessarily know what the latest sketch does.

It would appear that the DIP switch is not being read, or it’s in the wrong position, or it’s been set after the sketch started (as it is only read at start-up), or the switch is faulty.

Line 462 et seq in the sketch. Power is in watts. Voltage is × 100 (centivolts? !)
So is 307 W (by convention: -ve = export) a reasonable value? It would be sent as 205 254 in decimal bytes (0xFECD).

Regarding the debug RMS voltage:

from src.ino:

double vrms = calc_rms(0,1780) * 0.87;

double calc_rms(int pin, int samples)
  unsigned long sum = 0;
  for (int i=0; i<samples; i++) // 178 samples takes about 20ms
    int raw = (analogRead(0)-512);
    sum += (unsigned long)raw * raw;
  double rms = sqrt((double)sum / samples);
  return rms;

Serial.print("RMS Voltage on AC-AC  is: ~");
Serial.print(vrms,0); Serial.println("V");

What is the 0.87 for?

I assume that the supply voltage is connected to pin zero across a resistor: is this resistor calibrated for 230V?

(Note that calc_rms assumes that pin=0).

Yes 307 W is reasonable. How did you get the 205 254? I thought that the formula was
205 + 256*254 = 65,229

Definitely not set after sketch started (I set it about a year ago when I first got emonTx). I updated the sketch last week. If the dip switch was faulty/not set correctly, would I still see the correct vrms value in the debug output (which I am)?

It seems very odd that vrms reported via the 10 second interval data is correct (12249 centi-volts ;)), yet the RMS Voltage on AC-AC is: ~249V is not correct. :anguished:

That (double vrms = …) is a very rough calculation to determine whether there’s an a.c. adapter present and giving roughly the correct voltage. It is not used once the initialisation is complete.

Each a.c adapter gives roughly - not exactly, the 3 models all have slightly different calibration constants - the same output voltage at the nominal supply voltage. In your case (assuming you have an Ideal 77DA-10-09), it is 12.0 V ±5% with 120 V input on no load. Therefore, once the correct a.c. adapter is selected, the calibration is purely in software. The divider chain only needs changing if a different transformer is used that gives a substantially different output to the standard adapters.

I did tell you it was signed. So the top bit of “254” is the sign bit.

The switch has been read at that point, so it appears to be a Glyn-type slip-up. Not being your side of the pond, I’ve never felt a need to check. It would appear that Glyn didn’t either. As I wrote above, that bit of code is there for one purpose only - to set the default 120 or 230 V for the calculations if the adapter input isn’t there.

What is the sign bit? How, in math, did you get 205 254?

“two’s compliment” so 205 + (254*256) does make 65229. But as its a signed number and beyond the scope of a 16bit signed int (32767) so we subtract 65536.

Or vise versa -307 is a negative number so add 65536 = 65229 /256 = 254 remainder 205

Thanks Paul,

Let me make sure I understand this conversion correctly. In pseudo code, if have two decimal bytes (correct nomenclature?) called a and b, then to convert them to the decimal integer value:

if (a + b*256) < (2^16/2):
    return (a + b*256)
    return -1*( (a + b*256) - 2^16)


Almost, I don’t think you need the “-1*” as that would make it a positive number.

[EDIT] although I would have probably expressed it as (pseudo code)

x= (a + (b*256)) 
if x > (2^16/2)
    x = (x - (2^16)) 
return x

ah yes thanks! This is what I have been trying to figure out all week!

You need to be looking at “Two’s complement” numbers here, extended of course to 16 bits for our signed integers.

The 0.87 is (Vcal * (3.3/1024) assuming Vcal=268.97 as is the case for 240V.

Obviously this will be wrong if Vcal USA is used (when USA dip switch is enabled) Vcal_USA=130.0.

I have emended the initial calculation of Vms to use the actual value of Vcal:

double vrms = calc_rms(0,1780) * (Vcal * (3.3/1024) );

Firmware version has been bumped to V2.9. Thanks for letting me know.

Thanks Glyn!