Skip to content

Commit 1e2fb32

Browse files
committed
Make start/stop Bluetooth/WiFi reentrant.
1 parent d02d403 commit 1e2fb32

File tree

4 files changed

+82
-135
lines changed

4 files changed

+82
-135
lines changed

Firmware/RTK_Surveyor/RTK_Surveyor.ino

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
Add ntripServer_CasterUser/PW to AP config
4545
Add maxLogLength_minutes to AP config
4646
Add LBand to AP config
47+
4748
*/
4849

4950
const int FIRMWARE_VERSION_MAJOR = 2;
@@ -159,8 +160,7 @@ uint32_t sdUsedSpaceMB = 0;
159160
#include <WiFiClientSecure.h> //Built-in.
160161
#include <PubSubClient.h> //Built-in. Used for MQTT obtaining of keys
161162

162-
#include "esp_wifi.h" //Needed for init/deinit of resources to free up RAM
163-
#include "base64.h" //Built-in ESP32 library. Needed for NTRIP Client credential encoding.
163+
#include "base64.h" //Built-in. Needed for NTRIP Client credential encoding.
164164

165165
WiFiClient ntripServer; // The WiFi connection to the NTRIP caster. We use this to push local RTCM to the caster.
166166
WiFiClient ntripClient; // The WiFi connection to the NTRIP caster. We use this to obtain RTCM from the caster.
@@ -259,8 +259,6 @@ float battChangeRate = 0.0;
259259
//We use a local copy of the BluetoothSerial library so that we can increase the RX buffer. See issue: https://github.com/sparkfun/SparkFun_RTK_Firmware/issues/23
260260
#include "src/BluetoothSerial/BluetoothSerial.h"
261261
BluetoothSerial SerialBT;
262-
#include "esp_bt.h" //Core access is needed for BT stop. See customBTstop() for more info.
263-
#include "esp_gap_bt_api.h" //Needed for setting of pin. See issue: https://github.com/sparkfun/SparkFun_RTK_Firmware/issues/5
264262
#endif
265263

266264
char platformPrefix[40] = "Surveyor"; //Sets the prefix for broadcast names

