Skip to content

Commit

Permalink
Merge pull request #2 from ajs123/V0.17
Browse files Browse the repository at this point in the history
V0.17
  • Loading branch information
ajs123 authored Aug 4, 2021
2 parents 24bbbaf + f94534c commit 66000f4
Show file tree
Hide file tree
Showing 14 changed files with 974 additions and 667 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
plans*.h
*ino-
.vscode/*
!.vscode/settings.json
Expand Down
54 changes: 27 additions & 27 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,32 @@
"includePath": [
"/Users/alan/Library/Arduino15/packages/adafruit/tools/CMSIS/5.7.0/CMSIS/Core/Include/",
"/Users/alan/Library/Arduino15/packages/adafruit/tools/CMSIS/5.7.0/CMSIS/DSP/Include/",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/nrfx",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/nrfx/hal",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/nrfx/mdk",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/nrfx/soc",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/nrfx/drivers/include",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/nrfx/drivers/src",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include/nrf52",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/freertos/Source/include",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/freertos/config",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/freertos/portable/GCC/nrf52",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/freertos/portable/CMSIS/nrf52",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/sysview/SEGGER",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/sysview/Config",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/Adafruit_TinyUSB_Arduino/src/arduino",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/variants/feather_nrf52840_express",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/Bluefruit52Lib/src",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/Adafruit_nRFCrypto/src",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/Adafruit_TinyUSB_Arduino/src",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/nrfx",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/nrfx/hal",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/nrfx/mdk",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/nrfx/soc",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/nrfx/drivers/include",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/nrfx/drivers/src",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include/nrf52",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/freertos/Source/include",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/freertos/config",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/freertos/portable/GCC/nrf52",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/freertos/portable/CMSIS/nrf52",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/sysview/SEGGER",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/sysview/Config",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/Adafruit_TinyUSB_Arduino/src/arduino",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/variants/feather_nrf52840_express",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/Bluefruit52Lib/src",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/Adafruit_nRFCrypto/src",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/Adafruit_TinyUSB_Arduino/src",
"/Users/alan/Dropbox (Personal)/Arduino/libraries/U8g2/src",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/SPI",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/Wire",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/Adafruit_LittleFS/src",
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/libraries/InternalFileSytem/src",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/SPI",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/Wire",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/Adafruit_LittleFS/src",
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/libraries/InternalFileSytem/src",
"/Users/alan/Library/Arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/arm-none-eabi/include/c++/9.2.1",
"/Users/alan/Library/Arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/arm-none-eabi/include/c++/9.2.1/arm-none-eabi",
"/Users/alan/Library/Arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/arm-none-eabi/include/c++/9.2.1/backward",
Expand All @@ -58,15 +58,15 @@
"/Users/alan/Library/Arduino15/packages/adafruit/tools/arm-none-eabi-gcc/9-2019q4/arm-none-eabi/include"
],
"forcedInclude": [
"/Users/alan/Library/Arduino15/packages/adafruit/hardware/nrf52/0.24.0/cores/nRF5/Arduino.h"
"/Users/alan/Dropbox (Personal)/Arduino/hardware/Adafruit/Adafruit_nRF52_Arduino/cores/nRF5/Arduino.h"
],
"cStandard": "c11",
"cppStandard": "c++11",
"defines": [
"F_CPU=64000000",
"ARDUINO=10607",
"ARDUINO_NRF52840_FEATHER",
"ARDUINO_ARCH_NRF52",
"ARDUINO_ARCH_ADAFRUIT_NRF52_ARDUINO",
"ARDUINO_BSP_VERSION=\"0.24.0\"",
"NRF52840_XXAA",
"USBCON",
Expand Down
156 changes: 156 additions & 0 deletions BLE_services.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// BLE services

#ifndef BLE_SERVICES_
#define BLE_SERVICES_

/* Cycling Power Service (CPS) ---------------------------------------------------------------------------------
Supported Characteristics:
Name UUID Requirement Properties
---------------------------- ------ ----------- ----------
Cycling Power Feature 0x2A65 Mandatory Read
Cycling Power Measurement 0x2A63 Mandatory Notify
Sensor Location 0x2A5D Mandatory Read
*/

