This commit is contained in:
Pawel Spychalski
2018-05-16 13:07:12 +02:00
parent 3766948329
commit 0079264128
10 changed files with 63 additions and 57 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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,13 +49,13 @@ 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
LoRa.sleep();
LoRa.receive();
deviceState = RADIO_STATE_RX;
bytesToRead = NO_DATA_TO_READ;
}
@@ -76,4 +76,19 @@ void RadioNode::hopFrequency(bool forward, uint8_t fromChannel, uint32_t timesta
RadioNode::getFrequencyForChannel(_channel)
);
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();
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;