Firmware/RTK_Surveyor/States.ino

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void updateSystemState()
153153
{
154154
//Turn off Bluetooth and turn on WiFi
155155
stopBluetooth();
156-
startClientWiFi();
156+
startWiFi(settings.ntripClient_wifiSSID, settings.ntripClient_wifiPW);
157157
wifiStartTime = millis();
158158

159159
ntripClientAttempted = true; //Do not allow re-entry into STATE_ROVER_CLIENT_WIFI_STARTED
@@ -605,7 +605,7 @@ void updateSystemState()
605605
{
606606
//Turn off Bluetooth and turn on WiFi
607607
stopBluetooth();
608-
startServerWiFi();
608+
startWiFi(settings.ntripServer_wifiSSID, settings.ntripServer_wifiPW);
609609

610610
changeState(STATE_BASE_TEMP_WIFI_STARTED);
611611
}
@@ -834,7 +834,7 @@ void updateSystemState()
834834
{
835835
//Turn off Bluetooth and turn on WiFi
836836
stopBluetooth();
837-
startServerWiFi();
837+
startWiFi(settings.ntripServer_wifiSSID, settings.ntripServer_wifiPW);
838838

839839
rtcmPacketsSent = 0; //Reset any previous number
840840

@@ -1128,7 +1128,7 @@ void updateSystemState()
11281128
//If we don't have keys, begin zero touch provisioning
11291129
else if (strlen(settings.pointPerfectCurrentKey) == 0 || strlen(settings.pointPerfectNextKey) == 0)
11301130
{
1131-
startHomeWiFi();
1131+
startWiFi(settings.home_wifiSSID, settings.home_wifiPW);
11321132
wifiStartTime = millis(); //Start timer for WiFi connection timeout
11331133
changeState(STATE_KEYS_PROVISION_WIFI_STARTED);
11341134
}
@@ -1163,7 +1163,7 @@ void updateSystemState()
11631163

11641164
if (online.rtc == false)
11651165
{
1166-
startHomeWiFi();
1166+
startWiFi(settings.home_wifiSSID, settings.home_wifiPW);
11671167
wifiStartTime = 0; //Start timer for WiFi connection timeout
11681168
changeState(STATE_KEYS_WIFI_STARTED); //If we can't check the RTC, continue
11691169
}
@@ -1174,7 +1174,7 @@ void updateSystemState()
11741174
settings.lastKeyAttempt = rtc.getEpoch(); //Mark it
11751175
recordSystemSettings(); //Record these settings to unit
11761176

1177-
startHomeWiFi();
1177+
startWiFi(settings.home_wifiSSID, settings.home_wifiPW);
11781178
wifiStartTime = 0; //Start timer for WiFi connection timeout
11791179
changeState(STATE_KEYS_WIFI_STARTED);
11801180
}

Firmware/RTK_Surveyor/System.ino

Lines changed: 73 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,121 @@
11
//Get MAC, start radio
22
//Tack device's MAC address to end of friendly broadcast name
33
//This allows multiple units to be on at same time
4-
bool startBluetooth()
4+
void startBluetooth()
55
{
6+
if (radioState == WIFI_ON_NOCONNECTION || radioState == WIFI_CONNECTED)
7+
stopWiFi();
8+
9+
if (radioState == RADIO_OFF)
10+
{
611
#ifdef COMPILE_BT
7-
char stateName[10];
8-
if (buttonPreviousState == BUTTON_ROVER)
9-
strcpy(stateName, "Rover");
10-
else
11-
strcpy(stateName, "Base");
12+
char stateName[10];
13+
if (buttonPreviousState == BUTTON_ROVER)
14+
strcpy(stateName, "Rover");
15+
else
16+
strcpy(stateName, "Base");
1217

13-
sprintf(deviceName, "%s %s-%02X%02X", platformPrefix, stateName, unitMACAddress[4], unitMACAddress[5]); //Base mode
18+
sprintf(deviceName, "%s %s-%02X%02X", platformPrefix, stateName, unitMACAddress[4], unitMACAddress[5]); //Base mode
1419

15-
if (SerialBT.begin(deviceName, false, settings.sppRxQueueSize, settings.sppTxQueueSize) == false) //localName, isMaster, rxBufferSize, txBufferSize
16-
{
17-
Serial.println(F("An error occurred initializing Bluetooth"));
18-
radioState = RADIO_OFF;
20+
//if (SerialBT.begin(deviceName, false, settings.sppRxQueueSize, settings.sppTxQueueSize) == false) //localName, isMaster, rxBufferSize, txBufferSize
21+
if (SerialBT.begin(deviceName, false) == false) //localName, isMaster
22+
{
23+
Serial.println(F("An error occurred initializing Bluetooth"));
24+
radioState = RADIO_OFF;
1925

20-
if (productVariant == RTK_SURVEYOR)
21-
digitalWrite(pin_bluetoothStatusLED, LOW);
22-
return (false);
23-
}
26+
if (productVariant == RTK_SURVEYOR)
27+
digitalWrite(pin_bluetoothStatusLED, LOW);
28+
return;
29+
}
2430

25-
//Set PIN to 1234 so we can connect to older BT devices, but not require a PIN for modern device pairing
26-
//See issue: https://github.com/sparkfun/SparkFun_RTK_Firmware/issues/5
27-
//https://github.com/espressif/esp-idf/issues/1541
28-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
29-
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
31+
//Set PIN to 1234 so we can connect to older BT devices, but not require a PIN for modern device pairing
32+
//See issue: https://github.com/sparkfun/SparkFun_RTK_Firmware/issues/5
33+
//https://github.com/espressif/esp-idf/issues/1541
34+
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
35+
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
3036

31-
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE; //Requires pin 1234 on old BT dongle, No prompt on new BT dongle
32-
//esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_OUT; //Works but prompts for either pin (old) or 'Does this 6 pin appear on the device?' (new)
37+
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE; //Requires pin 1234 on old BT dongle, No prompt on new BT dongle
38+
//esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_OUT; //Works but prompts for either pin (old) or 'Does this 6 pin appear on the device?' (new)
3339

34-
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
40+
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
3541

36-
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
37-
esp_bt_pin_code_t pin_code;
38-
pin_code[0] = '1';
39-
pin_code[1] = '2';
40-
pin_code[2] = '3';
41-
pin_code[3] = '4';
42-
esp_bt_gap_set_pin(pin_type, 4, pin_code);
43-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
42+
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
43+
esp_bt_pin_code_t pin_code;
44+
pin_code[0] = '1';
45+
pin_code[1] = '2';
46+
pin_code[2] = '3';
47+
pin_code[3] = '4';
48+
esp_bt_gap_set_pin(pin_type, 4, pin_code);
49+
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
4450

45-
SerialBT.register_callback(btCallback); //Controls BT Status LED on Surveyor
46-
SerialBT.setTimeout(250);
51+
SerialBT.register_callback(btCallback); //Controls BT Status LED on Surveyor
52+
SerialBT.setTimeout(250);
4753

48-
Serial.print(F("Bluetooth broadcasting as: "));
49-
Serial.println(deviceName);
54+
Serial.print(F("Bluetooth broadcasting as: "));
55+
Serial.println(deviceName);
5056

51-
radioState = BT_ON_NOCONNECTION;
57+
//Start task for controlling Bluetooth pair LED
58+
if (productVariant == RTK_SURVEYOR)
59+
{
60+
ledcWrite(ledBTChannel, 255); //Turn on BT LED
61+
btLEDTask.detach(); //Slow down the BT LED blinker task
62+
btLEDTask.attach(btLEDTaskPace2Hz, updateBTled); //Rate in seconds, callback
63+
}
64+
#endif
5265

53-
//Start task for controlling Bluetooth pair LED
54-
if (productVariant == RTK_SURVEYOR)
55-
{
56-
ledcWrite(ledBTChannel, 255); //Turn on BT LED
57-
btLEDTask.detach(); //Slow down the BT LED blinker task
58-
btLEDTask.attach(btLEDTaskPace2Hz, updateBTled); //Rate in seconds, callback
66+
radioState = BT_ON_NOCONNECTION;
5967
}
60-
#endif
6168

62-
return (true);
6369
}
6470

6571
//This function stops BT so that it can be restarted later
6672
//It also releases as much system resources as possible so that WiFi/caster is more stable
6773
void stopBluetooth()
6874
{
75+
if (radioState == BT_ON_NOCONNECTION || radioState == BT_CONNECTED)
76+
{
6977
#ifdef COMPILE_BT
70-
SerialBT.flush(); //Complete any transfers
71-
SerialBT.disconnect(); //Drop any clients
72-
SerialBT.end(); //SerialBT.end() will release significant RAM (~100k!) but a SerialBT.start will crash.
78+
SerialBT.register_callback(NULL);
79+
SerialBT.flush(); //Complete any transfers
80+
SerialBT.disconnect(); //Drop any clients
81+
SerialBT.end(); //SerialBT.end() will release significant RAM (~100k!) but a SerialBT.start will crash.
7382
#endif
7483

75-
//The following code releases the BT hardware so that it can be restarted with a SerialBT.begin
76-
customBTstop();
77-
Serial.println(F("Bluetooth turned off"));
78-
79-
radioState = RADIO_OFF;
80-
}
81-
82-
//Starting and restarting BT is a problem. See issue: https://github.com/espressif/arduino-esp32/issues/2718
83-
//To work around the bug without modifying the core we create our own btStop() function with
84-
//the patch from github
85-
bool customBTstop() {
86-
#ifdef COMPILE_BT
87-
if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE) {
88-
return true;
89-
}
90-
if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED) {
91-
if (esp_bt_controller_disable()) {
92-
log_e("BT Disable failed");
93-
return false;
94-
}
95-
while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED);
96-
}
97-
if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED)
98-
{
99-
log_i("inited");
100-
if (esp_bt_controller_deinit())
101-
{
102-
log_e("BT deint failed");
103-
return false;
104-
}
105-
while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED)
106-
;
107-
return true;
84+
log_d("Bluetooth turned off");
85+
radioState = RADIO_OFF;
10886
}
109-
log_e("BT Stop failed");
110-
#endif
111-
return false;
11287
}
11388

