Skip to content

Commit 72c1f88

Browse files
committed
Inflight BLE support in example and minor logger fix.
1 parent 71f616a commit 72c1f88

File tree

11 files changed

+239
-7
lines changed

11 files changed

+239
-7
lines changed

examples/arduino32/nano33ble/MotionDetection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <TaskManager.h>
55
#include <Arduino_LSM9DS1.h>
6-
#include "nano33ble_menu.h"
6+
#include "generated/nano33ble_menu.h"
77

88
/**
99
* Here we create a polling event that checks if the acceleration / magnetic data is available, and whenever it is

examples/arduino32/nano33ble/SensorManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <Arduino_HTS221.h>
66
#include <Arduino_LPS22HB.h>
77
#include <MenuItems.h>
8-
#include "nano33ble_menu.h"
8+
#include "generated/nano33ble_menu.h"
99

1010
/**
1111
* Here we have a class that extends `Executable`, meaning that the `exec()` method is called every time the event

examples/arduino32/nano33ble/nano33ble_menu.cpp renamed to examples/arduino32/nano33ble/generated/nano33ble_menu.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <tcMenu.h>
1212
#include "nano33ble_menu.h"
1313
#include "ThemeMonoInverse.h"
14+
#include "tcMenuBLERemoteConnector.h"
1415

1516
// Global variable declarations
1617
const ConnectorLocalInfo applicationInfo = { "Nano 33 BLE Sense", "e95fcf8a-8a03-4043-9313-01fd8b8e8707" };
@@ -49,6 +50,10 @@ AnalogMenuItem menuHumidity(&minfoHumidity, 0, &menuBPressure, INFO_LOCATION_PGM
4950
const AnalogMenuInfo minfoTemp = { "Temp", 1, 0xffff, 2000, NO_CALLBACK, 0, 10, "C" };
5051
AnalogMenuItem menuTemp(&minfoTemp, 0, &menuHumidity, INFO_LOCATION_PGM);
5152

53+
tcremote::TcMenuRemoteServer remoteServer(applicationInfo);
54+
tcremote::BLEDeviceInitialisation bleInitialisation;
55+
tcremote::BLETagValTransport bleTransport;
56+
5257
void setupMenu() {
5358
// First we set up eeprom and authentication (if needed).
5459
setSizeBasedEEPROMStorageEnabled(false);
@@ -65,5 +70,7 @@ void setupMenu() {
6570
renderer.setTitleMode(BaseGraphicalRenderer::TITLE_FIRST_ROW);
6671
renderer.setUseSliderForAnalog(false);
6772
installMonoInverseTitleTheme(renderer, MenuFontDef(nullptr, 1), MenuFontDef(nullptr, 1), true);
73+
74+
remoteServer.addConnection(new tcremote::TagValueRemoteServerConnection(bleTransport, bleInitialisation));
6875
}
6976

examples/arduino32/nano33ble/nano33ble_menu.h renamed to examples/arduino32/nano33ble/generated/nano33ble_menu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "tcMenuU8g2.h"
1717
#include <IoAbstraction.h>
1818
#include <EepromItemStorage.h>
19+
#include "tcMenuBLERemoteConnector.h"
1920

2021
// variables we declare that you may need to access
2122
extern const PROGMEM ConnectorLocalInfo applicationInfo;
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
The code in this file uses open source libraries provided by thecoderscorner
3+
4+
DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER
5+
INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE.
6+
7+
All the variables you may need access to are marked extern in this file for easy
8+
use elsewhere.
9+
*/
10+
11+
#include "tcMenuBLERemoteConnector.h"
12+
13+
using namespace tcremote;
14+
15+
BLEDevice tcremote::central;
16+
BLEService tcremote::bleApiService(bleServiceIdentifier);
17+
BLECharacteristic tcremote::toApiCharacteristic(characteristicDeviceToApi, BLERead | BLENotify, 255, false);
18+
BLECharacteristic tcremote::fromApiCharacteristic(characteristicApiToDevice, BLEWrite, 255, false);
19+
BLECharacteristic tcremote::deviceSequenceCharacteristic(characteristicDeviceSeqCounter, BLERead | BLENotify, 4, true);
20+
BLECharacteristic tcremote::apiSequenceCharacteristic(characteristicApiSeqCounter, BLEWrite, 4, true);
21+
22+
inline uint32_t read32From(uint8_t* buf) {
23+
return (uint32_t)buf[0] << 24 | (uint32_t)buf[1] << 16 | (uint32_t)buf[2] << 8 | (uint32_t)buf[3];
24+
}
25+
26+
inline void writeToBuffer(uint8_t* buffer, uint32_t sequence) {
27+
buffer[0] = (sequence >> 24);
28+
buffer[1] = (sequence >> 16) & 0xFF;
29+
buffer[2] = (sequence >> 8) & 0xFF;
30+
buffer[3] = sequence & 0xFF;
31+
}
32+
33+
BLETagValTransport::BLETagValTransport() : BaseBufferedRemoteTransport(BUFFER_ONE_MESSAGE, 255, 255) {
34+
writeBufferPos = 4;
35+
writeToBuffer(writeBuffer, currDeviceSequence + 1);
36+
}
37+
38+
bool BLETagValTransport::readAvailable() {
39+
if(readBufferAvail && readBufferPos < readBufferAvail) {
40+
return true;
41+
}
42+
43+
fillReadBuffer(readBuffer, readBufferSize);
44+
return readBufferPos < readBufferAvail;
45+
}
46+
47+
int BLETagValTransport::fillReadBuffer(uint8_t *dataBuffer, int maxSize) {
48+
if(!central.connected() || !fromApiCharacteristic.written()) {
49+
return 0;
50+
}
51+
52+
readBufferAvail = fromApiCharacteristic.readValue(readBuffer, readBufferSize);
53+
if(readBufferAvail <= 4)
54+
{
55+
return 0;
56+
}
57+
58+
serlogHexDump(SER_NETWORK_DEBUG, "fromApi ", readBuffer, readBufferAvail);
59+
60+
size_t i=4;
61+
while(readBuffer[i] != 0 && i < readBufferAvail) {
62+
i++;
63+
}
64+
readBufferAvail = i;
65+
uint32_t rxSequence = read32From(readBuffer);
66+
serlogF3(SER_NETWORK_DEBUG, "RxSeq ", rxSequence, readBufferAvail);
67+
68+
uint8_t buffer[4];
69+
writeToBuffer(buffer, rxSequence);
70+
bool writtenSeqOk = deviceSequenceCharacteristic.writeValue(buffer, 4) != 0;
71+
serlogF2(SER_NETWORK_DEBUG, "RxSeqOK ", writtenSeqOk);
72+
73+
readBufferPos = 4;
74+
return readBufferAvail;
75+
}
76+
77+
void BLETagValTransport::flush() {
78+
if(apiSequenceCharacteristic.written()) {
79+
uint8_t buffer[4];
80+
apiSequenceCharacteristic.readValue(buffer, sizeof(buffer));
81+
currApiSequence = read32From(buffer);
82+
serlogF3(SER_NETWORK_DEBUG, "ApiSeq rd ", currApiSequence, currDeviceSequence)
83+
}
84+
if(central.connected() && currApiSequence == currDeviceSequence) {
85+
// bump the device sequence
86+
currDeviceSequence += 1;
87+
88+
// zero terminate if not full size of buffer
89+
if((writeBufferSize - writeBufferPos) > 1) {
90+
writeBuffer[writeBufferPos] = 0;
91+
writeBufferPos++;
92+
}
93+
94+
// write the value out and make sure it all writes.
95+
int written = toApiCharacteristic.writeValue(writeBuffer, writeBufferPos);
96+
if(written != 0) {
97+
serlogF3(SER_NETWORK_DEBUG, "ApiToDevice ", writeBufferPos, currDeviceSequence)
98+
} else {
99+
central.disconnect();
100+
}
101+
writeBufferPos = 4;
102+
writeToBuffer(writeBuffer, currDeviceSequence);
103+
}
104+
}
105+
106+
bool BLETagValTransport::available() {
107+
return central.connected();
108+
}
109+
110+
bool BLETagValTransport::connected() {
111+
return central.connected();
112+
}
113+
114+
void BLETagValTransport::connectedClient() {
115+
currApiSequence = currDeviceSequence = 0;
116+
uint8_t zeroBuffer[] = {0};
117+
deviceSequenceCharacteristic.writeValue(zeroBuffer, 4);
118+
}
119+
120+
bool BLEDeviceInitialisation::attemptInitialisation() {
121+
serlogF(SER_NETWORK_INFO, "BLE Starting");
122+
if(!initialised && BLE.begin() == 0) return false;
123+
initialised = true;
124+
if (!BLE.begin()) {
125+
serlogF(SER_ERROR, "BLE failed!");
126+
}
127+
128+
bleApiService.addCharacteristic(toApiCharacteristic);
129+
bleApiService.addCharacteristic(fromApiCharacteristic);
130+
bleApiService.addCharacteristic(apiSequenceCharacteristic);
131+
bleApiService.addCharacteristic(deviceSequenceCharacteristic);
132+
uint8_t buffer[4] = {0};
133+
apiSequenceCharacteristic.writeValue(buffer, 4);
134+
deviceSequenceCharacteristic.writeValue(buffer, 4);
135+
136+
BLE.addService(bleApiService);
137+
BLE.setLocalName(applicationInfo.name);
138+
BLE.setAdvertisedService(bleApiService);
139+
BLE.advertise();
140+
141+
serlogF(SER_NETWORK_INFO, "BLE Up");
142+
return true;
143+
}
144+
145+
bool BLEDeviceInitialisation::attemptNewConnection(BaseRemoteServerConnection *transport) {
146+
central = BLE.central();
147+
if(central.connected()) {
148+
reinterpret_cast<BLETagValTransport*>(transport)->connectedClient();
149+
return true;
150+
}
151+
return false;
152+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
The code in this file uses open source libraries provided by thecoderscorner
3+
4+
DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER
5+
INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE.
6+
7+
All the variables you may need access to are marked extern in this file for easy
8+
use elsewhere.
9+
*/
10+
11+
#ifndef TCMENU_BLEREMOTECONNECTOR_H
12+
#define TCMENU_BLEREMOTECONNECTOR_H
13+
14+
#include <PlatformDetermination.h>
15+
#include <RemoteTypes.h>
16+
#include <RemoteConnector.h>
17+
#include <MessageProcessors.h>
18+
#include <ArduinoBLE.h>
19+
#include <remote/BaseRemoteComponents.h>
20+
#include <remote/BaseBufferedRemoteTransport.h>
21+
22+
#ifndef LARGEST_PROCESSABLE_MSG
23+
#define LARGEST_PROCESSABLE_MSG 512
24+
#endif
25+
26+
extern const PROGMEM ConnectorLocalInfo applicationInfo;
27+
28+
namespace tcremote {
29+
30+
const char bleServiceIdentifier[] PROGMEM = "8589F957-1916-4B27-BA6D-B0AF36F317EF";
31+
const char characteristicApiToDevice[] PROGMEM = "7E7CA4D5-CF52-4918-BD60-6E98A810F0EB";
32+
const char characteristicDeviceToApi[] PROGMEM = "D361F4F9-B13D-4118-A6C4-B54CF12EED3C";
33+
const char characteristicApiSeqCounter[] PROGMEM = "AB2ED3BE-C8C4-4E0D-8BF9-E7D6717F761C";
34+
const char characteristicDeviceSeqCounter[] PROGMEM = "79A24791-EEDA-4DA5-9E8C-04B8C9060B1F";
35+
36+
extern BLEDevice central;
37+
extern BLEService bleApiService;
38+
extern BLECharacteristic toApiCharacteristic;
39+
extern BLECharacteristic fromApiCharacteristic;
40+
extern BLECharacteristic deviceSequenceCharacteristic;
41+
extern BLECharacteristic apiSequenceCharacteristic;
42+
43+
class BLEDeviceInitialisation : public DeviceInitialisation {
44+
public:
45+
BLEDeviceInitialisation() = default;
46+
bool attemptInitialisation() override;
47+
bool attemptNewConnection(BaseRemoteServerConnection *connection) override;
48+
};
49+
50+
enum TcConnectionStateType { BLE_CON_DISCONNECTED, BLE_CON_BUILDING_MSG, BLE_CON_SENDING_MSG, BLE_CON_AWAITING_ACK};
51+
52+
class BLETagValTransport : public BaseBufferedRemoteTransport {
53+
private:
54+
uint32_t currDeviceSequence;
55+
uint32_t currApiSequence;
56+
public:
57+
BLETagValTransport();
58+
int fillReadBuffer(uint8_t* dataBuffer, int maxSize) override;
59+
bool readAvailable() override;
60+
void flush() override;
61+
bool available() override;
62+
bool connected() override;
63+
void connectedClient();
64+
};
65+
}
66+
67+
#endif //TCMENU_BLEREMOTECONNECTOR_H
File renamed without changes.
File renamed without changes.

examples/arduino32/nano33ble/nano33ble.emf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,13 @@
364364
],
365365
"namingRecursive": true,
366366
"useCppMain": false,
367-
"saveLocation": "ALL_TO_CURRENT",
367+
"saveLocation": "PROJECT_TO_CURRENT_WITH_GENERATED",
368368
"usingSizedEEPROMStorage": false,
369369
"eepromDefinition": "",
370370
"authenticatorDefinition": "",
371371
"projectIoExpanders": [
372-
"customIO:io23017",
373-
"deviceIO:"
372+
"deviceIO:",
373+
"customIO:io23017"
374374
],
375375
"menuInMenuCollection": {
376376
"menuDefinitions": []

examples/arduino32/nano33ble/nano33ble.ino

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Getting started: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/tcmenu-overview-quick-start/
1010
*/
1111

12-
#include "nano33ble_menu.h"
12+
#include "generated/nano33ble_menu.h"
1313
#include "SensorManager.h"
1414
#include "MotionDetection.h"
1515
#include <AnalogDeviceAbstraction.h>
@@ -26,7 +26,12 @@ SensorManager sensorManager;
2626
MotionDetection motionDetection;
2727

2828
void setup() {
29+
// start up serial and wait for it to actually begin, needed on this board.
2930
Serial.begin(115200);
31+
while(!Serial);
32+
33+
serEnableLevel(SER_NETWORK_DEBUG, true);
34+
3035
Wire.begin();
3136
Wire.setClock(400000);
3237

0 commit comments

Comments
 (0)