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}