114-
//Start WiFi assuming it was previously fully released
115-
//See WiFiBluetoothSwitch sketch for more info
116-
void startServerWiFi()
89+
void startWiFi(char* ssid, char* pw)
11790
{
118-
#ifdef COMPILE_WIFI
119-
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
120-
esp_wifi_init(&wifi_init_config); //Restart WiFi resources
121-
122-
Serial.printf("Connecting to local WiFi: %s\n\r", settings.ntripServer_wifiSSID);
123-
WiFi.begin(settings.ntripServer_wifiSSID, settings.ntripServer_wifiPW);
124-
#endif
91+
if (radioState == BT_ON_NOCONNECTION || radioState == BT_CONNECTED)
92+
stopBluetooth();
12593

126-
radioState = WIFI_ON_NOCONNECTION;
127-
}
128-
129-
void startClientWiFi()
130-
{
131-
#ifdef COMPILE_WIFI
132-
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
133-
esp_wifi_init(&wifi_init_config); //Restart WiFi resources
134-
135-
Serial.printf("Connecting to local WiFi: %s\n\r", settings.ntripClient_wifiSSID);
136-
WiFi.begin(settings.ntripClient_wifiSSID, settings.ntripClient_wifiPW);
137-
#endif
138-
139-
radioState = WIFI_ON_NOCONNECTION;
140-
}
141-
142-
void startHomeWiFi()
143-
{
94+
if (radioState == RADIO_OFF)
95+
{
14496
#ifdef COMPILE_WIFI
145-
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
146-
esp_wifi_init(&wifi_init_config); //Restart WiFi resources
147-
148-
Serial.printf("Connecting to home WiFi: %s", settings.home_wifiSSID);
149-
WiFi.begin(settings.home_wifiSSID, settings.home_wifiPW);
97+
Serial.printf("Connecting to WiFi: %s", ssid);
98+
WiFi.begin(ssid, pw);
15099
#endif
151100

152-
radioState = WIFI_ON_NOCONNECTION;
101+
radioState = WIFI_ON_NOCONNECTION;
102+
}
153103
}
154104

