วันนี้มาลองเขียนโปรแกรมเพื่อรับค่าน้ำตาลในเลือดจากเครื่องวัดน้ำตาลในเลือดของ Accu-Chek กันบ้าง เครื่องของ Accu-Chek เองก็เป็นที่นิยมในตลาด หาซื้อได้ง่าย ความแม่นยำสูง และเช่นเคยข้อมูลที่ส่งออกมาก็เป็นสัญญาน Bluetooth เช่นกัน ต่างจากเครื่องของ Yuwell นิดหน่อย ตรงที่ต้องทำการ  Pairing และใส่ PIN Code เข้าไปก่อน แต่เดียวมาดูวิธีการทำกัน

ข้อควรระวัง ระหว่างคอมพิวเตอร์ที่รันโปรแกรมและตัวเครื่องตรวจน้ำตาล Accu-Chek ต้องอยู่ห่างกันไม่เกิน 3 เมตร น้อยกว่าเครื่องของ Yuwell อีก อาจจะเพราะว่าใช้ถ่านกระดุม เลยทำให้ส่งสัญญานได้ไม่ไกลมากนัก ฉะนั้นตอนทดลองแนะนำให้ลองใกล้ ๆ ก่อน

0. Install library

เช่นเคย เริ่มต้นด้วยการติดตั้งโปรแกรมและไลบรารีที่จำเป็นกันก่อน

# apt-get update
# apt-get install -y bluez* pkg-config libbluetooth-dev libglib2.0-dev
# apt-get install -y libboost-thread-dev libboost-python-dev python3-capstone

# pip3 install requests
# pip3 install bleak
# pip3 install asyncio

1. discover.py

ทำการเขียนโปรแกรมสำหรับค้นหา MAC Address ของเครื่องตรวจน้ำตาลในเลือด

# nano discover.py
import sys
import asyncio
import time

from typing import Sequence
from bleak import BleakScanner
from bleak.backends.device import BLEDevice

