Skip to content

Commit e0b8419

Browse files
authored
Merge pull request #575 from LeeLeahy2/air-speed
Make operating mode and airSpeed easy to change
2 parents 70771ee + 84d49f8 commit e0b8419

File tree

6 files changed

+115
-137
lines changed

6 files changed

+115
-137
lines changed

Firmware/LoRaSerial/Commands.ino

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,25 +1261,7 @@ bool valSpeedAir (void * value, uint32_t valMin, uint32_t valMax)
12611261
UNUSED(valMin);
12621262
UNUSED(valMax);
12631263

1264-
valid = ((settingValue == 40)
1265-
|| (settingValue == 150)
1266-
|| (settingValue == 400)
1267-
|| (settingValue == 1200)
1268-
|| (settingValue == 2400)
1269-
|| (settingValue == 4800)
1270-
|| (settingValue == 9600)
1271-
|| (settingValue == 19200)
1272-
|| (settingValue == 28800)
1273-
|| (settingValue == 38400));
1274-
if (valid)
1275-
{
1276-
//Adjust the settings to match the requested airSpeed
1277-
convertAirSpeedToSettings(&tempSettings, settingValue);
1278-
airSpeed = settingValue;
1279-
systemPrintln("Warning: AirSpeed overrides bandwidth, coding rate, spread factor,");
1280-
systemPrintln("heartbeatTimeout, and txToRxUsec");
1281-
}
1282-
return valid;
1264+
return validateAirSpeed(&tempSettings, settingValue);
12831265
}
12841266

12851267
//Validate the SerialSpeed value

Firmware/LoRaSerial/LoRaSerial.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const int FIRMWARE_VERSION_MINOR = 0;
4545
#define RADIOLIB_LOW_LEVEL //Enable access to the module functions
4646
//#define ENABLE_DEVELOPER true //Uncomment this line to enable special developer modes
4747

48+
#define DEFAULT_AIR_SPEED 4800
49+
#define DEFAULT_OPERATING_MODE MODE_POINT_TO_POINT
50+
4851
#define UNUSED(x) (void)(x)
4952

5053
//Define the LoRaSerial board identifier:

Firmware/LoRaSerial/NVM.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ void getDefaultSettings(Settings * newSettings)
6565

6666
//Set the initial radio parameters
6767
*newSettings = defaultSettings;
68+
validateAirSpeed(newSettings, DEFAULT_AIR_SPEED);
6869
}
6970

7071
//Modify defaults for each radio type (915, 868, 433, etc)

Firmware/LoRaSerial/Radio.ino

Lines changed: 53 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -105,126 +105,68 @@ bool configureRadio()
105105
return success;
106106
}
107107

