Shop OBEX P1 Docs P2 Docs Learn Events
Live logger for home power usage. - Page 3 — Parallax Forums

Live logger for home power usage.

13»

Comments

  • kwinnkwinn Posts: 8,697
    edited 2012-08-19 12:48
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-19 21:14
    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

    Is that correct or way off?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-19 22:25
    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.

    Full answer is (900 * 10/60) + (6000 * 10/60) + (900 * 40/60) = 150 + 1000 + 600 = 1750 watt hours.
  • kwinnkwinn Posts: 8,697
    edited 2012-08-20 00:19
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-21 18:58
    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?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-21 19:10
    I wonder if this object would do what you want? http://obex.parallax.com/objects/532/ a real time clock without needing an I2C chip.

    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-21 19:13
    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?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-21 19:35
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-21 19:44
    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 :p
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-21 20:54
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-21 21:00
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-21 21:28
    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?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-21 22:18
    http://www.asciitable.com/ the ascii value for "1" is 49. Somewhere along the line it is getting converted. Not sure where...
  • SRLMSRLM Posts: 5,045
    edited 2012-08-21 22:33
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-21 22:39
    i don't have the GetDec function in the FullDuplexSerial I have running. Where could I find this?
  • SRLMSRLM Posts: 5,045
    edited 2012-08-22 00:30
    You should take a look at FullDuplexSerialPlus.spin. It's more or less the standard full function serial driver. I've attached it to this post.

    I've also attached my version that takes several improvements from different people and combines it into one driver.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-22 21:22
    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?
  • SRLMSRLM Posts: 5,045
    edited 2012-08-23 09:46
    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)).

    Finally, your Propeller code would look like:
    repeat
    	repeat until serial.rx == "$"
    
    	command := serial.rx
    
    	if command == TIME_COMMAND
    		hour := serial.rx
    		minute := serial.rx
    	
    	elsif command == WATT_HOUR_COMMAND
    		serial.dec(current_watt_hour)
    

    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.
  • JLockeJLocke Posts: 354
    edited 2012-08-23 14:30
    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
     
    
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-23 18:10
    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.
  • kwinnkwinn Posts: 8,697
    edited 2012-08-23 19:49
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-23 20:45
    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.
  • kwinnkwinn Posts: 8,697
    edited 2012-08-23 22:27
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-24 23:17
    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.
  • kwinnkwinn Posts: 8,697
    edited 2012-08-25 00:26
    Try Ser.tx(String("#",13)

    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-25 16:43
    Just tried that and it still did not work :( I think the Prop is sending the data, but the VB program is not understanding it or something.
  • SRLMSRLM Posts: 5,045
    edited 2012-08-25 16:49
    "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("#").
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-25 18:43
    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.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-08-25 22:43
    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
    

    Now to see if i can complete this project :)
Sign In or Register to comment.