187 lines
5.6 KiB
Go
Raw Normal View History

2024-10-28 20:10:55 +01:00
package main
import (
2024-11-12 13:57:14 +01:00
"encoding/binary"
2024-10-28 20:10:55 +01:00
"fmt"
"machine"
"time"
"tinygo.org/x/bluetooth"
"tinygo.org/x/drivers/lsm6ds3tr"
)
var adapter = bluetooth.DefaultAdapter
2024-11-13 21:22:29 +01:00
var isBleConnected bool = false
2024-10-28 20:10:55 +01:00
2024-11-13 21:22:29 +01:00
var isCapturing bool = false
2024-11-12 13:57:14 +01:00
2024-10-28 20:10:55 +01:00
var (
2024-11-12 13:57:14 +01:00
LSM6DS3TRService = [16]byte{0x4C, 0x53, 0x4D, 0x36, 0x44, 0x53, 0x33, 0x54, 0x52, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65}
accelerationData = [16]byte{0x61, 0x63, 0x63, 0x65, 0x6C, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x61, 0x74, 0x61}
2024-11-13 21:22:29 +01:00
unixTimeStampRst = [16]byte{0x75, 0x6E, 0x69, 0x78, 0x54, 0x69, 0x6D, 0x65, 0x53, 0x74, 0x61, 0x6D, 0x70, 0x52, 0x73, 0x74}
capturingService = [16]byte{0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x69, 0x6E, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65}
//tempSenseService = [16]byte{0x74, 0x65, 0x6D, 0x70, 0x53, 0x65, 0x6E, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65}
//temperatureSense = [16]byte{0x74, 0x65, 0x6D, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x6E, 0x73, 0x65}
2024-10-28 20:10:55 +01:00
)
2024-11-13 21:22:29 +01:00
var unixTimeStamp time.Time = time.Now()
const sleepDuration time.Duration = time.Millisecond * 100
2024-10-28 20:10:55 +01:00
func main() {
// Configure LSM6DS3TR
machine.I2C0.Configure(machine.I2CConfig{})
accel := lsm6ds3tr.New(machine.I2C0)
err := accel.Configure(lsm6ds3tr.Configuration{})
if err != nil {
for {
println("Failed to configure", err.Error())
time.Sleep(time.Second)
}
}
// Configure Bluetooth
must("enable BLE stack", adapter.Enable())
adv := adapter.DefaultAdvertisement()
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "Go Bluetooth",
ManufacturerData: []bluetooth.ManufacturerDataElement{
2024-11-12 13:57:14 +01:00
// 0xFFFF: Special Use/Default ID
// Bluetooth Company Identifiers:
// https://gist.github.com/angorb/f92f76108b98bb0d81c74f60671e9c67
2024-10-28 20:10:55 +01:00
{CompanyID: 0xffff, Data: []byte{0x01, 0x02}},
},
}))
adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) {
if connected {
2024-11-13 21:22:29 +01:00
isBleConnected = true
2024-10-28 20:10:55 +01:00
} else {
2024-11-13 21:22:29 +01:00
isBleConnected = false
isCapturing = false
2024-10-28 20:10:55 +01:00
}
})
2024-11-12 13:57:14 +01:00
//
// Start Bluetooth advertisment
2024-10-28 20:10:55 +01:00
must("start adv", adv.Start())
var senseCharacteristic bluetooth.Characteristic
must("add sense service", adapter.AddService(&bluetooth.Service{
2024-11-12 13:57:14 +01:00
UUID: bluetooth.NewUUID(LSM6DS3TRService),
2024-10-28 20:10:55 +01:00
Characteristics: []bluetooth.CharacteristicConfig{
{
Handle: &senseCharacteristic,
2024-11-12 13:57:14 +01:00
UUID: bluetooth.NewUUID(accelerationData),
2024-11-13 21:22:29 +01:00
// can only send a max amount of 20 bytes in one packet
//Value: []byte{},
Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission,
},
{
UUID: bluetooth.NewUUID(unixTimeStampRst),
Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission,
WriteEvent: func(client bluetooth.Connection, offset int, value []byte) {
if len(value) != 8 {
return
}
millisFromEpoch := binary.BigEndian.Uint64(value)
unixTimeStamp = time.Unix(0, int64(millisFromEpoch)*int64(time.Millisecond))
},
},
{
UUID: bluetooth.NewUUID(capturingService),
Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission,
WriteEvent: func(client bluetooth.Connection, offset int, value []byte) {
if len(value) != 1 {
return
}
if value[0] == 1 {
isCapturing = true
} else {
isCapturing = false
}
},
2024-10-28 20:10:55 +01:00
},
},
}))
2024-11-12 13:57:14 +01:00
// var tempCharacteristic bluetooth.Characteristic
// must("add temperature service", adapter.AddService(&bluetooth.Service{
// UUID: bluetooth.NewUUID(tempSenseService),
// Characteristics: []bluetooth.CharacteristicConfig{
// {
// Handle: &tempCharacteristic,
// UUID: bluetooth.NewUUID(temperatureSense),
// Value: []byte(tempData),
// Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission,
// },
// },
// }))
// Main Loop
2024-10-28 20:10:55 +01:00
for {
2024-11-12 13:57:14 +01:00
// Only read and update sensor data
// with an active bluetooth connection
2024-11-13 21:22:29 +01:00
// and when `isCapturing` is set to true
if isBleConnected {
2024-11-12 13:57:14 +01:00
X, Y, Z, _ := accel.ReadRotation()
x, y, z, _ := accel.ReadAcceleration()
2024-11-13 21:22:29 +01:00
arrRot := valuesToByteArray(X, Y, Z, int8(1))
senseCharacteristic.Write(arrRot)
2024-11-12 13:57:14 +01:00
2024-11-13 21:22:29 +01:00
arrAcc := valuesToByteArray(x, y, z, int8(2))
senseCharacteristic.Write(arrAcc)
2024-11-12 13:57:14 +01:00
2024-11-13 21:22:29 +01:00
arrTime := timeStampToByteArray(unixTimeStamp.UnixMilli(), int8(3))
senseCharacteristic.Write(arrTime)
}
fmt.Println("TIME: ", unixTimeStamp)
2024-11-12 13:57:14 +01:00
2024-11-13 21:22:29 +01:00
time.Sleep(sleepDuration)
if isCapturing {
unixTimeStamp = unixTimeStamp.Add(sleepDuration)
2024-11-12 13:57:14 +01:00
}
2024-10-28 20:10:55 +01:00
}
}
2024-11-13 21:22:29 +01:00
func valuesToByteArray(x int32, y int32, z int32, p int8) []byte {
arr := make([]byte, 13)
arr[0] = byte(x)
arr[1] = byte(x >> 8)
arr[2] = byte(x >> 16)
arr[3] = byte(x >> 24)
arr[4] = byte(y)
arr[5] = byte(y >> 8)
arr[6] = byte(y >> 16)
arr[7] = byte(y >> 24)
arr[8] = byte(z)
arr[9] = byte(z >> 8)
arr[10] = byte(z >> 16)
arr[11] = byte(z >> 24)
arr[12] = byte(p)
return arr
}
func timeStampToByteArray(value int64, p int8) []byte {
arr := make([]byte, 9)
arr[0] = byte(value)
arr[1] = byte(value >> 8)
arr[2] = byte(value >> 16)
arr[3] = byte(value >> 24)
arr[4] = byte(value >> 32)
arr[5] = byte(value >> 40)
arr[6] = byte(value >> 48)
arr[7] = byte(value >> 56)
arr[8] = byte(p)
return arr
}
2024-10-28 20:10:55 +01:00
func must(action string, err error) {
if err != nil {
panic("failed to " + action + ": " + err.Error())
}
}