Go Down

Topic: rms Voltage (Read 5687 times) previous topic - next topic

charliesixpack

#15
Sep 07, 2014, 02:19 pm Last Edit: Sep 07, 2014, 02:39 pm by charliesixpack Reason: 1
You will find that
Code: [Select]
(unsigned long)( adc_raw * adc_raw) does not give the same result as
Code: [Select]
(unsigned long) adc_raw * (unsigned long)adc_raw  I don't know why.  It just doesn't on the uno.  I believe it will also work correctly if you initially define adc_raw as an unsigned long.

For debugging I recommend starting with the simplest possible case.  Try testing your code on a DC voltage first.  You can connect the 3.3V output pin to the A3 input.  Your rms calculation should give 3.3V.    

nilton61

That would be because adc_raw is a signed int that will take negative values for samples below 510 sample points i OP code.
I believe casting a negative value into an unsigned long  will sign extend the value, that is setting all bits missing bits to 1.  Since the result is to be interpreted as an unsigned number it would be a very large one.

So (unsigned long) (adc_raw*adc_raw) would yield  the right result for negative values

charliesixpack


That would be because adc_raw is a signed int that will take negative values for samples below 510 sample points i OP code.

The problem exists even for all positive values for adc_raw.  For a DC input voltage of 3.3V and setting adc_raw = analogRead(3) you will get constant values of 681 for adc_raw.  Still, the problem exists.

tmd3

Code: [Select]
(unsigned long)( adc_raw * adc_raw) does not give the same result as
Code: [Select]
(unsigned long) adc_raw * (unsigned long)adc_raw I don't know why.  It just doesn't on the uno. 
It's because the Uno uses 16-bit integers, and the values of adc_raw are bigger than 8 bits, so their product overflows an integer calculation on the Uno.  adc_raw  is type int, so the calculation is dutifully carried out with integer math. When the result is bigger than 16 bits, the calculation overflows and information is lost.  The reason that it doesn't work on the Uno, and might on some other platforms, is that Uno integers are 16 bits, and they're bigger on some other machines.

I'd prefer to cast adc_raw as long, since it clearly takes on negative values.  The calculation yields the same result either way, on account of the miracle of two's complement arithmetic, but I'm more comfortable closer to the mathematical realities of the problem.

The other thing that rankles about the original program is the nominal sample rate at 1 per 100 us.  A standard analogRead() takes a bit longer than that, so the timing will always be off.

charliesixpack


Code: [Select]
(unsigned long)( adc_raw * adc_raw) does not give the same result as
Code: [Select]
(unsigned long) adc_raw * (unsigned long)adc_raw I don't know why.  It just doesn't on the uno. 
It's because the Uno uses 16-bit integers, and the values of adc_raw are bigger than 8 bits, so their product overflows an integer calculation on the Uno.  adc_raw  is type int, so the calculation is dutifully carried out with integer math. When the result is bigger than 16 bits, the calculation overflows and information is lost.  The reason that it doesn't work on the Uno, and might on some other platforms, is that Uno integers are 16 bits, and they're bigger on some other machines.


Finally, someone who knows what they are talking about.

Nadine100

hi,

below is a simplified version of the schematic. As you can see, the Nerve Stimulator outputs a square pulse of current. It is a Stimuplex HNS 11 by Braun.


Grumpy_Mike

#21
Sep 09, 2014, 06:20 pm Last Edit: Sep 09, 2014, 06:23 pm by Grumpy_Mike Reason: 1

hi,

below is a simplified version of the schematic. As you can see, the Nerve Stimulator outputs a square pulse of current. It is a Stimuplex HNS 11 by Braun.


Where ?

Anyway you have a nerve, with all those request to post your code correctly ignored and then you expect help. Do you think you deserve it?

nilton61

The measurents i made in a TNS (on myself) revelaed to follwing:


  • A TNS is a pulsed current source. This implies that there must a impedance in the circuit in order for it to function. Skin/body impedance can vary a lot since it is influenced by a multitude of parameters: contact area, electrolyte concentration, voltage, individual variants and so on. 

  • The pulses are about 180us in duration and have a a variable ampitude from 0 to about 60mA. The short duration makes it safe to use even these high amplitudes. But they are very painful if applied directly. The pulse frequency can be adjusted up to several pulses/sec



Since the duty factor of the pulses is extremely low the rms current will also be very low

Go Up