/* Cycling Power Feature characteristic
See https://github.com/sputnikdev/bluetooth-gatt-parser/blob/master/src/main/resources/gatt/characteristic/org.bluetooth.characteristic.cycling_power_feature.xml
Properties = Read
Fixed len = 4
B0
.7 - Accumulated energy supported - 0
.6 - Top and bottom dead spot angles supported - 0
.5 - Extreme angles supported - 0
.4 - Extreme magnitudes supported - 0
.3 - Crank revolution data supported - 0
.2 - Wheel revolution data supported - 0
.1 - Accumulated torque supported - 0
.0 - Pedal power balance supported - 0
B1
.7 - Span Length Adjustment Supported - 0
.6 - Chain Weight Adjustment Supported - 0
.5 - Chain Length Adjustment Supported - 0
.4 - Crank Length Adjustment Supported - 0
.3 - Multiple Sensor Locations Supported - 0
.2 - Cyc Pow Meas Char Cont Masking Supported - 0
.1 - Offset Compensation Supported - 0
.0 - Offset Compensation Indicator Supported - 0
B2
.7 - Reserved
.6 - Reserved
.4-5 - Distribute System Support - 0
.4-5 - [00 Legacy; 01 No; 02 Yes; 03 RFU - 0
.3 - Enhanced Offset Compensation Supported - 0
.2 - Factory Calibration Date Supported - 0
.1 - Instantaneous Measu Direction Supported - 0
.0 - Sensor Meas Context (0 Force, 1 Torque) - 0
B3
.0-7 - Reserved
*/

const uint8_t cpf_data[4] = {0x0, 0x0, 0x0, 0x0};

/* Sensor Location characteristic
See https://github.com/sputnikdev/bluetooth-gatt-parser/blob/master/src/main/resources/gatt/characteristic/org.bluetooth.characteristic.sensor_location.xml
Properties = Read
Fixed len = 4
0x01, 0x00, 0x00, 0x00 = "Other"
*/

const uint8_t cl_data[4] = {0x01, 0x00, 0x00, 0x00};

/* Cycle Power Measurement characteristic
See https://github.com/sputnikdev/bluetooth-gatt-parser/blob/master/src/main/resources/gatt/characteristic/org.bluetooth.characteristic.cycling_power_measurement.xml
Properties = Notify
Fixed len = 8 // Flags[2], InstPower[2], CrankRev[2], Timestamp[2]
Flags = { 0x20, 0x00 } = Crank Revolution Data present
*/

// #define CPM_DATA_0 0x20
// #define CPM_DATA_1 0x00
/* The union (or struct) holding the transmitted data should probably be initialized here...*/
struct power_data_t
{
uint8_t flags[2] {0x20, 0x00}; // These don't change
uint16_t data[3]; // These are loaded with the data
} power_data;


/* FiTness Machine Service (FTMS) -----------------------------------------------------------------------------
Supported Characteristics:
Name UUID Requirement Properties
---------------------------- ------ ----------- ----------
Fitness Machine Feature 0x2ACC Mandatory Read
Indoor Bike Data 0x2A38 Mandatory Notify
*/

/* FiTness Machine Service requires a Service Data field specifying bike support and availability
Per https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/) Service Data is Type 0x16
Contents are
B0-1 - Fitness Machine Service UUID - UINT16 - 2 bytes = 0x1826
B2 - Flags - UINT8 - 1 byte = 0x01 (Machine available)
B3-4 - Fitness Machine Type - UINT16 - 2 bytes = 0x0020 (Indoor bike supported (bit 5))
*/

