Hi,
I'm working on a project in which I measure two signals using the adc10 command and convert these to current in mA and voltage in mV. I then calculate a power in mW by multiplying voltage and current together.
What I'd like to do next is to integrate the power measurement using a known, constant time step to calculate energy in mWh. In order to do this correctly, I need to be able to control the program's iteration time so that it is equal to the constant value used in the calculation. I would like to be able to specify an iteration time with a resolution of say 10ms (so 10ms, 20ms or 110ms etc. would be possible iteration times). The time required for program execution shall then be some fraction of the iteration time, and the next iteration is not started until the time for the current iteration has elapsed i.e. having executed the entire program, the PicAxe waits for the remainder of the time before continuing with the next iteration. Below is my program, in which I assume for the moment that the iteration time is 1 second.
I've searched a lot on the forum and on the internet in general. It seems one way to achieve a fixed iteration time is to use a crystal oscillator or real time clock to trigger code execution using an external interrupt. There seems to also be another, less accurate way using the internal RC oscillator of the PicAxe itself and the Timer1 command. As simplicity is more important than accuracy for this project, I would prefer to use the latter method, if possible.
I found this thread on the topic http://www.picaxeforum.co.uk/showthread.php?5824-Timer1-a-possible-simple-use-for-it/page2 and tried the test example posted by forum member Jeremy Leach. The test program should output 'Paused = Xms. Measured = Yms.' where X and Y are approximately equal and increasing with each program iteration. However, when I ran it in the simulation mode of my PicAxe Editor V6.0.8.8, I only saw 'Paused = Xms. Measured = 0ms.' on the serial terminal, i.e. only X was increasing. When I downloaded the program to my PicAxe 08m2, the following was displayed on the serial terminal:
Can someone please advise me as to why the test program didn't work for me?
Could the Timer1 method allow me to achieve a constant iteration time on an 08m2?
Hope someone can help. Thanks.
I'm working on a project in which I measure two signals using the adc10 command and convert these to current in mA and voltage in mV. I then calculate a power in mW by multiplying voltage and current together.
What I'd like to do next is to integrate the power measurement using a known, constant time step to calculate energy in mWh. In order to do this correctly, I need to be able to control the program's iteration time so that it is equal to the constant value used in the calculation. I would like to be able to specify an iteration time with a resolution of say 10ms (so 10ms, 20ms or 110ms etc. would be possible iteration times). The time required for program execution shall then be some fraction of the iteration time, and the next iteration is not started until the time for the current iteration has elapsed i.e. having executed the entire program, the PicAxe waits for the remainder of the time before continuing with the next iteration. Below is my program, in which I assume for the moment that the iteration time is 1 second.
Code:
#Rem
################################################## #######
# Current, voltage, power and energy meter.
# B.Dolan July 2016.
################################################## #######
This module measures current and voltage, and from these
calculates power and energy.
#endrem
Start:
SYMBOL mAmp = W0
SYMBOL mVolt = W1
SYMBOL mWatt = W2
SYMBOL mWattSeconds = W3
SYMBOL mWattHours = W5
SYMBOL mWattHeadroom = W6
SYMBOL mWattHoursLessThan18 = W7
Main:
FVRSETUP FVR2048 'Set reference voltage to 2.048V for battery operation.
ADCCONFIG %011
readadc10 C.1, mAmp
readadc10 C.4, mVolt
#Rem
Current --------------------------------
Current (A) = 2.048*ADCin/1024 = ADCin/500.
Current (mA) = 1000*ADCin/500 = ADCin*2.
Max current = 1024*2 = 2048 (mA).
Resolution = 2 (mA).
#endrem
mAmp = mAmp*2
#Rem
Voltage --------------------------------
R1 = 30kOhm, R2 = 5kOhm => Vin = Vout*7.
Vout (V) = 2.048*ADCin/1024 = ADCin/500.
Vout (mV) = 1000*Vout = 1000*ADCin/500 = ADCin*2.
Vin (mV) = Vout*7 (mV) = ADCin*2*7 = ADCin*14.
Max voltage = 1024*14 = 14336 (mV).
Resolution = 14 (mV).
#endrem
mVolt = mVolt*14
#Rem
Power = Voltage*Current ----------------
Credit to PicAxe forum member 'hippy' for this
little trick here.
#endrem
mWatt = mAmp*34**63164
mWatt = mVolt*2**mWatt
#Rem
Energy meter --------------------------
Assume code executed with a cycle time of 1 second.
Assuming the power remained constant over the 1 second interval, this implies that
the instantaneous power measurement is also the accumulated
energy over the past interval of 1 second, with units of mWs (milliWatt-seconds).
Energy in mWs will quickly become a huge number, so we want energy in mWh.
3600 is the number of seconds in one hour => mWh = mWs/3600.
64800 is the highest integer number less than 65536, which when divided by 3600,
results in an integer value.
2^16 = 65536 -> 65536/3600 = 18.2 -> Round(18.2) = 18 -> 3600*18 = 64800.
Check how many more mWs we can count before exceeding our limit,
then compare this value to the current power (which is also energy in mWs) reading.
Note: mWattSeconds <= 64800 for all time.
#endrem
mWattHeadroom = 64800 - mWattSeconds
IF mWattHeadroom < mWatt THEN
'If we don't have enough 'headroom', then increment the counter (meaning we have
'filled our quota of 64800 mWs, which equates to 18 mWh)...
mWattHours = mWattHours + 18
'..and store the amount of overflow in mWs.
mWattSeconds = mWatt - mWattHeadroom
ELSE
'If we do have enough 'headroom', then add the current power (which is also energy in mWs)
'reading to the previously accumulated energy value to give the total.
mWattSeconds = mWattSeconds + mWatt
ENDIF
'mWh = mWh + mWs/3600 = mWattHours + mWattSeconds/3600
mWattHoursLessThan18 = mWattSeconds/3600
mWattHours = mWattHours + mWattHoursLessThan18
sertxd("Current [mA]: ",#mAmp,CR,LF)
sertxd("Voltage [mV]: ",#mVolt,CR,LF)
sertxd("Power [mW]: ",#mWatt,CR,LF)
sertxd("Energy [mWh]: ",#mWattHours,CR,LF)
goto main
I found this thread on the topic http://www.picaxeforum.co.uk/showthread.php?5824-Timer1-a-possible-simple-use-for-it/page2 and tried the test example posted by forum member Jeremy Leach. The test program should output 'Paused = Xms. Measured = Yms.' where X and Y are approximately equal and increasing with each program iteration. However, when I ran it in the simulation mode of my PicAxe Editor V6.0.8.8, I only saw 'Paused = Xms. Measured = 0ms.' on the serial terminal, i.e. only X was increasing. When I downloaded the program to my PicAxe 08m2, the following was displayed on the serial terminal:
Can someone please advise me as to why the test program didn't work for me?
Could the Timer1 method allow me to achieve a constant iteration time on an 08m2?
Hope someone can help. Thanks.