Skip to content

Commit df70a32

Browse files
committed
Add ./xiao-ble-laptimer
1 parent 961ab60 commit df70a32

File tree

5 files changed

+260
-0
lines changed

5 files changed

+260
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ This is a Demo using Bluetooth.
4444

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

47+
* [./xiao-ble-laptimer/](./xiao-ble-laptimer/)
48+
49+
![](./xiao-ble-laptimer/xiao-ble-laptimer.jpg)
50+
4751

4852

4953
## wioterminal initialize

xiao-ble-laptimer/README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# xiao-ble-laptimer examples
2+
3+
TinyGo example of XIAO BLE.
4+
This is a Demo using Bluetooth.
5+
6+
* [./xiao-ble-laptimer/laptimer/](./ble-laptimer/laptimer/)
7+
* [./xiao-ble-laptimer/laptimer-xiao/](./laptimer-xiao/)
8+
9+
![](./xiao-ble-laptimer.jpg)
10+
11+
12+
## Usage
13+
14+
First flash it to an nRF52840 microcontroller such as xiao-ble.
15+
16+
```
17+
$ tinygo flash --target xiao-ble --size short ./xiao-ble-laptimer/laptimer-xiao
18+
code data bss | flash ram
19+
11228 156 8012 | 11384 8168
20+
```
21+
22+
Then, start a program to measure the lap time on the computer.
23+
If the BLE scan fails for 3 minutes, the next lap is considered to have progressed.
24+
25+
26+
```
27+
$ go run ./xiao-ble-laptimer/laptimer
28+
```
29+
30+
To change to a value other than 3 minutes, change the following settings.
31+
32+
33+
```go
34+
thresh := 3 * time.Minute
35+
```
36+
37+
Below is the actual log file.
38+
39+
```
40+
2022/10/22 10:46:25 2562047:47:16 0 found
41+
2022/10/22 10:53:06 lost
42+
2022/10/22 11:26:39 00:40:14 1 found
43+
2022/10/22 11:30:02 lost
44+
2022/10/22 11:38:02 00:11:23 2 found
45+
2022/10/22 11:41:19 lost
46+
2022/10/22 11:48:16 00:10:13 3 found
47+
2022/10/22 11:51:31 lost
48+
2022/10/22 11:58:43 00:10:26 4 found
49+
2022/10/22 12:01:58 lost
50+
```
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package main
2+
3+
import (
4+
"machine"
5+
"time"
6+
7+
"tinygo.org/x/bluetooth"
8+
)
9+
10+
var adapter = bluetooth.DefaultAdapter
11+
var ledColor = []byte{0x00, 0x00, 0x00, 0x00}
12+
13+
var (
14+
serviceUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
15+
charUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
16+
)
17+
18+
func main() {
19+
println("starting")
20+
must("enable BLE stack", adapter.Enable())
21+
adv := adapter.DefaultAdvertisement()
22+
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
23+
LocalName: "No 10 - TinyGo LapTimer",
24+
Interval: bluetooth.NewDuration(32 * time.Millisecond),
25+
}))
26+
must("start adv", adv.Start())
27+
28+
led := machine.LED
29+
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
30+
31+
//var err error
32+
for {
33+
//fmt.Printf("start\r\n")
34+
//err = adv.Start()
35+
//if err != nil {
36+
// fmt.Printf("err %s\r\n", err.Error())
37+
//}
38+
39+
led.Low()
40+
time.Sleep(time.Millisecond * 100)
41+
led.High()
42+
time.Sleep(time.Millisecond * 100)
43+
//fmt.Printf("stop\r\n")
44+
//err = adv.Stop()
45+
//if err != nil {
46+
// fmt.Printf("err %s\r\n", err.Error())
47+
//}
48+
}
49+
}
50+
51+
func must(action string, err error) {
52+
if err != nil {
53+
panic("failed to " + action + ": " + err.Error())
54+
}
55+
}

