1package comms
2
3import (
4 "bytes"
5 "encoding/binary"
6 "math"
7 "odoki-firmware/constants"
8 "odoki-firmware/utils"
9 "time"
10
11 "tinygo.org/x/bluetooth"
12)
13
14var adapter = bluetooth.DefaultAdapter
15
16var heartRateMeasurement bluetooth.Characteristic
17
18var rawDataChra bluetooth.Characteristic
19
20func Init() {
21 // Enable BLE interface.
22 utils.CheckError(adapter.Enable())
23
24 // Define the peripheral device info.
25 adv := adapter.DefaultAdvertisement()
26 address, err := adapter.Address()
27 address_str := address.MAC.String()
28 utils.CheckError(err)
29 utils.CheckError(adv.Configure(bluetooth.AdvertisementOptions{
30 LocalName: "odoki " + address_str[0:2] + address_str[3:5],
31 ServiceUUIDs: []bluetooth.UUID{bluetooth.ServiceUUIDHeartRate},
32 }))
33
34 // Start advertising
35 utils.CheckError(adv.Start())
36 println("advertising...")
37
38 utils.CheckError(adapter.AddService(&bluetooth.Service{
39 UUID: bluetooth.ServiceUUIDHeartRate,
40 Characteristics: []bluetooth.CharacteristicConfig{
41 {
42 Handle: &heartRateMeasurement,
43 UUID: bluetooth.CharacteristicUUIDHeartRateMeasurement,
44 Value: []byte{0, 0}, //default value is 0
45 Flags: bluetooth.CharacteristicNotifyPermission,
46 },
47 },
48 }))
49
50 defaultValue := make([]byte, (constants.ChannelCount)*4+1)
51 utils.CheckError(adapter.AddService(&bluetooth.Service{
52 UUID: bluetooth.ServiceUUIDAdafruitAddressable,
53 Characteristics: []bluetooth.CharacteristicConfig{
54 {
55 Handle: &rawDataChra,
56 UUID: bluetooth.CharacteristicUUIDAdafruitRawTXRX,
57 Value: defaultValue,
58 Flags: bluetooth.CharacteristicNotifyPermission,
59 },
60 },
61 }))
62
63}
64
65func UpdateHR(heartRate uint8) {
66 heartRateMeasurement.Write([]byte{0, heartRate})
67}
68
69func SimulateHR() {
70 var heartRate uint8 = 60
71 nextBeat := time.Now()
72 for {
73 nextBeat = nextBeat.Add(time.Minute / time.Duration(heartRate))
74 println("tick", time.Now().Format("04:05.000"))
75 time.Sleep(time.Until(nextBeat))
76
77 // random variation in heartrate
78 heartRate = utils.RandomInt(65, 85)
79
80 // and push the next notification
81 heartRateMeasurement.Write([]byte{0, heartRate})
82 }
83}
84
85func WriteECG(value int32) {
86 //data := []byte{0}
87 /*
88 buffer := new(bytes.Buffer)
89
90 for i := 0; i < constants.ChannelCount; i++ {
91 binary.Write(buffer, binary.BigEndian, value)
92 }
93
94 data = append(data, buffer.Bytes()...)
95 */
96 //rawDataChra.Write(data)
97}
98
99func SimulateECG() {
100 k := 0.0
101 for {
102 data := []byte{0}
103
104 buffer := new(bytes.Buffer)
105
106 for i := 0; i < constants.ChannelCount; i++ {
107 value := int32(math.Sin(k) * 10000)
108 binary.Write(buffer, binary.BigEndian, value)
109 }
110
111 data = append(data, buffer.Bytes()...)
112
113 rawDataChra.Write(data)
114 time.Sleep(time.Millisecond * 100)
115 k += 0.1
116 }
117
118}