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

Added automatic BLE connecting script #115

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
25 changes: 25 additions & 0 deletions Drivers/pico_remote/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Description:
This device interacts with the wahoo kickr and climbr via the Raspberry Pi 000001, located in the IoT lab, building M.102.
Its intention is to manipulate the hardware in real-time without the need for running or accessing third-party software such as the mobile app, VR, or other interfaces.
The purpose of this is that it allows users to simply use the bike with a simple interface.

# How to Run:
- Kickr script (/iot/scripts/./start_kickr.sh) must be executed and successful connection between Pi and Kickr must be established for this device to work as intended.
- Turn on remote device by pushing the white button on the power regulator on the top of the breadboard
- BT module should be flashing red while waiting for pairing.
- Navigate to iot/Drivers/pico_remote and execute the script via 'python3 pico_bt_handler.py' to run the handler.
- successful connection is determined by the HC-06 module turning into a solid red light.
- Upon successful connection between the HC-06 Bluetooth module and the Raspberry pi, you may now interact with the hardware via the push buttons:

### Note: You must press and hold the selected button in order to influence hardware.

# Buttons:
### Button 1: increase resistance
### Button 2: decrease resistance
### Button 3: increase incline
### Button 4: decrease incline

![Screenshot 2023-09-24 142627](https://github.com/redbackoperations/iot/assets/69894063/d3f90db2-0b68-41e7-b8c1-3ca8d65c8ad4)
![WIN_20230924_12_03_43_Pro](https://github.com/redbackoperations/iot/assets/69894063/0cd708ff-146f-48b0-ac11-f858ef215387)
![WIN_20230924_12_03_08_Pro](https://github.com/redbackoperations/iot/assets/69894063/91f63b5b-432b-4208-a054-40ffb96bd527)

77 changes: 77 additions & 0 deletions scripts/ble-auto-connect/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# BLE Auto Connecting Script

[Image of script running to be inserted]

This script was created to handle some persistent BLE issues we had with the bike. Connecting to the bike was not consistent with failed pairing on start up and even manually connecting using the `bluetoothctl` interface on the Raspberry Pi not working consistently. This script should resolve these issues by using `bluetoothctl` and `expect` script to act like a user and automatically resolve the BLE connection.

## Script Start & Setup

To start this script run the following command from the home directory:

`bash iot/scripts/ble-auto-connect/ble_auto_connect.sh`

### KICKR MAC Address

The KICKR's MAC address must be accurately stored in the hidden `.env` file, in the home directory, with the following format:

`... KICKR_MAC_ADDRESS="XX:XX:XX:XX:XX:XX" ...`

*To access the hidden environment file use `nano .env` in the home directory*

### Bike on Standby

Ensure that the bike is not on standby: the BLE indicator light on the KICKR is blink blue and not off

[Image to be inserted]

*If it is on standby rotate the pedals a few times*

### Expect Installed

Ensure `expect` is installed using:

`sudo apt-get install expect`

## Script Process

[Flow chart of scripts decision logic to be inserted]

The script follows a simple flow of commands reacting to expected outputs to terminal from `bluetoothctl` commands and writing input commands into the terminal.

### Once Started

Once the script has been started, it enter commands into the terminal interface like a user, waiting for expected output from commands and responding to resolve any issues.

[Image of script process to be inserted]

**DO NOT** attempt to enter anything into command-line during this process - if you must, terminate the script using `Ctrl + C` before doing so.

### Script Completion

If a connection was successfully achieved, an output to the terminal should indicate so:

`Connection established with bike via BLE`

[Image to be inserted]

### Script Failure

The above process should only take a few seconds but can fail for unknown reasons and enter into a loop. If this happens, use `Ctrl + C` to terminate the script and then restart both the bike & Pi, and re-run the script.

## Future

Some improvements to the script are desireable and left for future team members to implement:

- Running the script on Pi start up using a daemon to fully automate the connection
- Running the script on script start up (`start_all.sh`) so that BLE connection is always resolved before other processes initialise
- Running the script in a background process so that it does not interfer with the command-line
- Forever looping the script so that it will reconnect if the connection drops for some reason
- Extend script to handle any future encountered issues
- Change the regex pattern used to match the KICKR MAC address to be more forgiving

## Resources

- `bluetoothctl` - https://manpages.debian.org/unstable/bluez/bluetoothctl.1.en.html
- `expect` introduction - https://phoenixnap.com/kb/linux-expect
- Reading files using `tcl` (the backbone of `expect`) - https://wiki.tcl-lang.org/page/How+do+I+read+and+write+files+in+Tcl
- Shell script & expect script located in `iot/scripts/ble_auto_connect.sh`
62 changes: 62 additions & 0 deletions scripts/ble-auto-connect/ble_auto_connect.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/expect -f

# get KICKR address from environment file
set fh [exec cat ~/.env]
regexp {(?:KICKR_MAC_ADDRESS=\")(.*?)(?=\")} $fh _ KICKR_MAC_ADDRESS

# set target MAC address
set TARGET_ADDRESS $KICKR_MAC_ADDRESS

# attempt to connect to target
set timeout -1
set prompt "#"
set connection_established 0

spawn bluetoothctl

# request and wait for default agent
expect -re $prompt
send "default-agent\r"

expect -re "Default agent request successful"

# TODO: expand to scan, trust and pair

# Attempt to connect to the device
expect -re $prompt
send "connect $TARGET_ADDRESS\r"
while {$connection_established != 1} {
expect {
# end loop on successful connect
-re "Connection successful" {
set connection_established 1
}
# retry connect if failed
-re "Connected: no" {
# Retry connecting if it fails
expect -re $prompt
send "connect $TARGET_ADDRESS\r"
}
# if hit device not available - scan to discover the device and continue
-re "not available" {

# ensure the device is not already known
expect -re $prompt
send "remove $TARGET_ADDRESS\r"

# rediscover the device by scanning
expect -re $prompt
send "discoverable on\r"
expect -re $prompt
send "scan on\r"
expect -re "(?i)$TARGET_ADDRESS"
send "scan off\r"
}
}
}

# Exit bluetoothctl
expect -re $prompt
send "exit\r"

expect eof
15 changes: 15 additions & 0 deletions scripts/ble-auto-connect/ble_auto_connect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# auto connect to the bike by resolving the BLE issues automatically via bluetoothctl
source ~/.env
echo "Attempting auto connect to bike via BLE"

# set target MAC address
TARGET_ADDRESS=$KICKR_MAC_ADDRESS

EXPECT_SCRIPT="ble_auto_connect.exp"
expect "$EXPECT_SCRIPT"

echo "Connection established with bike via BLE"

exit 0