Skip to content

Commit d82f013

Browse files
committed
New training button behavior
When the training button is pressed the green LEDs start counting seconds. When the 4 second boundary is crossed the yellow LED starts to blink. When the 8 second boundary is crossed the blue LED starts to blink. When the time reaches 15 seconds the radio clears NVM and resets. Upon boot the LoRaSerial radio starts with factory settings.
1 parent 4ff483d commit d82f013

File tree

4 files changed

+126
-35
lines changed

4 files changed

+126
-35
lines changed

Firmware/LoRaSerial/LoRaSerial.ino

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,11 @@ uint8_t AESiv[AES_IV_BYTES] = {0}; //Set during hop table generation
166166
#include <JC_Button.h> // http://librarymanager/All#JC_Button //v2.1.2
167167
Button *trainBtn = NULL; //We can't instantiate the button here because we don't yet know what pin number to use
168168

169-
const int trainButtonTime = 2000; //ms press and hold before entering training
170-
bool trainViaButton = false; //Allows auto-creation of server if client times out
169+
const int trainButtonClientTime = 4 * 1000; //ms press and hold before entering client training
170+
const int trainButtonServerTime = 8 * 1000; //ms press and hold before entering server training
171+
const int trainButtonFactoryResetTime = 16 * 1000; //ms press and hold before reset
172+
173+
bool inTraining; //True if training is in process
171174
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
172175

173176
//Hardware Timers

Firmware/LoRaSerial/States.ino

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,12 +1717,16 @@ void updateRadioState()
17171717

17181718
//If we are training via button, and in point to point mode, and the user has not manually set the server
17191719
//then reboot with current settings after a single client acks
1720-
if (trainViaButton
1721-
&& tempSettings.operatingMode == MODE_POINT_TO_POINT
1722-
&& tempSettings.server == false)
1720+
if (inTraining
1721+
&& (trainingSettings.operatingMode == MODE_POINT_TO_POINT)
1722+
&& (!trainingSettings.server))
17231723
{
1724+
//Save the training parameters
1725+
settings = trainingSettings;
1726+
recordSystemSettings();
1727+
17241728
//Reboot the radio with the newly generated random netID/Key parameters
1725-
commandReset;
1729+
commandReset();
17261730
}
17271731
}
17281732
break;

Firmware/LoRaSerial/System.ino

Lines changed: 112 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -257,35 +257,97 @@ uint8_t systemRead()
257257
//Check the train button and change state accordingly
258258
void updateButton()
259259
{
260-
static TrainStates trainState = TRAIN_NO_PRESS;
260+
bool buttonPressed;
261+
static bool buttonWasPressed;
262+
uint32_t deltaTime;
263+
static Settings originalSettings;
264+
static uint32_t pressedTime;
261265

262266
if (trainBtn != NULL)
263267
{
264-
trainBtn->read();
268+
//Determine the previous state of the button
269+
buttonPressed = trainBtn->read();
265270

266-
if (trainState == TRAIN_NO_PRESS && trainBtn->pressedFor(trainButtonTime))
271+
//Determine the current button state
272+
if (buttonWasPressed)
267273
{
268-
trainState = TRAIN_PRESSED;
269-
270-
trainViaButton = true;
271-
trainingSettings = settings;
272-
selectTraining();
273-
}
274-
else if (trainState == TRAIN_PRESSED && trainBtn->wasReleased())
275-
{
276-
trainState = TRAIN_IN_PROCESS;
274+
//Update the LEDs
275+
deltaTime = millis() - pressedTime;
276+
buttonLeds(deltaTime);
277+
if (!buttonPressed)
278+
{
279+
//Button just released
280+
settings = originalSettings;
281+
282+
//Check for reset to factory settings
283+
if (deltaTime >= trainButtonFactoryResetTime)
284+
{
285+
//Erase the EEPROM
286+
nvmErase();
287+
288+
//Reboot the radio
289+
commandReset();
290+
}
291+
292+
//Starting training or exiting training via the button is only possible
293+
//when the radio is not in command mode!
294+
else if (!inCommandMode)
295+
{
296+
//Check for server training request
297+
if (deltaTime >= trainButtonServerTime)
298+
{
299+
//Set the training settings
300+
trainingSettings = settings;
301+
inTraining = true;
302+
if (settings.operatingMode == MODE_POINT_TO_POINT)
303+
{
304+
//Select a random netID and encryption key
305+
generateRandomKeysID(&trainingSettings);
306+
}
307+
beginTrainingServer();
308+
}
309+
310+
//Check for client training request
311+
else if (deltaTime >= trainButtonClientTime)
312+
{
313+
trainingSettings = settings; //Set the training settings
314+
inTraining = true;
315+
beginTrainingClient();
316+
}
317+
318+
//Exit training
319+
else
320+
{
321+
//The user has stopped training with the button
322+
//Restore the previous settings
323+
settings = originalSettings;
324+
if (inTraining)
325+
{
326+
inTraining = false;
327+
changeState(RADIO_RESET);
328+
}
329+
}
330+
}
331+
}
277332
}
278-
else if (trainState == TRAIN_IN_PROCESS && trainBtn->wasReleased())
279-
{
280-
settings = trainingSettings; //Return to original radio settings
281333

282-
recordSystemSettings(); //Record original settings
334+
//The button was not previously pressed
335+
else
336+
{
337+
//Determine if the button is pressed
338+
if (buttonPressed)
339+
{
340+
//Button just pressed
341+
pressedTime = millis();
283342

284-
//Reboot the radio
285-
petWDT();
286-
systemFlush();
287-
systemReset();
343+
//Save the previous led state
344+
if (!inTraining)
345+
originalSettings = settings;
346+
}
288347
}
348+
349+
//Save the current button state
350+
buttonWasPressed = buttonPressed;
289351
}
290352
}
291353

@@ -1001,6 +1063,36 @@ void updateCylonLEDs()
10011063
blinkRadioTxLed(false);
10021064
}
10031065