155105
//Stop WiFi and release all resources
156106
//See WiFiBluetoothSwitch sketch for more info
157107
void stopWiFi()
158108
{
109+
if (radioState == WIFI_ON_NOCONNECTION || radioState == WIFI_CONNECTED)
110+
{
159111
#ifdef COMPILE_WIFI
160112
ntripServer.stop();
161113
WiFi.mode(WIFI_OFF);
162-
163-
if (radioState == WIFI_ON_NOCONNECTION || radioState == WIFI_CONNECTED)
164-
esp_wifi_deinit(); //Free all resources
165114
#endif
166115

167116
log_d("WiFi Stopped");
168-
169117
radioState = RADIO_OFF;
118+
}
170119
}
171120

172121
//Setup the u-blox module for any setup (base or rover)
@@ -180,12 +129,12 @@ bool configureUbloxModule()
180129
int maxWait = 2000;
181130

182131
//Wait for initial report from module
183-
while(pvtUpdated == false)
132+
while (pvtUpdated == false)
184133
{
185134
i2cGNSS.checkUblox(); //Regularly poll to get latest data and any RTCM
186135
i2cGNSS.checkCallbacks(); //Process any callbacks: ie, eventTriggerReceived
187136
delay(10);
188-
if(millis() - startTime > maxWait) break;
137+
if (millis() - startTime > maxWait) break;
189138
}
190139

191140
//The first thing we do is go to 1Hz to lighten any I2C traffic from a previous configuration
@@ -494,7 +443,7 @@ void danceLEDs()
494443
else
495444
{
496445
//Units can boot under 1s. Keep splash screen up for at least 2s.
497-
while(millis() - splashStart < 2000) delay(1);
446+
while (millis() - splashStart < 2000) delay(1);
498447
}
499448
}
500449

Firmware/RTK_Surveyor/menuPP.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void menuPointPerfect()
6969
else if (incoming == '5')
7070
{
7171
#ifdef COMPILE_WIFI
72-
startHomeWiFi();
72+
startWiFi(settings.home_wifiSSID, settings.home_wifiPW);
7373

7474
unsigned long startTime = millis();
7575
while (WiFi.status() != WL_CONNECTED)

0 commit comments

Comments
 (0)