108-
//Update the settings based upon the airSpeed value
109-
void convertAirSpeedToSettings(Settings *newSettings, uint16_t airSpeed)
110-
{
111-
switch (airSpeed)
112-
{
113-
default:
114-
systemPrint("Unknown airSpeed: ");
115-
systemPrintln(airSpeed);
116-
waitForever("ERROR - Invalid airSpeed value");
117-
break;
118-
case (40):
119-
newSettings->radioSpreadFactor = 11;
120-
newSettings->radioBandwidth = 62.5;
121-
newSettings->radioCodingRate = 8;
122-
//HEARTBEAT bytes worst case
123-
// P2P - 13,
124-
// MP - 7,
125-
// VC - 30,
126-
if (newSettings->operatingMode == MODE_VIRTUAL_CIRCUIT)
127-
newSettings->heartbeatTimeout = 60 * 1000;
128-
else
129-
newSettings->heartbeatTimeout = 25 * 1000;
130-
//uSec: 26018 26026 26026 26025 26020 26038 ==> ~26026
131-
newSettings->txToRxUsec = 26026;
132-
break;
133-
case (150):
134-
newSettings->radioSpreadFactor = 10;
135-
newSettings->radioBandwidth = 62.5;
136-
newSettings->radioCodingRate = 8;
137-
if (newSettings->operatingMode == MODE_VIRTUAL_CIRCUIT)
138-
newSettings->heartbeatTimeout = 15 * 1000;
139-
else
140-
newSettings->heartbeatTimeout = 8 * 1000;
141-
//uSec: 12187 12188 12189 12190 12191 12194 ==> ~12190
142-
newSettings->txToRxUsec = 12190;
143-
break;
144-
case (400):
145-
newSettings->radioSpreadFactor = 10;
146-
newSettings->radioBandwidth = 125;
147-
newSettings->radioCodingRate = 8;
108+
const char * verifyAirSpeedTable ()
109+
{
110+
bool valid;
111+
112+
//Verify the length of the airSpeed table
113+
valid = (AIR_SPEED_MAX_ENTRIES == airSpeedTableEntries);
114+
if (!valid)
115+
return "ERROR: Fix difference between AIR_SPEED_MAX_ENTRIES and airSpeedTable";
116+
return NULL;
117+
}
118+
119+
//Validate the AirSpeed value
120+
bool validateAirSpeed (Settings * newSettings, uint32_t value)
121+
{
122+
int index;
123+
124+
//Validate the airspeed value
125+
for (index = 0; index < airSpeedTableEntries; index++)
126+
{
127+
if (value == airSpeedTable[index].airSpeed)
128+
{
129+
//Adjust the settings to match the requested airSpeed
130+
airSpeed = value;
131+
newSettings->radioBandwidth = airSpeedTable[index].bandwidth;
132+
newSettings->radioCodingRate = airSpeedTable[index].codingRate;
133+
newSettings->radioSpreadFactor = airSpeedTable[index].spreadFactor;
134+
newSettings->radioPreambleLength = airSpeedTable[index].preambleLength;
135+
newSettings->txToRxUsec = airSpeedTable[index].txToRxUsec;
148136
if (newSettings->operatingMode == MODE_VIRTUAL_CIRCUIT)
149-
newSettings->heartbeatTimeout = 9 * 1000;
137+
newSettings->heartbeatTimeout = airSpeedTable[index].vcHbMsec;
150138
else
151-
newSettings->heartbeatTimeout = 5 * 1000;
152-
//uSec: 6072 6070 6072 6070 6069 6067 ==> ~6070
153-
newSettings->txToRxUsec = 6070;
154-
break;
155-
case (1200):
156-
newSettings->radioSpreadFactor = 9;
157-
newSettings->radioBandwidth = 125;
158-
newSettings->radioCodingRate = 8;
159-
newSettings->heartbeatTimeout = 5 * 1000;
160-
//uSec: 2770 2777 2772 2773 2771 2773 ==> ~2773
161-
newSettings->txToRxUsec = 2773;
162-
break;
163-
case (2400):
164-
newSettings->radioSpreadFactor = 10;
165-
newSettings->radioBandwidth = 500;
166-
newSettings->radioCodingRate = 8;
167-
newSettings->heartbeatTimeout = 5 * 1000;
168-
//uSec: 1495 1481 1482 1481 1482 1481 ==> ~1484
169-
newSettings->txToRxUsec = 1484;
170-
break;
171-
case (4800):
172-
newSettings->radioSpreadFactor = 9;
173-
newSettings->radioBandwidth = 500;
174-
newSettings->radioCodingRate = 8;
175-
newSettings->heartbeatTimeout = 5 * 1000;
176-
//uSec: 657 657 657 658 657 657 ==> ~657
177-
newSettings->txToRxUsec = 657;
178-
break;
179-
case (9600):
180-
newSettings->radioSpreadFactor = 8;
181-
newSettings->radioBandwidth = 500;
182-
newSettings->radioCodingRate = 7;
183-
newSettings->heartbeatTimeout = 5 * 1000;
184-
//uSec: 279 279 281 280 280 279 ==> ~280
185-
newSettings->txToRxUsec = 280;
186-
break;
187-
case (19200):
188-
newSettings->radioSpreadFactor = 7;
189-
newSettings->radioBandwidth = 500;
190-
newSettings->radioCodingRate = 7;
191-
newSettings->heartbeatTimeout = 5 * 1000;
192-
//uSec: 119 118 118 119 120 119 ==> ~119
193-
newSettings->txToRxUsec = 119;
194-
break;
195-
case (28800):
196-
newSettings->radioSpreadFactor = 6;
197-
newSettings->radioBandwidth = 500;
198-
newSettings->radioCodingRate = 6;
199-
newSettings->heartbeatTimeout = 5 * 1000;
200-
//uSec: ???
201-
newSettings->txToRxUsec = 0;
202-
break;
203-
case (38400):
204-
newSettings->radioSpreadFactor = 6;
205-
newSettings->radioBandwidth = 500;
206-
newSettings->radioCodingRate = 5;
207-
newSettings->heartbeatTimeout = 5 * 1000;
208-
//uSec: ???
209-
newSettings->txToRxUsec = 0;
210-
break;
139+
newSettings->heartbeatTimeout = airSpeedTable[index].p2pHbMsec;
140+
systemPrintln("Warning: AirSpeed overrides bandwidth, coding rate, spread factor,");
141+
systemPrintln("heartbeatTimeout, and txToRxUsec");
142+
return true;
143+
}
211144
}
145+
146+
//Unknown airSpeed value
147+
systemPrint("Unknown airSpeed: ");
148+
systemPrintln(airSpeed);
149+
waitForever("ERROR - Invalid airSpeed value");
150+
return false;
212151
}
213152

214153
//Given settings, attempt to ID our airSpeed
215154
uint16_t convertSettingsToAirSpeed(Settings *newSettings)
216155
{
217-
if ( (newSettings->radioBandwidth == 62.5) && (newSettings->radioSpreadFactor == 11) && (newSettings->radioCodingRate == 8) ) return (40);
218-
else if ( (newSettings->radioBandwidth == 62.5) && (newSettings->radioSpreadFactor == 10) && (newSettings->radioCodingRate == 8) ) return (150);
219-
else if ( (newSettings->radioBandwidth == 125) && (newSettings->radioSpreadFactor == 10) && (newSettings->radioCodingRate == 8) ) return (400);
220-
else if ( (newSettings->radioBandwidth == 125) && (newSettings->radioSpreadFactor == 9) && (newSettings->radioCodingRate == 8) )return (1200);
221-
else if ( (newSettings->radioBandwidth == 500) && (newSettings->radioSpreadFactor == 10) && (newSettings->radioCodingRate == 8) )return (2400);
222-
else if ( (newSettings->radioBandwidth == 500) && (newSettings->radioSpreadFactor == 9) && (newSettings->radioCodingRate == 8) )return (4800);
223-
else if ( (newSettings->radioBandwidth == 500) && (newSettings->radioSpreadFactor == 8) && (newSettings->radioCodingRate == 7) ) return (9600);
224-
else if ( (newSettings->radioBandwidth == 500) && (newSettings->radioSpreadFactor == 7) && (newSettings->radioCodingRate == 7) ) return (19200);
225-
else if ( (newSettings->radioBandwidth == 500) && (newSettings->radioSpreadFactor == 6) && (newSettings->radioCodingRate == 6) ) return (28800);
226-
else if ( (newSettings->radioBandwidth == 500) && (newSettings->radioSpreadFactor == 6) && (newSettings->radioCodingRate == 5) ) return (38400);
156+
int index;
157+
158+
//Check for a match within the table
159+
for (index = 0; index < airSpeedTableEntries; index++)
160+
{
161+
//bandwidth, codingRate and spreadFactor determine the airSpeed
162+
if ((newSettings->radioBandwidth == airSpeedTable[index].bandwidth)
163+
&& (newSettings->radioCodingRate == airSpeedTable[index].codingRate)
164+
&& (newSettings->radioPreambleLength == airSpeedTable[index].preambleLength)
165+
&& (newSettings->radioSpreadFactor == airSpeedTable[index].spreadFactor))
166+
return airSpeedTable[index].airSpeed;
167+
}
227168

169+
//Unknown airSpeed
228170
systemPrint("Unknown airSpeed for Bandwidth: ");
229171
systemPrint(newSettings->radioBandwidth);
230172
systemPrint(" SpreadFactor: ");

Firmware/LoRaSerial/System.ino

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,11 @@ void verifyTables()
12871287
if (errorMessage)
12881288
break;
12891289

1290+
//Verify the airSpeed table
1291+
errorMessage = verifyAirSpeedTable();
1292+
if(errorMessage)
1293+
break;
1294+
12901295
//Verify the VC state name table
12911296
errorMessage = verifyVcStateNames();
12921297
if (errorMessage)

Firmware/LoRaSerial/settings.h

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,51 @@ typedef struct _CLOCK_SYNC_DATA
378378
bool timeToHop;
379379
} CLOCK_SYNC_DATA;
380380

381+
typedef struct _AIR_SPEED_TABLE
382+
{
383+
uint16_t airSpeed; //Approximate air speed bit rate
384+
float bandwidth; //kHz, possible values 62.5 / 125 / 250 / 500
385+
uint8_t codingRate; //5 to 8. Higher coding rates ensure less packets dropped.
386+
uint8_t spreadFactor; //6 to 12. Use higher factor for longer range.
387+
uint16_t preambleLength; //Number of symbols. Different lengths does *not* guarantee a remote radio privacy. 8 to 11 works. 8 to 15 drops some. 8 to 20 is silent.
388+
uint32_t txToRxUsec; //TX transactionComplete to RX transactionComplete in microseconds
389+
uint16_t p2pHbMsec; //ms before sending HEARTBEAT to see if link is active
390+
uint16_t vcHbMsec; //ms before sending HEARTBEAT to see if link is active
391+
} AIR_SPEED_TABLE;
392+
393+
const AIR_SPEED_TABLE airSpeedTable[] =
394+
{// air coding spread preamble txToRx
395+
// Speed bandwidth Rate Factor Length Usec p2pHbMsec vcHbMsec
396+
{ 40, 62.5, 8, 11, 8, 26026, 25 * 1000, 60 * 1000},
397+
{ 150, 62.5, 8, 10, 8, 12190, 8 * 1000, 15 * 1000},
398+
{ 400, 125, 8, 10, 8, 6070, 5 * 1000, 9 * 1000},
399+
{ 1200, 125, 8, 9, 8, 2773, 5 * 1000, 5 * 1000},
400+
{ 2400, 500, 8, 10, 8, 1484, 5 * 1000, 5 * 1000},
401+
{ 4800, 500, 8, 9, 8, 657, 5 * 1000, 5 * 1000},
402+
{ 9600, 500, 7, 8, 8, 280, 5 * 1000, 5 * 1000},
403+
{ 19200, 500, 7, 7, 8, 119, 5 * 1000, 5 * 1000},
404+
{ 28800, 500, 6, 6, 8, 0, 5 * 1000, 5 * 1000},
405+
{ 38400, 500, 5, 6, 8, 0, 5 * 1000, 5 * 1000},
406+
};
407+
const int airSpeedTableEntries = sizeof(airSpeedTable) / sizeof(airSpeedTable[0]);
408+
409+
typedef enum
410+
{
411+
AIR_SPEED_40,
412+
AIR_SPEED_150,
413+
AIR_SPEED_400,
414+
AIR_SPEED_1200,
415+
AIR_SPEED_2400,
416+
AIR_SPEED_4800,
417+
AIR_SPEED_9600,
418+
AIR_SPEED_19200,
419+
AIR_SPEED_28800,
420+
AIR_SPEED_38400,
421+
422+
//Number of airSpeed entries
423+
AIR_SPEED_MAX_ENTRIES
424+
} AIR_SPEED_VALUES;
425+
381426
//These are all the settings that can be set on Serial Terminal Radio. It's recorded to NVM.
382427
typedef struct struct_settings {
383428
uint16_t sizeOfSettings = 0; //sizeOfSettings **must** be the first entry and must be int
@@ -389,8 +434,8 @@ typedef struct struct_settings {
389434

390435
float frequencyMin = 902.0; //MHz
391436
float frequencyMax = 928.0; //MHz
392-
float radioBandwidth = 500.0; //kHz 125/250/500 generally. We need 500kHz for higher data.
393-
uint32_t txToRxUsec = 657; //TX transactionComplete to RX transactionComplete in microseconds
437+
float radioBandwidth = 0;
438+
uint32_t txToRxUsec = 0;
394439

395440
bool frequencyHop = true; //Hop between frequencies to avoid dwelling on any one channel for too long
396441
uint8_t numberOfChannels = 50; //Divide the min/max freq band into this number of channels and hop between.
@@ -402,18 +447,18 @@ typedef struct struct_settings {
402447
#define TX_POWER_DB 30
403448
#endif //ENABLE_DEVELOPER
404449
uint8_t radioBroadcastPower_dbm = TX_POWER_DB; //Transmit power in dBm. Max is 30dBm (1W), min is 14dBm (25mW).
405-
uint8_t radioCodingRate = 8; //5 to 8. Higher coding rates ensure less packets dropped.
406-
uint8_t radioSpreadFactor = 9; //6 to 12. Use higher factor for longer range.
450+
uint8_t radioCodingRate = 0;
451+
uint8_t radioSpreadFactor = 0;
407452
uint8_t radioSyncWord = 18; //18 = 0x12 is default for custom/private networks. Different sync words does *not* guarantee a remote radio will not get packet.
408453

409-
uint16_t radioPreambleLength = 8; //Number of symbols. Different lengths does *not* guarantee a remote radio privacy. 8 to 11 works. 8 to 15 drops some. 8 to 20 is silent.
454+
uint16_t radioPreambleLength = 0; //Number of symbols. Different lengths does *not* guarantee a remote radio privacy. 8 to 11 works. 8 to 15 drops some. 8 to 20 is silent.
410455
bool autoTuneFrequency = false; //Based on the last packets frequency error, adjust our next transaction frequency
411456

412457
//----------------------------------------
413458
//Radio protocol parameters
414459
//----------------------------------------
415460

416-
uint8_t operatingMode = MODE_POINT_TO_POINT; //Receiving unit will check netID and ACK. If set to false, receiving unit doesn't check netID or ACK.
461+
uint8_t operatingMode = DEFAULT_OPERATING_MODE; //Receiving unit will check netID and ACK. If set to false, receiving unit doesn't check netID or ACK.
417462

418463
uint8_t selectLedUse = LEDS_RSSI; //Select LED use
419464
bool server = false; //Default to being a client, enable server for multipoint, VC and training
@@ -427,7 +472,7 @@ typedef struct struct_settings {
427472
bool enableCRC16 = true; //Append CRC-16 to packet, check CRC-16 upon receive
428473
uint8_t framesToYield = 3; //If remote requests it, supress transmission for this number of max packet frames
429474

430-
uint16_t heartbeatTimeout = 5000; //ms before sending HEARTBEAT to see if link is active
475+
uint16_t heartbeatTimeout = 0;
431476
uint16_t overheadTime = 10; //ms added to ack and datagram times before ACK timeout occurs
432477

433478
uint8_t maxResends = 0; //Attempt resends up to this number, 0 = infinite retries

0 commit comments

Comments
 (0)