Skip to content

Commit 5cc0cda

Browse files
authored
Merge pull request #503 from LeeLeahy2/new-training
New training button behavior
2 parents 86b6781 + d82f013 commit 5cc0cda

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)