const uint8_t FTMS_Adv_Data[5] = {0x26, 0x18, 0x01, 0x20, 0x00};

/* Fitness Machine Feature characteristic
See:
Properties = Read
Fixed Len = 4
B0 = UINT8 - Flag (MANDATORY)
7 = 0 - Resistance level supported
6 = 0 - Step count supported
5 = 0 - Pace supported
4 = 0 - Elevation gain supported
3 = 0 - Inclination supported
2 = 0 - Total distance supported
1 = 1 - Cadence supported
0 = 0 - Average speed supported
B1 = UINT8
7 = 0 - Force on belt and power output supported
6 = 1 - Power measurement supported
5 = 0 - Remaining time supported
4 = 0 - Elapsed time supported
3 = 0 - Metabolic equivalent supported
2 = 0 - Heart rate measurement supported
1 = 0 - Expended energy supported
0 = 0 - Stride count supported
B2 = UINT8
2-7 = 0 - RESERVED
0 = 0 - User data retention supported
B3 = UINT8 - RESERVED
*/

const uint8_t ftmf_data[4] = {0b00000010, 0b01000000, 0b00000000, 0b00000000};

/* Indoor Bike Data characteristic - See 4.9.1 IN FTMS_V1.0.pdf
See:
Properties = Notify
Fixed Len = 8
B0 = UINT8 - Flag (MANDATORY)
7 = 0 - Average power present
6 = 1 - Instantaneous power present
5 = 1 - Resistance level present
4 = 0 - Total distance present
3 = 0 - Average cadence present
2 = 1 - Instantaneous cadence present
1 = 0 - Average speed present
0 = 0 - More Data (Instantaneous speed field not present)
B1 = UINT 8
4 = 0 - Remaining time present
3 = 0 - Elapsed time present
2 = 0 - Metabolic equivalent present
1 = 0 - Heart rate present
0 = 0 - Expended energy present
B2-3 = Instantaneous speed - UINT16 - Km/Hr with 0.01 resolution
B4-5 = Instantaneous cadence - UINT16 - 1/min with 0.5 resolution
B6-7 = Instantaneous power - UINT16 - W with 1.0 resolution */

struct bike_data_t
{
uint8_t flags[2] {0b01100100, 0b00000000}; // These don't change
uint16_t data[4]; // These are loaded with the data
} bike_data;

#endif
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,15 @@
- Adafruit's Bluefruit Connect app works well. Be sure that the Uart function is set to include an end-of-line. The system won't care whether <return> or <newline> is used.
- Calibration similar to Keiser's procedure, initiated through the *calibrate* command and with step-by-step prompts for using the calibration tool.
- Calibration will not yet survive a reset. Saving parameters to nonvolatile memory (LittleFS) is next.
- V0.17
- Calibration is now saved to nonvolatile memory (via LittleFS). If cal files aren't present, they're created from the defaults in calibration.h and written out to nonvolatile memory. Further changes are via the console.
- Little U8G2 log screen at startup to show parameters read from or written to nonvolatile memory
- Bike resistance measurement
- Set the ADC sample time (TACQ) as recommended by Nordic for higher resistance sources (such as the 20K resistance sense pot). This reduces noise in resistance measurements. This required an addition to the Adafruit analog input core which is included on Adafruit v0.25 and the current Github master. If not available, comment out the #define for SAADC_TACQ.
- Calibration of the ADC offset - This is recommended by Nordic if the temperature could vary by more than 10 C. It's done at reset and at wakeup from low power mode.
- Improvements and additions to the command line interface
- Now allows calibration values to be re-read from, or written to, nonvolatile memory.
- Now works via BLEUart or serial. It will respond to whichever is the source of input.
- Moved globals to globals.h - start of some code cleanup
- Moved BLE service definitions and flags to BLE_services.h
- Cleaner struct definition for BLE data
Loading

0 comments on commit 66000f4

Please sign in to comment.