Announcement

Collapse
No announcement yet.

Serial code to download Accu-Chek meter

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Serial code to download Accu-Chek meter

    Here is some script code to download the memory of an Accu-Chek blood glucose meter that is used by diabetics. It's an example of how to send simple serial commands to a device and read and parse the results. Right now it just takes the readings and writes them to the HS log. I haven't decided how I'm going to use the data in HS yet but I'm thinking about putting it into some type of a file or database so it can be graphed. You need a serial IR data cable from Roche Diagnostics which can be found here:

    https://www.accu-chek.com/us/estore....4%26csr%3Dnull


    This cable is the same as the Tekram IR-210B IrDA cable but it's only $15 instead of the $29.95 Tekram wants for it.

    This code should also work with any IrDA compliant port that supports the IRCOMM protocol.

    Tested with an Accu-Chek Compact Plus meter.

    Code:
        ' =============================================================================
        '
        ' Script to Download readings from an Accu-Chek Blood Glucose Meter
        '
        ' Tested with the Roche Diagnostics Serial IR cable which is the same as the
        ' Tekram IR Mate IR-210B adapter but it should work with just about any IrDA 
        ' compliant device that supports IRCOMM protocol. 
        '
        ' Rev 2010xxxx
        '
        ' For best display, use a monospaced font (Courier) with tabs = 4 spaces.
        '
        ' =============================================================================
        '
        ' Change History
        '
        '    2010xxxx   KLM     - Initial Release
        ' =============================================================================
    
        ' []------------------------------------------------------------[]
        '  | This code was developed, tested, and debugged using:       |
        '  |                                                            |
        '  | The "tenScripting" HomeSeer Script Development Environment |
        '  |                                                            |
        '  |  If you find this script useful please consider making a   |
        '  |  donation here:                                            |
        '  |                                                            |
        '  |    http://www.tenholder.net/tenWare2/CharityWare.aspx      |
        ' []------------------------------------------------------------[]
    
        ' This name will appear in the log next to each event log message. 
        Const sC_scriptName = "AccuChek"
    
        ' ============================================================================
        '
        ' HomeSeer Log Output
        '
        ' Actual errors are always logged to the HomeSeer log
        '
        ' For problems, the following constant, scTraceLevel, can be set as follows:
        '
        '	0 = No trace output
        '	1 = Minimal tracing (main methods)
        '	2 = Additional method tracing and other activity
        '	3 = All methods traced, variable tracing plus additional diagnostic output
        '	4 = Very low level tracing (lots and lots of output)
        '
        Const scTraceLevel = 3
    
        ' COM port number for IrDA device
        Const port = 8
    
        '
        ' Definitions for data record
        '
        Dim Reading, rHour, rMinute, rDay, rMonth, rYear, rValid As String
    
        '
        '
        Public Sub Main(ByVal parm As Object)
    
            Dim err As String
            Dim data As String
            Dim count As Integer
            Dim num_of_readings As String
            Dim reading_b1 As String
            Dim reading_b2 As String
            Dim reading_b3 As String
    
            ' Open COM port in raw mode
            err = hs.OpenComPort(port, "9600,N,8,1", 0, "", "")
    
            If err <> "" Then
                LogIt("Unable to Open COM" & CStr(port))
                Exit Sub
            Else
                LogIt("COM" & CStr(port) & " Successfully Opened")
            End If
    
    
            ' The following commands are just copied from the
            ' Perl script I found on the internet. 
            ' 
            ' I don't know what they do but things seem to break
            ' if you don't follow this command sequence. 
            ' 
            hs.SendToComPort(port, Chr(1))
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "0x01 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            hs.SendToComPort(port, Chr(11))
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "0x0B Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            hs.SendToComPort(port, "C")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, "4")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "C4 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            hs.SendToComPort(port, "C")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, " ")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, "3")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "C 3 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            hs.SendToComPort(port, "S")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, " ")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, "1")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "S 1 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            hs.SendToComPort(port, "S")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, " ")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, "2")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "S 2 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            ' This command returns the number of readings stored in the meter.
            '
            hs.SendToComPort(port, "`")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, Chr(96) & " Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            If Len(data) <> 13 Then
                LogIt("Problem getting # of readings. Byte count not equal to 13(" & CStr(Len(data)) & ")")
                hs.CloseComPort(port)
                Exit Sub
            Else
                num_of_readings = Mid(data, 7, 3)
                reading_b1 = Mid(num_of_readings, 1, 1)
                reading_b2 = Mid(num_of_readings, 2, 1)
                reading_b3 = Mid(num_of_readings, 3, 1)
                TraceIt(3, "Number of readings=" & reading_b1 & reading_b2 & reading_b3)
            End If
    
            hs.SendToComPort(port, "S")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, " ")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, "3")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.2)
            TraceIt(4, "S 3 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            ' Now request the first reading using the number of readings
            ' from the previous command. 
            '
            ' The most recent reading is returned first. 
            '
            hs.SendToComPort(port, "a")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, " ")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, "1")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, " ")
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, reading_b1)
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, reading_b2)
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, reading_b3)
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.3)
            TraceIt(3, "a 1 Count=" & hs.GetComPortCount(port))
            data = hs.GetComPortData(port)
    
            Reading = Mid(data, 13, 3)
            rHour = Mid(data, 16, 2)
            rMinute = Mid(data, 18, 2)
            rDay = Mid(data, 20, 2)
            rMonth = Mid(data, 22, 2)
            rYear = Mid(data, 24, 2)
    
            ' This field indicates the difference between a valid
            ' reading, a control solution test reading, and an
            ' invalid reading. 
            ' 
            '   0 = valid
            '   2 = control
            '   8 = invalid
    
            rValid = Mid(data, 26, 1)
    
            ' For now just write the reading to the HS logfile. 
            '
            LogIt("1:" & ":20" & rYear & ":" & rMonth & ":" & rDay & ":" & _
                  rHour & ":" & rMinute & ":" & Reading & ":" & rValid)
    
            ' Now go get the rest of the readings
            '
            If (IsNumeric(num_of_readings)) Then
    
                For count = 2 To CInt(num_of_readings)
    
                    ' This appears to be a "Next" command the requests the
                    ' next reading which is actually the previous reading since
                    ' the readings are read out in reverse order. 
                    ' 
                    hs.SendToComPort(port, Chr(6))
                    hs.WaitSecs(0.3)
                    data = hs.GetComPortData(port)
    
                    Reading = Mid(data, 5, 3)
                    rHour = Mid(data, 8, 2)
                    rMinute = Mid(data, 10, 2)
                    rDay = Mid(data, 12, 2)
                    rMonth = Mid(data, 14, 2)
                    rYear = Mid(data, 16, 2)
    
                    ' This field indicates the difference between a valid
                    ' reading, a control solution test reading, and an
                    ' invalid reading. 
                    ' 
                    '   0 = valid
                    '   2 = control
                    '   8 = invalid
    
                    rValid = Mid(data, 18, 1)
    
                    ' For now just write the reading to the HS logfile. 
                    '
                    LogIt(count & ":20" & rYear & ":" & rMonth & ":" & rDay & ":" & _
                                       rHour & ":" & rMinute & ":" & Reading & ":" & rValid)
    
                Next
    
            End If
    
            ' Tell the meter we're done transfering data so it can go to sleep. 
            '
            hs.SendToComPort(port, Chr(29))
            hs.WaitSecs(0.1)
            hs.SendToComPort(port, Chr(13))
            hs.WaitSecs(0.3)
            data = hs.GetComPortData(port)
    
            hs.CloseComPort(port)
    
        End Sub
    
    
        ' ============================================================================
        ' L o g g i n g   a n d   T r a c i n g   M e t h o d s
        ' ============================================================================
        ' ============================================================================
        '
        ' LogIt
        '
        ' Unconditionally log a message to the HomeSeer log
        '
        ' ============================================================================
        Private Sub LogIt(ByVal message As String)
    
            hs.WriteLog(sC_scriptName, message)
    
        End Sub
    
        ' ============================================================================
        '
        ' TraceIt
        '
        ' Output a trace message to the HomeSeer log
        '
        ' ============================================================================
        Private Sub TraceIt(ByVal level As Integer, ByVal message As String)
            'hs.WriteLog("DEBUG", "Got to TraceIt.1")
    
            If (level <= scTraceLevel) Then
                'hs.WriteLog("DEBUG", "Got to TraceIt.2")
    
                hs.WriteLog(sC_scriptName, "(" & CStr(level) & ") " & message)
            End If
    
        End Sub
    "if I have seen further [than others], it is by standing on the shoulders of giants." --Sir Isaac Newton (1675)

    #2
    Ken,

    Great idea!
    - Pete

    Auto mator
    Homeseer 3 Pro - 3.0.0.548 (Linux) - Ubuntu 18.04/W7e 64 bit Intel Haswell CPU 16Gb

    HS4 Pro - Ubuntu 22.04 / Lenova Tiny M900 / 32Gb Ram
    HSTouch on Intel tabletop tablets (Jogglers) - Asus AIO - Windows 11

    X10, UPB, Zigbee, ZWave and Wifi MQTT automation-Tasmota-Espurna. OmniPro 2, Russound zoned audio, Alexa, Cheaper RFID, W800 and Home Assistant

    Comment


      #3
      Hi, I am trying to establish connection between this glucometer and a Microcontroller. When you open the IR port in RAW mode, you mean that it doesn't follow the irda hanshaking protocols? you just have to send and receive bytes? Thanks for your help!

      Comment

      Working...
      X