Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ./xiao-ble-laptimer #4

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ smoketest:
go build -o /tmp/test ./xiao-ble/ble-led-client
tinygo build -o /tmp/test.hex --target xiao-ble --size short ./xiao-ble/ble-led-client
tinygo build -o /tmp/test.hex --target xiao-ble --size short ./xiao-ble/ble-led-client-xiao
tinygo build -o /tmp/test.hex --target xiao-ble --size short ./xiao-ble-laptimer/laptimer-xiao
go build -o /tmp/test ./xiao-ble-laptimer/laptimer

fmt-check:
@unformatted=$$(gofmt -l `find . -name "*.go"`); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ This is a Demo using Bluetooth.

[![](https://img.youtube.com/vi/HWBxuMbNUTI/0.jpg)](https://www.youtube.com/watch?v=HWBxuMbNUTI)

* [./xiao-ble-laptimer/](./xiao-ble-laptimer/)

![](./xiao-ble-laptimer/xiao-ble-laptimer.jpg)



## wioterminal initialize
Expand Down
50 changes: 50 additions & 0 deletions xiao-ble-laptimer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# xiao-ble-laptimer examples

TinyGo example of XIAO BLE.
This is a Demo using Bluetooth.

* [./xiao-ble-laptimer/laptimer/](./ble-laptimer/laptimer/)
* [./xiao-ble-laptimer/laptimer-xiao/](./laptimer-xiao/)

![](./xiao-ble-laptimer.jpg)


## Usage

First flash it to an nRF52840 microcontroller such as xiao-ble.

```
$ tinygo flash --target xiao-ble --size short ./xiao-ble-laptimer/laptimer-xiao
code data bss | flash ram
11228 156 8012 | 11384 8168
```

Then, start a program to measure the lap time on the computer.
If the BLE scan fails for 3 minutes, the next lap is considered to have progressed.


```
$ go run ./xiao-ble-laptimer/laptimer
```

To change to a value other than 3 minutes, change the following settings.


```go
thresh := 3 * time.Minute
```

Below is the actual log file.

```
2022/10/22 10:46:25 2562047:47:16 0 found
2022/10/22 10:53:06 lost
2022/10/22 11:26:39 00:40:14 1 found
2022/10/22 11:30:02 lost
2022/10/22 11:38:02 00:11:23 2 found
2022/10/22 11:41:19 lost
2022/10/22 11:48:16 00:10:13 3 found
2022/10/22 11:51:31 lost
2022/10/22 11:58:43 00:10:26 4 found
2022/10/22 12:01:58 lost
```
55 changes: 55 additions & 0 deletions xiao-ble-laptimer/laptimer-xiao/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package main

import (
"machine"
"time"

"tinygo.org/x/bluetooth"
)

var adapter = bluetooth.DefaultAdapter
var ledColor = []byte{0x00, 0x00, 0x00, 0x00}

var (
serviceUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
charUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
)

func main() {
println("starting")
must("enable BLE stack", adapter.Enable())
adv := adapter.DefaultAdvertisement()
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "No 10 - TinyGo LapTimer",
Interval: bluetooth.NewDuration(32 * time.Millisecond),
}))
must("start adv", adv.Start())

led := machine.LED
led.Configure(machine.PinConfig{Mode: machine.PinOutput})

//var err error
for {
//fmt.Printf("start\r\n")
//err = adv.Start()
//if err != nil {
// fmt.Printf("err %s\r\n", err.Error())
//}

led.Low()
time.Sleep(time.Millisecond * 100)
led.High()
time.Sleep(time.Millisecond * 100)
//fmt.Printf("stop\r\n")
//err = adv.Stop()
//if err != nil {
// fmt.Printf("err %s\r\n", err.Error())
//}
}
}

func must(action string, err error) {
if err != nil {
panic("failed to " + action + ": " + err.Error())
}
}
151 changes: 151 additions & 0 deletions xiao-ble-laptimer/laptimer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package main

import (
"bufio"
"flag"
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
"time"

"tinygo.org/x/bluetooth"
)

// bluetooth
var (
adapter = bluetooth.DefaultAdapter
dc bluetooth.DeviceCharacteristic
serviceUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
charUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
)

func getCurrentStatus(file string) (bool, time.Time, int, error) {
//time.Local = time.FixedZone("Asia/Tokyo", 9*60*60)
found := false
var prevTimeOfLap time.Time
laps := 0

r, err := os.Open(file)
if err != nil {
return found, prevTimeOfLap, laps, err
}
defer r.Close()

scanner := bufio.NewScanner(r)
lastLine := ""
lastLineWithFound := ""
for scanner.Scan() {
lastLine = scanner.Text()
fmt.Printf("%s\n", lastLine)
if strings.HasSuffix(lastLine, " found") {
lastLineWithFound = lastLine
found = true
} else {
found = false
}
}

prevTimeOfLap, err = time.Parse("2006/01/02 15:04:05", lastLineWithFound[:19])
if err == nil {
prevTimeOfLap = prevTimeOfLap.Add(-1 * 9 * time.Hour)
}

spl := strings.Split(lastLineWithFound, " ")
x, _ := strconv.ParseUint(spl[3], 10, 64)
laps = int(x) + 1
//fmt.Printf("prev : %s\n", prevTimeOfLap.In(time.Local))
//fmt.Printf("%s\n", lastLineWithFound)

return found, prevTimeOfLap, laps, nil
}

func run() error {
found, prevTimeOfLap, laps, err := getCurrentStatus("data.txt")
if err != nil {
//return err
}

wfh, err := os.OpenFile("data.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
return err
}
defer wfh.Close()

w := io.MultiWriter(os.Stdout, wfh)
log.SetOutput(w)

must("enable BLE stack", adapter.Enable())

// Scan for NUS peripheral.
timeFromLastFound := time.Now()
//thresh := 1 * time.Second
thresh := 3 * time.Minute
if debug {
thresh = 1000 * time.Millisecond
}
// found -> lost の間は thresh 以上の時間が必要
// 逆に lost -> found の間も thresh 以上の時間が必要
for {
cont := true
//println("scanning")
for cont {
err := adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) {
//fmt.Printf("%#v\n", result.Address.String())
//fmt.Printf("%#v %d\n", result.Address.String(), -1*time.Until(timer))
if result.LocalName() != "No 10 - TinyGo LapTimer" {
if -1*time.Until(timeFromLastFound) > thresh {
if found {
log.Printf("lost")
//time.Sleep(thresh)
}
found = false
}
return
}

// Stop the scan.
err := adapter.StopScan()
if err != nil {
// Unlikely, but we can't recover from this.
println("failed to stop the scan:", err.Error())
}
})
if err != nil {
println("could not start a scan:", err.Error())
return err
} else {
if !found {
lapTime := int(time.Now().Sub(prevTimeOfLap).Seconds())
log.Printf("%02d:%02d:%02d %d found", lapTime/3600, (lapTime/60)%60, lapTime%60, laps)
laps++
prevTimeOfLap = time.Now()
}
found = true
timeFromLastFound = time.Now()
cont = false
}
}
}
return nil
}

var debug bool

func main() {
flag.BoolVar(&debug, "debug", debug, "debug")
flag.Parse()

err := run()
if err != nil {
log.Fatal(err)
}
}

func must(action string, err error) {
if err != nil {
panic("failed to " + action + ": " + err.Error())
}
}
Binary file added xiao-ble-laptimer/xiao-ble-laptimer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.