I don't think using joules makes the calculation any easier. One joule is one watt for one second, and you still have to convert that to watt hours.
If your meter blinks once for every watt hour of electricity used the calculations are pretty simple.
For total power consumed over a period of time (second/minute/hour/day/week/month) zero the count at the beginning of the period and increment the count by 1 for each pulse.
Repeat for each blink:
>>watthoursused=watthoursused + 1
At the end of the desired time the total count = the watt hours used. If you save the reading every hour and reset watthoursused to 0 you would have 168 readings per week. Add them up for whatever period the utility bills you for and the totals should match.
For the instantaneous power (calculated for every pulse) the calculation would be:
instantaneouswatthoursused = 3600/deltatime
where 3600 is the number of seconds in an hour and deltatime is the time between the leading edge of two consecutive pulses. If the pulses are always the same width it does not matter if you use the leading or trailing edge.
If you can measure the deltatime accurately enough you might be able to detect the change caused by a bulb being turned on or off. If that is the case you might want to store the instantaneous reading and date/time every time a change of that magnitude occurs.
The key to the whole thing is how much energy each pulse represents. If it is 1 watt hour per pulse these calculations should be dead on.
BTW - If you are measuring time in milliseconds use 3,600,000 instead of 3,600 and you can use fixed point math instead of floating point.
Right now, I am tinkering with the best method to track the wattage without using excessive database calls for every blink of the light. I have my VB program talking to my MySql database and it is able to insert a row when needed, but I think storing every single value will take up quite a bit of memory and database size on the server.
Not sure if this is feasible option, but I am thinking of using the Prop to store each delay between pulses for 1 minute in an array. After that minute, it will start sending the array to the VB program or will calculate the watt hours used in that minute then send that to the VB program. The VB program will store the data for 10 minutes and which will then update the database for later viewing.
One thing I am not quite understanding is how to convert the watt calculation I am getting into watt hours. If the reading is 900 watts for 10 minutes, then my AC kicks on and bumps up the wattage to 6000 for 10 minutes, then the watt reading goes back to 900 for the remaining 40 minutes in a 1 hour span, how would I convert this to watt hours?
I am thinking something like this :
6000 watts / 10 minutes = 600 watt hours + 900 watts for the rest of the hour = 1500 watt hours
One thing I am not quite understanding is how to convert the watt calculation I am getting into watt hours. If the reading is 900 watts for 10 minutes, then my AC kicks on and bumps up the wattage to 6000 for 10 minutes, then the watt reading goes back to 900 for the remaining 40 minutes in a 1 hour span, how would I convert this to watt hours?
10 minutes is 10/60 of an hour. So 900 watts for 10 mins is 900 * 10/60 = 150 watt hours.
Dr_Acula's calculation is the way to calculate the power.
There is a simpler way to do what you seem to want. The watthoursused from my previous post has the number of watt hours used since the count was set to zero. If you save that to your database along with the time and date, and then zero the count every time there is a significant change in the instantaneouswatthoursused you will get data that outlines how much power was used at any time of the day, and the sum of this data for your billing period will give the total power used.
What is the best way to keep time on the prop? I was thinking of making a cog that does nothing but keep time by using the waitcnt function to update a variable +1 ever second. I would use the serial connection between the computer to sync the timer to the top of every hour. Basically, have the VB program send a signal to the prop telling it to reset the hour counter after sending the current pulse count. If the computer is off, and the hour counter gets to 3600, it will store the pulse count in an array and increase the array pointer. Once the computer is back on, it can send the signal to tell the prop it is online and the prop could then dump the data to the computer for further processing.
Also.... How can I get this thread moved to the Prop section in the forum?
Makes sense to store data in the prop and only dump when needed - then your PC does not need to be on all the time.
A moderator will need to move the link (or start a new thread). Would make sense to have this in the propeller forum - it is a cool project you are working on.
It is a perfect example of how the prop is so clever with multiple cores - set one core to do a clock, one to look for pulses, one to handle the serial transfer and with the propeller, you can be certain that there are no pulses missed. It would be harder to do this with a standard micro.
lol... I was just browsing the OBEX and just found that when you posted. Question is....can the prop "know" how long it has been turned off or is this something I have to have a battery backup for?
I'm sure there are ways of powering the prop down a bit so that it is monitoring the pulses but not doing much else. That can mean it could run on batteries for a long time. Or maybe rechargeable batteries and when the power comes back on you recharge the batteries as well. A few diodes and resistors could do that. I've not looked at the low power modes but I think there are quite a few options there.
Well, sometimes the power glitches around here enough to reset everything. Currently the prop is running from a plug in adapter which is not strong enough to charge batteries. It is the only one that I have that I can use I tore apart my others to build tasers
I wonder how low you could get the propeller consumption. Say you got it down to 10mA, then you could trickle charge some rechargeables at, say, 20mA which is low enough they could be charging all the time without a clever charge manager, and also would be low enough that your adapter could charge the batteries and run the propeller. Then if the power goes off, it just reverts to batteries.
I am looking into getting some rechargeable batteries and a holder that can output 4.8V. I have a 7805 that outputs to a LM2937 3.3 which runs the prop. The input voltage is 9V 200ma. If adding a battery between the 2 regulators is able to be done, the 7805 could charge the batteries as well as provide enough power to run the prop. If the power goes out, the batteries are after the 7805 which could power the LM2937 to run the prop. Sound feasible? No extra circuity required other than a possible diode from the 7805 to the batteries.
Maybe I am not understanding the FullDuplexSerial program.... I am having a hard time sending a string from VB to the prop, then have the prop return it back to the VB program. Here is where the sending and receiving happen :
VB code :
Private Sub Timer2_Timer()
Dim olddata As String
Dim currentTime As String
olddata = incomingdata
If (Val(olddata) <> 0) Then
pulsecount.Caption = olddata
incomingdata = ""
'currentWattage = ((60 / (Val(olddata) / 1000)) * 100) * 60
currentWattage = 3600 / (Val(olddata) / 1000)
currentwatts.Caption = currentWattage
End If
currentTime = Hour(Now) & ":" & Minute(Now) & ":" & Second(Now)
time_display.Caption = currentTime
MSComm1.Output = "1" '---------------- Send the Prop something... in this case, the number 1.
End Sub
Prop code :
CON
_CLKMODE = XTAL1 + pll16x
_XINFREQ = 5_000_000
LED = 0
Sensor = 1
CountDelay = 10
SendInterval = 5000
VAR
BYTE countpointer
LONG counter[200]
LONG count1
LONG count2
LONG pulsewidth
LONG counterStack[200]
LONG PulseCounterStack[500]
LONG readDataStack[100]
LONG receivedData
OBJ
Ser : "FullDuplexSerial"
PUB Main
Ser.start(17, 16, 0, 9600)
cognew(sendData, @counterstack)
cognew(PulseCounter, @PulseCounterStack)
cognew(readData, @readDataStack)
repeat
waitcnt(clkfreq / 1000 * CountDelay + cnt)
PUB sendData
repeat
'receivedData := Ser.rx
waitcnt(clkfreq / 1000 * SendInterval + cnt)
Ser.dec(pulsewidth)
waitcnt(clkfreq / 1000 * 500 + cnt)
Ser.dec(receivedData)
PUB readData
repeat
receivedData := Ser.rx
PUB PulseCounter
' 65825 counts per 1 second
count1 := 0
repeat
dira[LED]~~
repeat while ina[Sensor] == 1
waitcnt(clkfreq / 1000 * 10 + cnt)
outa[LED] := 1
if count1 > 0
pulsewidth := ((count1 * 1000) / 65825) * 2
count1 := 0
count1++
outa[LED] := 0
The value displayed in the VB program that is returned is 49. I am sending it the number 1, why do I get 49 back?
In your readData method, you read it one byte at a time. This stores the ASCII value of the received byte into receivedData. Then, instead of transmitting back the character as ASCII, you are transmitting it's literal value. In readData you need to use GetDec instead of rx.
I am still having a really hard time understanding how to send anything over 255 or a string through VB6 using MSComm. If I want to send a string say the current time "11:01:36" and use that information in the prop, I need to either send each time section (Hour, minute, second) or send it as a string so I can parse it out and use what I need from the string.
I am trying to read the system clock, send that information to the prop to update the time the prop should be at (Minute and second). I know I can send a Byte through VB to the prop and it will work correctly, but.... I need to make the data reading cog as modular as possible to where I can send it a command, then a variable. Something like this :
MSComm1.Output = "UpdateClock"
MSComm1.Output = Chr$(Minute(Now))
MSComm1.Output = Chr$(Second(Now))
OR...
MSComm1.Output = "UpdateClock#" & Minute(Now) & ":" & Second(Now)
Then to do another function....
MSComm1.Output = "GetCurrentWatts"
Is this possible with the Serial communication to the Prop? If so, how?
I'm not familiar with VB, so I don't know what the CHR$ command is doing, but I'll give you protocol advice.
I would send a single "synchronization" byte (such as "%" or "$"), followed by a single byte as a command. Your command table could be:
24 - UpdateClock
25 - Read Watts
26 - ...
I choose an arbitrary starting number, which is ok as long as all numbers are less than 255. Then, following that byte would be some amount of data (format and length determined by the particular command, down to a size of zero (no data)). Finally, a stop byte could be used to indicate the end of the string (I'd select ASCII CR (13 in decimal)).
In the above example, I assume that the time is transmitted as literal byte values (ie, a received value of 65 means a number of 65, etc.). This works for hours and minutes, since they are less than 255 (1 byte). It doesn't work for the watt hours, since that can be very large. So, watt hours has to be transmitted as a series of ASCII characters that represent it's value.
Here's some code I used in an outside unit powered with 3 AA batteries. It has a Propeller, an XBee, and a Sensirion SHT11 temp/humidity sensor. It 'wakes up' every 10 minutes and sends the temperature and humidity to the inside Master unit. I get about 70 days on a set of normal alkaline batteries.
PUB cog_Send | waitPer, t
'' sends current temp/humidity to master unit
'' on a timed basis (10 min)
''
Dira[XB_SLP]~~ ' set XBee sleep pin to output
Outa[XB_SLP]~ ' output low... wake XBee
waitPer := 0 ' reset wait timer period
t := (clkfreq + cnt) ' set the counter
repeat until (waitPer == 5) ' wait for XBee to get set
waitPer += 1 ' increment the count
waitcnt(t) ' wait
t += clkfreq ' add one second
sendTemp ' initial data send
waitcnt((clkfreq / 50) + cnt) ' wait 20 msec
Outa[XB_SLP]~~ ' put XBee to sleep
waitcnt((clkfreq / 50) + cnt) ' wait 20 msec
cogStop(idTemp~ - 1) ' stop the temperature cog
_slow_prop ' slow propeller to save power
' == cog loop ==
repeat
waitPer := 0 ' reset wait timer period
t := (clkfreq + cnt) ' set the counter
repeat until (waitPer == CYCLE) ' wait until cycle time to send
waitPer += 1 ' increment the cycle timer
waitcnt(t) ' wait
t += clkfreq ' add one second to the counter
_slow_to_fast_prop ' speed up the propeller
idTemp := cognew(cog_Temps, @stackTmtr) + 1 ' launch the temp/humidity cog
Outa[XB_SLP]~ ' output low... wake XBee
waitcnt((clkfreq * 2) + cnt) ' wait 2 seconds for temp to update
sendTemp ' send the data
waitcnt((clkfreq / 50) + cnt) ' wait 20 msec
Outa[XB_SLP]~~ ' pin high... XBee asleep
cogStop(idTemp~ - 1) ' stop the temperature cog
_slow_prop ' slow propeller to save power
{
===============================================================================
}
PRI _slow_prop
'' put propeller into slowest power save speed (5 MHz - using XTAL)
clkset(%0_0_1_01_010, 5_000_000) ' 5MHz no PLL
{
===============================================================================
}
PRI _slow_to_fast_prop
'' put propeller into a fast speed (80MHz), intended to be used after propeller
'' was put in slow mode
clkset(%0_1_1_01_010, 5_000_000) ' turn on PLL, but don't use it
waitcnt(500 + cnt) ' wait 100us for PLL to stabilize
clkset(%0_1_1_01_111, 80_000_000) ' 80MHz
I can send an integer to the VB program but sending one back from the VB program is pretty difficult. I have read that i have to split a LONG into bytes and send them one by one. Then I would have to decode it back to a string on the prop. I do like the idea of using a repeat until rx = "special character". I will try that out now.
Since you will be drawing 0 power when AC power is off why not do the following:
1. Power the prop from the AC line.
2. Use a crystal for the prop clock.
3. Have a backup battery for the prop.
4. Monitor AC power availability by counting AC cycles.
5. Keep time by counting AC cycles.
6. Monitor power based on whatever criteria you use.
7. When the AC power is lost decrease prop frequency to 5MHz (1x)
8. Store power used up to that point for future transmission.
9. Use waitcnt to wake up once every second, increment the time/date counter, and see if AC power has been restored.
10. When AC power is restored send/store power used record and power outage record.
11. Continue monitoring usage and recharge battery for a period of time based on the length of the power outage.
This will minimize battery size and power usage while maximizing battery life.
Not sure how to monitor AC cycles, but I thinking monitoring AC power availability is a good idea. I will work with the power situation as soon as I get the programs working good. Right now, I am redesigning the prop program to store the pulse counts in an array and when the VB program calls for the readings, it will send each value in the array and then clear the array and reset the pointer.
Not sure how to monitor AC cycles, but I thinking monitoring AC power availability is a good idea. I will work with the power situation as soon as I get the programs working good. Right now, I am redesigning the prop program to store the pulse counts in an array and when the VB program calls for the readings, it will send each value in the array and then clear the array and reset the pointer.
Here is a basic block diagram of a power supply with AC detection. The output pulses at AC det are 120Hz pulses that are clamped to the power supply output voltage (about 0.7V higher in voltage) For a 3.3V supply that would be about 4V. A 2K resistor between the AC det output and one of the prop pins will allow you to use the signal for both the RTC and AC power monitoring. A count of 120 pulses on that pin equals one second. If there is no pulse or high for more than 8.3 mSec then AC power is missing.
I am having trouble sending text from the chip to the VB program. No matter what I try, it either hangs in the VB program trying to receive the data or a blank line is sent according to the output that is displayed on the form. How can I send a single character from the chip to the VB program?
I have tried :
Ser.tx("#")
Ser.tx(String("#")
Ser.tx(String(13, "#"))
None of these seem to work and just hang the VB program.
"tx" sends a single byte of data. The Spin "string" function will store it's argument in Hub memory as a zero terminated series of bytes, and "returns" the starting address of that string. So, Ser.tx(string("...")) will transmit the lower byte of the Hub address of the string.
The correct way to send a single character is Ser.tx("#").
That is what I try, but data between the prop and the PC stop like the VB program is hanging waiting for data to be sent or it does not understand what to do with the data.
Here is the code I have so far for the Prop :
CON
_CLKMODE = XTAL1 + pll16x
_XINFREQ = 5_000_000
LED = 0
Sensor = 1
CountDelay = 10
SendInterval = 5000
VAR
BYTE countpointer
LONG pulseData[255]
LONG pulseCount
LONG count1
LONG Time_Count_Minutes
LONG Time_Count_Seconds
LONG pulsewidth
LONG PulseCounterStack[100]
LONG readDataStack[100]
LONG receivedData
LONG TimeStack[100]
OBJ
Ser : "FullDuplexSerialPlus"
PUB Main
pulseCount := 0
Time_Count_Minutes := 0
Time_Count_Seconds := 0
countpointer := 0
Ser.start(17, 16, 0, 9600)
cognew(TimeKeeper, @TimeStack)
cognew(PulseCounter, @PulseCounterStack)
cognew(readData, @readDataStack)
repeat
if Time_Count_Seconds == 60
Time_Count_Seconds := 0
Time_Count_Minutes++
if Time_Count_Minutes == 60
pulseData[countpointer] := pulseCount
countpointer++
Time_Count_Minutes := 0
waitcnt(clkfreq / 1000 * 200 + cnt)
PUB TimeKeeper
repeat
Time_Count_Seconds++
waitcnt(clkfreq / 1000 * 1000 + cnt)
PUB readData | command, i
repeat
repeat until Ser.rx == "#"
'Ser.dec(Time_Count_Seconds)
waitcnt(clkfreq / 1000 * 10 + cnt)
command := Ser.rx
if command == 1
Time_Count_Minutes := Ser.rx
Time_Count_Seconds := Ser.rx
'Ser.dec(Time_Count_Seconds)
if command == 2
Ser.tx("#")
'Ser.tx(13)
waitcnt(clkfreq / 1000 * 500 + cnt)
Ser.dec(pulsewidth)
if command == 3
repeat i from 0 to countpointer
Ser.dec(pulseData[i])
bytefill(@pulseData,0,i - countpointer)
countpointer := 0
'Ser.rxflush
PUB PulseCounter | updated
' 65825 counts per 1 second
count1 := 0
updated := 0
repeat
dira[LED]~~
repeat while ina[Sensor] == 1
if updated == 0
pulseCount++
updated := 1
waitcnt(clkfreq / 1000 * 10 + cnt)
outa[LED] := 1
if count1 > 0
pulsewidth := ((count1 * 1000) / 65825) * 2
count1 := 0
count1++
outa[LED] := 0
And for the VB6 program :
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Dim receivingdata As String
Dim incomingdata As String
Dim receiveInterval As Integer
Dim currentWattage As Long
Dim currentTime As String
Dim count1 As Integer
Dim Minutes As Long
Dim Seconds As Long
Private strDatabaseName As String
Private strDBCursorType As String
Private strDBLockType As String
Private strDBOptions As String
Private strSQL As String
Private rs As ADODB.Recordset
Private cn As ADODB.Connection
Private Sub Form_Load()
receiveInterval = 1
Dim myport As String
If MSComm1.PortOpen = False Then
On Error GoTo No_Connect
'myport = InputBox("Which COM Port?", "COM Port Selection", "1")
With MSComm1
.CommPort = 1
.Settings = "9600,n,8,1"
.RThreshold = 1
.InBufferSize = 1024
.InputLen = 1
.InputMode = 0 - comInputModeText
.PortOpen = True
End With
Timer1.Enabled = True
Timer2.Interval = 100
Timer2.Enabled = True
Timer4.Enabled = True
constatus.Caption = "Connected to Chip"
Send2Chip (1)
Else
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
constatus.Caption = "Disconnected"
End If
On Error GoTo 0
Exit Sub
No_Connect:
Dim response
response = MsgBox("Error: Could not connect.", vbExclamation + vbOKOnly)
On Error GoTo 0
End Sub
Private Sub Form_Unload(Cancel As Integer)
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
End Sub
Private Sub Timer1_Timer()
Do
incomingdata = incomingdata + "" + MSComm1.Input
DoEvents
If MSComm1.InBufferCount = 1 Then
CommandStatus.Caption = "Information recieved from chip"
Exit Do
End If
Loop
If (incomingdata = "?") Then
CommandStatus.Caption = "Command Sent"
End If
End Sub
Private Sub Timer2_Timer()
Dim olddata As String
Dim currentTime As String
olddata = incomingdata
If (Val(olddata) <> 0) Then
pulsecount.Caption = olddata
incomingdata = ""
currentWattage = 3600 / (Val(olddata) / 1000)
currentwatts.Caption = currentWattage
End If
currentTime = Hour(Now) & ":" & Minute(Now) & ":" & Second(Now)
time_display.Caption = currentTime
End Sub
Private Function updateMySql()
On Error GoTo Connection_Error
Dim b As Long
strDBCursorType = adOpenDynamic 'CursorType
strDBLockType = adLockOptimistic 'LockType
strDBOptions = adCmdText 'Options
Set cn = New ADODB.Connection
Me.MousePointer = 11
cn.Open ConnectString()
cn.Execute "INSERT INTO power (watts) VALUES ('" & currentWattage & "')"
ExitSub:
cn.Close
Set cn = Nothing
On Error GoTo 0
Me.MousePointer = 0
Exit Sub
Connection_Error:
Text1.Text = "Error " & Err.Number & " (" & Err.Description & ") " & "in procedure Command1_Click of Form " & Me.Name
Me.MousePointer = 0
End Sub
Private Function ConnectString() As String
Dim strServerName As String
Dim strDatabaseName As String
Dim strUserName As String
Dim strPassword As String
strServerName = "********"
strDatabaseName = "********"
strUserName = "********"
strPassword = "********"
ConnectString = "DRIVER={MySQL ODBC 3.51 Driver};" & _
"SERVER=" & strServerName & _
";DATABASE=" & strDatabaseName & ";" & _
"USER=" & strUserName & _
";PASSWORD=" & strPassword & _
";OPTION=3;"
End Function
Private Sub Timer3_Timer()
Dim sql
'sql = updateMySql()
End Sub
Private Sub Timer4_Timer()
Minutes = Minute(Now)
Seconds = Second(Now)
If (Minutes = 30) And (Seconds = 0) Or (Minutes = 59) And (Seconds = 0) Then
Send2Chip (1)
End If
Send2Chip (2)
End Sub
Private Function Send2Chip(what As Byte)
Minutes = Minute(Now)
Seconds = Second(Now)
If (what = 1) Then
CommandStatus.Caption = "Sending Command 1"
' Sync Chip Time to System Time
MSComm1.Output = "#"
MSComm1.Output = Chr$("1")
MSComm1.Output = Chr$(Minutes)
MSComm1.Output = Chr$(Seconds)
ElseIf (what = 2) Then
CommandStatus.Caption = "Sending Command 2"
' Get current watt usage
MSComm1.Output = "#"
MSComm1.Output = Chr$("2")
ElseIf (what = 3) Then
CommandStatus.Caption = "Sending Command 3"
' Get watt hours used
MSComm1.Output = "#"
MSComm1.Output = Chr$("3")
End If
End Function
I have changed several things while trying to get this to work. Instead of trying to send a "#", I have tried a "A". If I use Ser.tx("5"), it will send a 5 to the VB program and work properly. As soon as the data to be sent from the Prop to the PC is not Numeric, it stops all transmissions and will eventually cause the DoEvents to trigger an Out of Stack space error. I just can't seem to figure this out.
I got it working I just had to switch to the MSComm_OnComm function and remove the If MSComm1.InBufferCount = 1 Then exit do.
Here is the new function :
Private Sub MSComm1_OnComm()
Dim incoming As String
Dim olddata As String
Dim currentTime As String
If MSComm1.CommEvent = comEvReceive Then
CommandStatus.Caption = "Receiving Data From PROP"
incomingdata = ""
Do
incoming = MSComm1.Input
incomingdata = incomingdata + "" + incoming
If (incoming = "") Then
'Exit Sub
Exit Do
End If
Loop
CommandStatus.Caption = "Processing Data Received"
If (Mid$(incomingdata, 1, 1) = "#") Then
CommandStatus.Caption = "Command Received"
olddata = Mid$(incomingdata, 2, Len(incomingdata) - 1)
If (Val(olddata) <> 0) Then
pulsecount.Caption = olddata
incomingdata = ""
currentWattage = 3600 / (Val(olddata) / 1000)
currentwatts.Caption = currentWattage
End If
End If
End If
End Sub
Comments
If your meter blinks once for every watt hour of electricity used the calculations are pretty simple.
For total power consumed over a period of time (second/minute/hour/day/week/month) zero the count at the beginning of the period and increment the count by 1 for each pulse.
Repeat for each blink:
>>watthoursused=watthoursused + 1
At the end of the desired time the total count = the watt hours used. If you save the reading every hour and reset watthoursused to 0 you would have 168 readings per week. Add them up for whatever period the utility bills you for and the totals should match.
For the instantaneous power (calculated for every pulse) the calculation would be:
instantaneouswatthoursused = 3600/deltatime
where 3600 is the number of seconds in an hour and deltatime is the time between the leading edge of two consecutive pulses. If the pulses are always the same width it does not matter if you use the leading or trailing edge.
If you can measure the deltatime accurately enough you might be able to detect the change caused by a bulb being turned on or off. If that is the case you might want to store the instantaneous reading and date/time every time a change of that magnitude occurs.
The key to the whole thing is how much energy each pulse represents. If it is 1 watt hour per pulse these calculations should be dead on.
BTW - If you are measuring time in milliseconds use 3,600,000 instead of 3,600 and you can use fixed point math instead of floating point.
Not sure if this is feasible option, but I am thinking of using the Prop to store each delay between pulses for 1 minute in an array. After that minute, it will start sending the array to the VB program or will calculate the watt hours used in that minute then send that to the VB program. The VB program will store the data for 10 minutes and which will then update the database for later viewing.
One thing I am not quite understanding is how to convert the watt calculation I am getting into watt hours. If the reading is 900 watts for 10 minutes, then my AC kicks on and bumps up the wattage to 6000 for 10 minutes, then the watt reading goes back to 900 for the remaining 40 minutes in a 1 hour span, how would I convert this to watt hours?
I am thinking something like this :
6000 watts / 10 minutes = 600 watt hours + 900 watts for the rest of the hour = 1500 watt hours
Is that correct or way off?
10 minutes is 10/60 of an hour. So 900 watts for 10 mins is 900 * 10/60 = 150 watt hours.
Full answer is (900 * 10/60) + (6000 * 10/60) + (900 * 40/60) = 150 + 1000 + 600 = 1750 watt hours.
There is a simpler way to do what you seem to want. The watthoursused from my previous post has the number of watt hours used since the count was set to zero. If you save that to your database along with the time and date, and then zero the count every time there is a significant change in the instantaneouswatthoursused you will get data that outlines how much power was used at any time of the day, and the sum of this data for your billing period will give the total power used.
Also.... How can I get this thread moved to the Prop section in the forum?
Makes sense to store data in the prop and only dump when needed - then your PC does not need to be on all the time.
A moderator will need to move the link (or start a new thread). Would make sense to have this in the propeller forum - it is a cool project you are working on.
It is a perfect example of how the prop is so clever with multiple cores - set one core to do a clock, one to look for pulses, one to handle the serial transfer and with the propeller, you can be certain that there are no pulses missed. It would be harder to do this with a standard micro.
VB code :
Prop code :
The value displayed in the VB program that is returned is 49. I am sending it the number 1, why do I get 49 back?
I've also attached my version that takes several improvements from different people and combines it into one driver.
I am trying to read the system clock, send that information to the prop to update the time the prop should be at (Minute and second). I know I can send a Byte through VB to the prop and it will work correctly, but.... I need to make the data reading cog as modular as possible to where I can send it a command, then a variable. Something like this :
Is this possible with the Serial communication to the Prop? If so, how?
I would send a single "synchronization" byte (such as "%" or "$"), followed by a single byte as a command. Your command table could be:
24 - UpdateClock
25 - Read Watts
26 - ...
I choose an arbitrary starting number, which is ok as long as all numbers are less than 255. Then, following that byte would be some amount of data (format and length determined by the particular command, down to a size of zero (no data)). Finally, a stop byte could be used to indicate the end of the string (I'd select ASCII CR (13 in decimal)).
Finally, your Propeller code would look like:
In the above example, I assume that the time is transmitted as literal byte values (ie, a received value of 65 means a number of 65, etc.). This works for hours and minutes, since they are less than 255 (1 byte). It doesn't work for the watt hours, since that can be very large. So, watt hours has to be transmitted as a series of ASCII characters that represent it's value.
1. Power the prop from the AC line.
2. Use a crystal for the prop clock.
3. Have a backup battery for the prop.
4. Monitor AC power availability by counting AC cycles.
5. Keep time by counting AC cycles.
6. Monitor power based on whatever criteria you use.
7. When the AC power is lost decrease prop frequency to 5MHz (1x)
8. Store power used up to that point for future transmission.
9. Use waitcnt to wake up once every second, increment the time/date counter, and see if AC power has been restored.
10. When AC power is restored send/store power used record and power outage record.
11. Continue monitoring usage and recharge battery for a period of time based on the length of the power outage.
This will minimize battery size and power usage while maximizing battery life.
Here is a basic block diagram of a power supply with AC detection. The output pulses at AC det are 120Hz pulses that are clamped to the power supply output voltage (about 0.7V higher in voltage) For a 3.3V supply that would be about 4V. A 2K resistor between the AC det output and one of the prop pins will allow you to use the signal for both the RTC and AC power monitoring. A count of 120 pulses on that pin equals one second. If there is no pulse or high for more than 8.3 mSec then AC power is missing.
I have tried :
Ser.tx("#")
Ser.tx(String("#")
Ser.tx(String(13, "#"))
None of these seem to work and just hang the VB program.
PS - Here is the diagram that was supposed to be in my previous post. Basically a standard linear supply with an extra diode and resistor.
The correct way to send a single character is Ser.tx("#").
Here is the code I have so far for the Prop :
And for the VB6 program :
I have changed several things while trying to get this to work. Instead of trying to send a "#", I have tried a "A". If I use Ser.tx("5"), it will send a 5 to the VB program and work properly. As soon as the data to be sent from the Prop to the PC is not Numeric, it stops all transmissions and will eventually cause the DoEvents to trigger an Out of Stack space error. I just can't seem to figure this out.
Here is the new function :
Now to see if i can complete this project