xiao-ble-laptimer/laptimer/main.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"flag"
6+
"fmt"
7+
"io"
8+
"log"
9+
"os"
10+
"strconv"
11+
"strings"
12+
"time"
13+
14+
"tinygo.org/x/bluetooth"
15+
)
16+
17+
// bluetooth
18+
var (
19+
adapter = bluetooth.DefaultAdapter
20+
dc bluetooth.DeviceCharacteristic
21+
serviceUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
22+
charUUID = bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3})
23+
)
24+
25+
func getCurrentStatus(file string) (bool, time.Time, int, error) {
26+
//time.Local = time.FixedZone("Asia/Tokyo", 9*60*60)
27+
found := false
28+
var prevTimeOfLap time.Time
29+
laps := 0
30+
31+
r, err := os.Open(file)
32+
if err != nil {
33+
return found, prevTimeOfLap, laps, err
34+
}
35+
defer r.Close()
36+
37+
scanner := bufio.NewScanner(r)
38+
lastLine := ""
39+
lastLineWithFound := ""
40+
for scanner.Scan() {
41+
lastLine = scanner.Text()
42+
fmt.Printf("%s\n", lastLine)
43+
if strings.HasSuffix(lastLine, " found") {
44+
lastLineWithFound = lastLine
45+
found = true
46+
} else {
47+
found = false
48+
}
49+
}
50+
51+
prevTimeOfLap, err = time.Parse("2006/01/02 15:04:05", lastLineWithFound[:19])
52+
if err == nil {
53+
prevTimeOfLap = prevTimeOfLap.Add(-1 * 9 * time.Hour)
54+
}
55+
56+
spl := strings.Split(lastLineWithFound, " ")
57+
x, _ := strconv.ParseUint(spl[3], 10, 64)
58+
laps = int(x) + 1
59+
//fmt.Printf("prev : %s\n", prevTimeOfLap.In(time.Local))
60+
//fmt.Printf("%s\n", lastLineWithFound)
61+
62+
return found, prevTimeOfLap, laps, nil
63+
}
64+
65+
func run() error {
66+
found, prevTimeOfLap, laps, err := getCurrentStatus("data.txt")
67+
if err != nil {
68+
//return err
69+
}
70+
71+
wfh, err := os.OpenFile("data.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
72+
if err != nil {
73+
return err
74+
}
75+
defer wfh.Close()
76+
77+
w := io.MultiWriter(os.Stdout, wfh)
78+
log.SetOutput(w)
79+
80+
must("enable BLE stack", adapter.Enable())
81+
82+
// Scan for NUS peripheral.
83+
timeFromLastFound := time.Now()
84+
//thresh := 1 * time.Second
85+
thresh := 3 * time.Minute
86+
if debug {
87+
thresh = 1000 * time.Millisecond
88+
}
89+
// found -> lost の間は thresh 以上の時間が必要
90+
// 逆に lost -> found の間も thresh 以上の時間が必要
91+
for {
92+
cont := true
93+
//println("scanning")
94+
for cont {
95+
err := adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) {
96+
//fmt.Printf("%#v\n", result.Address.String())
97+
//fmt.Printf("%#v %d\n", result.Address.String(), -1*time.Until(timer))
98+
if result.LocalName() != "No 10 - TinyGo LapTimer" {
99+
if -1*time.Until(timeFromLastFound) > thresh {
100+
if found {
101+
log.Printf("lost")
102+
//time.Sleep(thresh)
103+
}
104+
found = false
105+
}
106+
return
107+
}
108+
109+
// Stop the scan.
110+
err := adapter.StopScan()
111+
if err != nil {
112+
// Unlikely, but we can't recover from this.
113+
println("failed to stop the scan:", err.Error())
114+
}
115+
})
116+
if err != nil {
117+
println("could not start a scan:", err.Error())
118+
return err
119+
} else {
120+
if !found {
121+
lapTime := int(time.Now().Sub(prevTimeOfLap).Seconds())
122+
log.Printf("%02d:%02d:%02d %d found", lapTime/3600, (lapTime/60)%60, lapTime%60, laps)
123+
laps++
124+
prevTimeOfLap = time.Now()
125+
}
126+
found = true
127+
timeFromLastFound = time.Now()
128+
cont = false
129+
}
130+
}
131+
}
132+
return nil
133+
}
134+
135+
var debug bool
136+
137+
func main() {
138+
flag.BoolVar(&debug, "debug", debug, "debug")
139+
flag.Parse()
140+
141+
err := run()
142+
if err != nil {
143+
log.Fatal(err)
144+
}
145+
}
146+
147+
func must(action string, err error) {
148+
if err != nil {
149+
panic("failed to " + action + ": " + err.Error())
150+
}
151+
}
153 KB
Loading

0 commit comments

Comments
 (0)