1066+
//Acknowledge the button press
1067+
void buttonLeds(uint32_t pressedMilliseconds)
1068+
{
1069+
const uint32_t blinkTime = 1000 / 4; //Blink 4 times per second
1070+
uint8_t on;
1071+
const uint32_t onTime = blinkTime / 2;
1072+
uint8_t seconds;
1073+
1074+
//Display the number of seconds the button has been pushed
1075+
seconds = pressedMilliseconds / 1000;
1076+
setRSSI((pressedMilliseconds >= trainButtonFactoryResetTime) ? 15 : seconds);
1077+
1078+
if (!inCommandMode)
1079+
{
1080+
//Determine the blink state
1081+
on = (pressedMilliseconds % blinkTime) >= onTime;
1082+
1083+
//Determine which LED to blink
1084+
if (pressedMilliseconds >= trainButtonServerTime)
1085+
{
1086+
//Blink the blue LED
1087+
digitalWrite(BLUE_LED, on);
1088+
digitalWrite(YELLOW_LED, 0);
1089+
}
1090+
else if (pressedMilliseconds >= trainButtonClientTime)
1091+
//Blink the yellow LED
1092+
digitalWrite(YELLOW_LED, on);
1093+
}
1094+
}
1095+
10041096
//Update the LED values depending upon the selected display
10051097
//This is the only function that touches the LEDs
10061098
void updateLeds()

Firmware/LoRaSerial/settings.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,6 @@ typedef struct _VIRTUAL_CIRCUIT
227227
#define ADD_VC_STATE_NAMES_TABLE
228228
#include "Virtual_Circuit_Protocol.h"
229229

230-
//Train button states
231-
typedef enum
232-
{
233-
TRAIN_NO_PRESS = 0,
234-
TRAIN_PRESSED,
235-
TRAIN_IN_PROCESS,
236-
} TrainStates;
237-
238230
enum
239231
{ //#, Width - Computed with:
240232
// triggerWidth = 25
@@ -358,7 +350,7 @@ typedef enum
358350
LEDS_RADIO_USE, // 3: Green1: RX, Green2: Link, Green3: RSSI, Green4: TX
359351
// Blue: Bad frames, Yellow: Bad CRC
360352
LEDS_RSSI, // 4: Green: RSSI, Blue: Serial TX, Yellow: Serial RX
361-
LEDS_RESERVED_1, // 5
353+
LEDS_BUTTON_PRESS,// 5: Green: Seconds, Yellow: Client, Blue: Server
362354
LEDS_RESERVED_2, // 6
363355
LEDS_CYLON, // 7: Display the cylon pattern on the green LEDs, others off
364356

0 commit comments

Comments
 (0)