step 3
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -3,7 +3,9 @@
|
||||
"variables.h": "c",
|
||||
"arduino.h": "c",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp"
|
||||
"random": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"iterator": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"**/build": true
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* DEVICE_MODE_TX
|
||||
* DEVICE_MODE_RX
|
||||
*/
|
||||
#define DEVICE_MODE_TX
|
||||
// #define DEVICE_MODE_RX
|
||||
// #define DEVICE_MODE_TX
|
||||
#define DEVICE_MODE_RX
|
||||
|
||||
#define FEATURE_TX_OLED
|
||||
// #define FORCE_TX_WITHOUT_INPUT
|
||||
|
||||
@@ -90,19 +90,21 @@ volatile RadioState_t radioState = {};
|
||||
|
||||
uint8_t tmpBuffer[MAX_PACKET_SIZE];
|
||||
|
||||
void onQspSuccess(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDeviceState_t *rxDeviceState, volatile RadioState_t *radioState) {
|
||||
void onQspSuccess(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDeviceState_t *rxDeviceState, uint8_t receivedChannel) {
|
||||
//If recide received a valid frame, that means it can start to talk
|
||||
radioNode.lastReceivedChannel = receivedChannel;
|
||||
|
||||
qsp->canTransmit = true;
|
||||
|
||||
radioState->rssi = radioNode.getRadioRssi();
|
||||
radioState->snr = radioNode.getRadioSnr();
|
||||
radioNode.readRssi();
|
||||
radioNode.readSnr();
|
||||
|
||||
/*
|
||||
* RX module hops to next channel after frame has been received
|
||||
*/
|
||||
#ifdef DEVICE_MODE_RX
|
||||
radioNode.hopFrequency(true, radioState->lastReceivedChannel, millis());
|
||||
radioState->failedDwellsCount = 0; // We received a frame, so we can just reset this counter
|
||||
radioNode.hopFrequency(true, radioNode.lastReceivedChannel, millis());
|
||||
radioNode.failedDwellsCount = 0; // We received a frame, so we can just reset this counter
|
||||
LoRa.receive(); //Put radio back into receive mode
|
||||
#endif
|
||||
|
||||
@@ -142,7 +144,7 @@ void onQspSuccess(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDev
|
||||
qsp->transmitWindowOpen = true;
|
||||
}
|
||||
|
||||
void onQspFailure(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDeviceState_t *rxDeviceState, volatile RadioState_t *radioState) {
|
||||
void onQspFailure(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDeviceState_t *rxDeviceState) {
|
||||
|
||||
}
|
||||
|
||||
@@ -346,20 +348,7 @@ void loop(void)
|
||||
* This routine handles resync of TX/RX while hoppping frequencies
|
||||
*/
|
||||
#ifdef DEVICE_MODE_RX
|
||||
|
||||
//In the beginning just keep jumping forward and try to resync over lost single frames
|
||||
if (radioState.failedDwellsCount < 6 && radioNode.getChannelEntryMillis() + RX_CHANNEL_DWELL_TIME < currentMillis) {
|
||||
radioState.failedDwellsCount++;
|
||||
radioNode.hopFrequency(true, radioNode.getChannel(), radioNode.getChannelEntryMillis() + RX_CHANNEL_DWELL_TIME);
|
||||
LoRa.receive();
|
||||
}
|
||||
|
||||
// If we are loosing more frames, start jumping in the opposite direction since probably we are completely out of sync now
|
||||
if (radioState.failedDwellsCount >= 6 && radioNode.getChannelEntryMillis() + (RX_CHANNEL_DWELL_TIME * 5) < currentMillis) {
|
||||
radioNode.hopFrequency(false, radioNode.getChannel(), radioNode.getChannelEntryMillis() + RX_CHANNEL_DWELL_TIME); //Start jumping in opposite direction to resync
|
||||
LoRa.receive();
|
||||
}
|
||||
|
||||
radioNode.handleChannelDwell();
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -456,7 +445,7 @@ void loop(void)
|
||||
lastRxStateTaskTime = currentMillis;
|
||||
updateRxDeviceState(&rxDeviceState);
|
||||
|
||||
uint8_t output = constrain(radioState.rssi - 40, 0, 100);
|
||||
uint8_t output = constrain(radioNode.rssi - 40, 0, 100);
|
||||
|
||||
rxDeviceState.indicatedRssi = (output * 10) + 1000;
|
||||
if (qsp.deviceState == DEVICE_STATE_FAILSAFE) {
|
||||
@@ -487,7 +476,7 @@ void loop(void)
|
||||
break;
|
||||
|
||||
case QSP_FRAME_RX_HEALTH:
|
||||
encodeRxHealthPayload(&qsp, &rxDeviceState, &radioState);
|
||||
encodeRxHealthPayload(&qsp, &rxDeviceState, radioNode.rssi, radioNode.snr);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -507,7 +496,7 @@ void loop(void)
|
||||
if (qsp.lastFrameReceivedAt[QSP_FRAME_RC_DATA] + RX_FAILSAFE_DELAY < currentMillis) {
|
||||
qsp.deviceState = DEVICE_STATE_FAILSAFE;
|
||||
rxDeviceState.indicatedRssi = 0;
|
||||
radioState.rssi = 0;
|
||||
radioNode.rssi = 0;
|
||||
} else {
|
||||
qsp.deviceState = DEVICE_STATE_OK;
|
||||
}
|
||||
@@ -569,9 +558,9 @@ void loop(void)
|
||||
} else if (txDeviceState.isReceiving && (rxDeviceState.flags & 0x1) == 1) {
|
||||
//Failsafe reported by RX module
|
||||
buzzerContinousMode(BUZZER_MODE_SLOW_BEEP, &buzzer);
|
||||
} else if (txDeviceState.isReceiving && radioState.rssi < 45) {
|
||||
} else if (txDeviceState.isReceiving && radioNode.rssi < 45) {
|
||||
buzzerContinousMode(BUZZER_MODE_DOUBLE_CHIRP, &buzzer); // RSSI below 45dB // Critical state
|
||||
} else if (txDeviceState.isReceiving && radioState.rssi < 55) {
|
||||
} else if (txDeviceState.isReceiving && radioNode.rssi < 55) {
|
||||
buzzerContinousMode(BUZZER_MODE_CHIRP, &buzzer); // RSSI below 55dB // Warning state
|
||||
} else {
|
||||
buzzerContinousMode(BUZZER_MODE_OFF, &buzzer);
|
||||
|
||||
@@ -62,9 +62,9 @@ void qspComputeCrc(QspConfiguration_t *qsp, uint8_t dataByte)
|
||||
qsp->crc = crc8_dvb_s2(qsp->crc, dataByte);
|
||||
}
|
||||
|
||||
void encodeRxHealthPayload(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceState, volatile RadioState_t *radioState) {
|
||||
qsp->payload[0] = radioState->rssi;
|
||||
qsp->payload[1] = radioState->snr;
|
||||
void encodeRxHealthPayload(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceState, uint8_t rssi, uint8_t snr) {
|
||||
qsp->payload[0] = rssi;
|
||||
qsp->payload[1] = snr;
|
||||
qsp->payload[2] = rxDeviceState->rxVoltage;
|
||||
qsp->payload[3] = rxDeviceState->a1Voltage;
|
||||
qsp->payload[4] = rxDeviceState->a2Voltage;
|
||||
@@ -165,8 +165,7 @@ void qspDecodeIncomingFrame(
|
||||
QspConfiguration_t *qsp,
|
||||
uint8_t incomingByte,
|
||||
RxDeviceState_t *rxDeviceState,
|
||||
TxDeviceState_t *txDeviceState,
|
||||
volatile RadioState_t *radioState
|
||||
TxDeviceState_t *txDeviceState
|
||||
) {
|
||||
static uint8_t frameId;
|
||||
static uint8_t payloadLength;
|
||||
@@ -210,10 +209,9 @@ void qspDecodeIncomingFrame(
|
||||
{
|
||||
if (qsp->crc == incomingByte) {
|
||||
//CRC is correct
|
||||
radioState->lastReceivedChannel = receivedChannel;
|
||||
qsp->onSuccessCallback(qsp, txDeviceState, rxDeviceState, radioState);
|
||||
qsp->onSuccessCallback(qsp, txDeviceState, rxDeviceState, receivedChannel);
|
||||
} else {
|
||||
qsp->onFailureCallback(qsp, txDeviceState, rxDeviceState, radioState);
|
||||
qsp->onFailureCallback(qsp, txDeviceState, rxDeviceState);
|
||||
}
|
||||
|
||||
// In both cases switch to listening for next preamble
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Arduino.h"
|
||||
#include "variables.h"
|
||||
#include "radio_node.h"
|
||||
|
||||
void qspDecodeRcDataFrame(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceSate);
|
||||
void decodeRxHealthPayload(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceState);
|
||||
@@ -7,14 +8,13 @@ void decodeRxHealthPayload(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceSta
|
||||
uint8_t get10bitHighShift(uint8_t channel);
|
||||
uint8_t get10bitLowShift(uint8_t channel);
|
||||
void qspComputeCrc(QspConfiguration_t *qsp, uint8_t dataByte);
|
||||
void encodeRxHealthPayload(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceState, volatile RadioState_t *radioState);
|
||||
void encodeRxHealthPayload(QspConfiguration_t *qsp, RxDeviceState_t *rxDeviceState, uint8_t rssi, uint8_t snr);
|
||||
void encodeRcDataPayload(QspConfiguration_t *qsp, volatile int16_t channels[], uint8_t noOfChannels);
|
||||
void qspDecodeIncomingFrame(
|
||||
QspConfiguration_t *qsp,
|
||||
uint8_t incomingByte,
|
||||
RxDeviceState_t *rxDeviceState,
|
||||
TxDeviceState_t *txDeviceState,
|
||||
volatile RadioState_t *radioState
|
||||
TxDeviceState_t *txDeviceState
|
||||
);
|
||||
void qspClearPayload(QspConfiguration_t *qsp);
|
||||
void qspEncodeFrame(QspConfiguration_t *qsp, volatile RadioState_t *radioState, uint8_t buffer[], uint8_t *size, uint8_t radioChannel);
|
||||
|
||||
@@ -5,14 +5,14 @@ RadioNode::RadioNode(void) {
|
||||
|
||||
}
|
||||
|
||||
static uint8_t RadioNode::getRadioRssi(void)
|
||||
void RadioNode::readRssi(void)
|
||||
{
|
||||
return 164 - constrain(LoRa.packetRssi() * -1, 0, 164);
|
||||
rssi = 164 - constrain(LoRa.packetRssi() * -1, 0, 164);
|
||||
}
|
||||
|
||||
static uint8_t RadioNode::getRadioSnr(void)
|
||||
void RadioNode::readSnr(void)
|
||||
{
|
||||
return (uint8_t) constrain(LoRa.packetSnr(), 0, 255);
|
||||
snr = (uint8_t) constrain(LoRa.packetSnr(), 0, 255);
|
||||
}
|
||||
|
||||
uint8_t RadioNode::getChannel(void) {
|
||||
@@ -49,7 +49,7 @@ void RadioNode::readAndDecode(
|
||||
LoRa.read(tmpBuffer, bytesToRead);
|
||||
|
||||
for (int i = 0; i < bytesToRead; i++) {
|
||||
qspDecodeIncomingFrame(qsp, tmpBuffer[i], rxDeviceState, txDeviceState, radioState);
|
||||
qspDecodeIncomingFrame(qsp, tmpBuffer[i], rxDeviceState, txDeviceState);
|
||||
}
|
||||
|
||||
//After reading, flush radio buffer, we have no need for whatever might be over there
|
||||
@@ -77,3 +77,18 @@ void RadioNode::hopFrequency(bool forward, uint8_t fromChannel, uint32_t timesta
|
||||
);
|
||||
LoRa.idle();
|
||||
}
|
||||
|
||||
void RadioNode::handleChannelDwell(void) {
|
||||
//In the beginning just keep jumping forward and try to resync over lost single frames
|
||||
if (failedDwellsCount < 6 && getChannelEntryMillis() + RX_CHANNEL_DWELL_TIME < millis()) {
|
||||
failedDwellsCount++;
|
||||
hopFrequency(true, getChannel(), getChannelEntryMillis() + RX_CHANNEL_DWELL_TIME);
|
||||
LoRa.receive();
|
||||
}
|
||||
|
||||
// If we are loosing more frames, start jumping in the opposite direction since probably we are completely out of sync now
|
||||
if (failedDwellsCount >= 6 && getChannelEntryMillis() + (RX_CHANNEL_DWELL_TIME * 5) < millis()) {
|
||||
hopFrequency(false, getChannel(), getChannelEntryMillis() + RX_CHANNEL_DWELL_TIME); //Start jumping in opposite direction to resync
|
||||
LoRa.receive();
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@
|
||||
class RadioNode {
|
||||
public:
|
||||
RadioNode(void);
|
||||
static uint8_t getRadioRssi(void);
|
||||
static uint8_t getRadioSnr(void);
|
||||
void readRssi(void);
|
||||
void readSnr(void);
|
||||
static uint32_t getFrequencyForChannel(uint8_t channel);
|
||||
static uint8_t getNextChannel(uint8_t channel);
|
||||
static uint8_t getPrevChannel(uint8_t channel);
|
||||
@@ -32,8 +32,13 @@ class RadioNode {
|
||||
);
|
||||
uint8_t getChannel(void);
|
||||
uint32_t getChannelEntryMillis(void);
|
||||
void handleChannelDwell(void);
|
||||
int8_t bytesToRead = -1;
|
||||
uint8_t deviceState = RADIO_STATE_RX;
|
||||
uint8_t rssi = 0;
|
||||
uint8_t snr = 0;
|
||||
uint8_t lastReceivedChannel = 0;
|
||||
uint8_t failedDwellsCount = 0;
|
||||
private:
|
||||
uint8_t _channel = 0;
|
||||
uint32_t _channelEntryMillis = 0;
|
||||
|
||||
@@ -151,11 +151,11 @@ void TxOled::renderPageStats(
|
||||
|
||||
_display.setCursor(0, 0);
|
||||
_display.setTextSize(3);
|
||||
_display.print(radioState->rssi);
|
||||
_display.print(radioNode.rssi);
|
||||
|
||||
_display.setCursor(18, 28);
|
||||
_display.setTextSize(2);
|
||||
_display.print(radioState->snr);
|
||||
_display.print(radioNode.snr);
|
||||
|
||||
_display.setCursor(74, 0);
|
||||
_display.setTextSize(3);
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "Wire.h"
|
||||
#include "variables.h"
|
||||
#include "tactile.h"
|
||||
#include "radio_node.h"
|
||||
|
||||
extern volatile RadioNode radioNode;
|
||||
|
||||
enum txOledPages {
|
||||
TX_PAGE_NONE,
|
||||
|
||||
@@ -95,13 +95,7 @@ struct RadioState_t {
|
||||
uint8_t loraSpreadingFactor = 7;
|
||||
uint8_t loraCodingRate = 6;
|
||||
uint8_t loraTxPower = 17; // Defines output power of TX, defined in dBm range from 2-17
|
||||
uint8_t rssi = 0;
|
||||
uint8_t snr = 0;
|
||||
uint32_t nextTxCheckMillis = 0;
|
||||
|
||||
const uint32_t dwellTime = TX_TRANSMIT_SLOT_RATE * 2;
|
||||
uint8_t lastReceivedChannel = 0;
|
||||
uint8_t failedDwellsCount = 0;
|
||||
};
|
||||
|
||||
struct TxDeviceState_t {
|
||||
@@ -133,8 +127,8 @@ struct QspConfiguration_t {
|
||||
uint32_t lastFrameReceivedAt[QSP_FRAME_COUNT] = {0};
|
||||
uint32_t anyFrameRecivedAt = 0;
|
||||
uint8_t deviceState = DEVICE_STATE_UNDETERMINED;
|
||||
void (* onSuccessCallback)(QspConfiguration_t*, TxDeviceState_t*, RxDeviceState_t*, volatile RadioState_t*);
|
||||
void (* onFailureCallback)(QspConfiguration_t*, TxDeviceState_t*, RxDeviceState_t*, volatile RadioState_t*);
|
||||
void (* onSuccessCallback)(QspConfiguration_t*, TxDeviceState_t*, RxDeviceState_t*, uint8_t receivedChannel);
|
||||
void (* onFailureCallback)(QspConfiguration_t*, TxDeviceState_t*, RxDeviceState_t*);
|
||||
bool canTransmit = false;
|
||||
bool forcePongFrame = false;
|
||||
uint8_t debugConfig = 0;
|
||||
|
||||
Reference in New Issue
Block a user