async def findBluetoothDevice():
    devices: Sequence[BLEDevice] = await BleakScanner.discover(timeout=1)

    print("** Date Time: ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "**\n")

    for device in devices:
        print(device)

    print("--------------------------------------------------\n")

print("If you want to exit, you can press Ctrl + C.\n")

while True:
    try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(findBluetoothDevice())
    except KeyboardInterrupt:
        print("\nExit\n")
        sys.exit(0)
    except Exception as e:
        print("Exception Message:", str(e))
        time.sleep(1)

2. Find device address

ทำการรันคำสั่ง discover.py เพื่อหา MAC Address ของเครื่องตรวจน้ำตาลในเลือด เมื่อรันคำสั่งแล้วให้กดเปิดเครื่อง โดยชื่อเครื่องจะขึ้นต้นด้วย meter+

# python3 discover.py
Image

3. Pairing device and enter PIN code

ขั้นตอนสำคัญ ในการ parring ให้ทำการกดปุ่มล่างค้างไว้ 3 วินาที  (ปุ่มที่มีลูกศรชี้ลง) จนขึ้นสัญลักษณ์ดังรูป จากนั้นรันคำสั่ง bluetoothctl และทำการ pair ไปยัง MAC Address ของเครื่องตรวจน้ำตาลในเลือดของเรา เมื่อทำการ pair แล้วระบบจะแสดงข้อความให้ใส่ PIN Code ซึ่งก็เป็นตัวเลข PIN ที่อยู่หลังเครื่อง ก็ใส่เข้าไป

# bluetoothctl
[bluetooth]# scan on
[bluetooth]# trust 84:C6:XX:XX:64:64
[bluetooth]# pair 84:C6:XX:XX:64:64
Image
Image

4. blood-glucose-accu-chek.py

ทำการเขียนโปรแกรมสำหรับรับค่าจากเครื่องตรวจน้ำตาลในเลือด อย่าลืมแก้ไขค่าในตัวแปร GLUCOSE_DEVICE_ADDRESS เป็นค่า MAC Address ของเครื่องตรวจน้ำตาลในเลือด Accu-Chek

# nano blood-glucose-accu-chek.py
import sys
import asyncio
import struct
import requests
import time
import platform

from typing import Sequence
from bleak import BleakClient, BleakScanner
from bleak.backends.device import BLEDevice
from datetime import datetime
from requests.structures import CaseInsensitiveDict

GLUCOSE_DEVICE_ADDRESS = "84:C6:XX:XX:64:64" # Change to your device address
GLUCOSE_MEASUREMENT_UUID = "00002a18-0000-1000-8000-00805f9b34fb" # Glucose measurement UUID

def glucoseMeasurement(handle, data):
    unpackData = [dt[0] for dt in struct.iter_unpack("<B", data)]

    hexData = [hex(dt) for dt in unpackData]
    print("hexData:", hexData)

    deviceDateTime = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(int(((unpackData[4] & 0xFF) << 8) | unpackData[3]), int(unpackData[5]), int(unpackData[6]), int(unpackData[7]), int(unpackData[8]), int(unpackData[9]))

    # Convert to Local Time Zone
    currentTimestamp = time.time()
    localTimeZoneOffset = datetime.fromtimestamp(currentTimestamp) - datetime.utcfromtimestamp(currentTimestamp)
    currentDateTime = datetime.strptime(deviceDateTime, "%Y-%m-%d %H:%M:%S") + localTimeZoneOffset

    glucoseOffset = 0

    if unpackData[13] == 176:
        glucoseOffset = 0 * 256
    elif unpackData[13] == 177:
        glucoseOffset = 1 * 256
    elif unpackData[13] == 178:
        glucoseOffset = 2 * 256
    elif unpackData[13] == 179:
        glucoseOffset = 3 * 256

    glucoseMg = "{:.1f}".format(unpackData[12] + glucoseOffset)
    glucoseMm = "{:.1f}".format((unpackData[12] + glucoseOffset) / 18.0)

    print("Date Time: ", str(currentDateTime.strftime("%Y-%m-%d %H:%M:%S")), "\t\tGlucose: ", glucoseMm, "mmol/L , ", glucoseMg, "mg/dL")

async def receiveNotification():
    print("Connect To: ", GLUCOSE_DEVICE_ADDRESS, "\t\t", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

    async with BleakClient(GLUCOSE_DEVICE_ADDRESS) as client:
        await client.start_notify(GLUCOSE_MEASUREMENT_UUID, glucoseMeasurement)
        await asyncio.sleep(5.0)
        await client.stop_notify(GLUCOSE_MEASUREMENT_UUID)

async def findBluetoothDevice():
    devices: Sequence[BLEDevice] = await BleakScanner.discover(timeout=1)

    for device in devices:
        if device.address == GLUCOSE_DEVICE_ADDRESS:
            await receiveNotification()

print("If you want to exit, you can press Ctrl + C.\n")

while True:
    try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(findBluetoothDevice())
    except KeyboardInterrupt:
        print("\nExit\n")
        sys.exit(0)
    except Exception as e:
        print("Exception Message:", str(e))
        time.sleep(1)

5. Run

สั่งรันคำสั่งเพื่อรอรับค่าจากเครื่องตรวจน้ำตาลในเลือด เมื่อรันโปรแกรมแล้ว ก็ลองเจาะเลือดเพื่อตรวจน้ำตาลในเลือดและดูการแสดงผล

# python3 blood-glucose-accu-chek.py
Image

6. การนำไปประยุกต์ใช้

ส่งเข้า LINE Messenger เช่นเคย เพราะยังไม่รู้จะเอาไปทำอะไร

7. ดูโค้ดทั้งหมดได้ที่ GitHub

GitHub - LookHin/blood-glucose-meter-accu-chek
Contribute to LookHin/blood-glucose-meter-accu-chek development by creating an account on GitHub.