Slots for transmitting on RX side close #8
This commit is contained in:
@@ -25,8 +25,8 @@ Development, not yet functional
|
|||||||
| 0010 | 0x2 | Request receiver configuration | TX -> RX |
|
| 0010 | 0x2 | Request receiver configuration | TX -> RX |
|
||||||
| 0011 | 0x3 | Receiver configuration | RX -> TX |
|
| 0011 | 0x3 | Receiver configuration | RX -> TX |
|
||||||
| 0100 | 0x4 | Set receiver configuration | TX -> RX |
|
| 0100 | 0x4 | Set receiver configuration | TX -> RX |
|
||||||
| 0101 | 0x5 | PING frame | TX -> RX |
|
| 0101 | 0x5 | PING frame, uses 9 byte payload | TX -> RX |
|
||||||
| 0110 | 0x6 | PONG frame | RX -> TX |
|
| 0110 | 0x6 | PONG frame, the same payload as PING | RX -> TX |
|
||||||
|
|
||||||
### `RC_DATA` frame format
|
### `RC_DATA` frame format
|
||||||
|
|
||||||
|
|||||||
149
crossbow.ino
149
crossbow.ino
@@ -1,11 +1,11 @@
|
|||||||
#define LORA_HARDWARE_SPI
|
#define LORA_HARDWARE_SPI
|
||||||
|
|
||||||
#define DEVICE_MODE_TX
|
// #define DEVICE_MODE_TX
|
||||||
// #define DEVICE_MODE_RX
|
#define DEVICE_MODE_RX
|
||||||
|
|
||||||
#define FEATURE_TX_OLED
|
#define FEATURE_TX_OLED
|
||||||
|
|
||||||
#define DEBUG_SERIAL
|
// #define DEBUG_SERIAL
|
||||||
// #define DEBUG_PING_PONG
|
// #define DEBUG_PING_PONG
|
||||||
// #define DEBUG_LED
|
// #define DEBUG_LED
|
||||||
// #define WAIT_FOR_SERIAL
|
// #define WAIT_FOR_SERIAL
|
||||||
@@ -63,7 +63,7 @@ uint8_t getRadioRssi(void)
|
|||||||
return map(constrain(LoRa.packetRssi() * -1, 0, 164), 0, 164, 255, 0);
|
return map(constrain(LoRa.packetRssi() * -1, 0, 164), 0, 164, 255, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getRadioSnr(void)
|
uint8_t getRadioSnr(void)
|
||||||
{
|
{
|
||||||
return (uint8_t) constrain(LoRa.packetSnr(), 0, 255);
|
return (uint8_t) constrain(LoRa.packetSnr(), 0, 255);
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ int8_t rxSendSequence[16] = {
|
|||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
QSP_FRAME_RX_HEALTH,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
@@ -217,7 +217,7 @@ int8_t rxSendSequence[16] = {
|
|||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
QSP_FRAME_RX_HEALTH,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1
|
-1
|
||||||
@@ -236,7 +236,13 @@ void updateRxDeviceState(RxDeviceState_t *rxDeviceState) {
|
|||||||
rxDeviceState->snr = getRadioSnr();
|
rxDeviceState->snr = getRadioSnr();
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t getFrameToTransmit() {
|
int8_t getFrameToTransmit(QspConfiguration_t *qsp) {
|
||||||
|
|
||||||
|
if (qsp->forcePongFrame) {
|
||||||
|
qsp->forcePongFrame = false;
|
||||||
|
return QSP_FRAME_PONG;
|
||||||
|
}
|
||||||
|
|
||||||
int8_t retVal = rxSendSequence[currentSequenceIndex];
|
int8_t retVal = rxSendSequence[currentSequenceIndex];
|
||||||
|
|
||||||
currentSequenceIndex++;
|
currentSequenceIndex++;
|
||||||
@@ -250,7 +256,7 @@ int8_t getFrameToTransmit() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEVICE_MODE_TX
|
#ifdef DEVICE_MODE_TX
|
||||||
int8_t getFrameToTransmit() {
|
int8_t getFrameToTransmit(QspConfiguration_t *qsp) {
|
||||||
int8_t retVal = txSendSequence[currentSequenceIndex];
|
int8_t retVal = txSendSequence[currentSequenceIndex];
|
||||||
|
|
||||||
currentSequenceIndex++;
|
currentSequenceIndex++;
|
||||||
@@ -284,7 +290,7 @@ void loop(void)
|
|||||||
qsp.protocolState == QSP_STATE_IDLE
|
qsp.protocolState == QSP_STATE_IDLE
|
||||||
) {
|
) {
|
||||||
|
|
||||||
int8_t frameToSend = getFrameToTransmit();
|
int8_t frameToSend = getFrameToTransmit(&qsp);
|
||||||
|
|
||||||
if (frameToSend == QSP_FRAME_RC_DATA && !ppmReader.isReceiving()) {
|
if (frameToSend == QSP_FRAME_RC_DATA && !ppmReader.isReceiving()) {
|
||||||
frameToSend = -1;
|
frameToSend = -1;
|
||||||
@@ -313,17 +319,70 @@ void loop(void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if (
|
#ifdef DEVICE_MODE_RX
|
||||||
// qsp.forcePongFrame &&
|
|
||||||
// !transmitPayload &&
|
|
||||||
// qsp.protocolState == QSP_STATE_IDLE
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// qsp.forcePongFrame = false;
|
|
||||||
// qsp.frameToSend = QSP_FRAME_PONG;
|
|
||||||
// transmitPayload = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine updates RX device state and updates one of radio channels with RSSI value
|
||||||
|
*/
|
||||||
|
if (abs(currentMillis - lastRxStateTaskTime) > RX_TASK_HEALTH) {
|
||||||
|
lastRxStateTaskTime = currentMillis;
|
||||||
|
updateRxDeviceState(&rxDeviceState);
|
||||||
|
ppm[RSSI_CHANNEL - 1] = map(rxDeviceState.rssi, 0, 255, 1000, 2000);
|
||||||
|
|
||||||
|
if (qsp.deviceState == DEVICE_STATE_FAILSAFE) {
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
} else {
|
||||||
|
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main routine to answer to TX module
|
||||||
|
*/
|
||||||
|
if (qsp.transmitWindowOpen && qsp.protocolState == QSP_STATE_IDLE) {
|
||||||
|
|
||||||
|
qsp.transmitWindowOpen = false;
|
||||||
|
|
||||||
|
int8_t frameToSend = getFrameToTransmit(&qsp);
|
||||||
|
|
||||||
|
if (frameToSend > -1) {
|
||||||
|
|
||||||
|
qsp.frameToSend = frameToSend;
|
||||||
|
|
||||||
|
if (frameToSend != QSP_FRAME_PONG) {
|
||||||
|
qspClearPayload(&qsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (qsp.frameToSend) {
|
||||||
|
case QSP_FRAME_PONG:
|
||||||
|
/*
|
||||||
|
* Pong frame just responses with received payload
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSP_FRAME_RX_HEALTH:
|
||||||
|
encodeRxHealthPayload(&qsp, &rxDeviceState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
transmitPayload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentMillis > sbusTime) {
|
||||||
|
sbusPreparePacket(sbusPacket, ppm, false, (qsp.deviceState == DEVICE_STATE_FAILSAFE));
|
||||||
|
Serial1.write(sbusPacket, SBUS_PACKET_LENGTH);
|
||||||
|
sbusTime = currentMillis + SBUS_UPDATE_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(currentMillis - qsp.lastFrameReceivedAt[QSP_FRAME_RC_DATA]) > RX_FAILSAFE_DELAY) {
|
||||||
|
qsp.deviceState = DEVICE_STATE_FAILSAFE;
|
||||||
|
} else {
|
||||||
|
qsp.deviceState = DEVICE_STATE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEVICE_MODE_TX
|
#ifdef DEVICE_MODE_TX
|
||||||
|
|
||||||
@@ -363,48 +422,6 @@ void loop(void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #ifdef DEVICE_MODE_RX
|
|
||||||
|
|
||||||
// if (currentMillis > sbusTime) {
|
|
||||||
// sbusPreparePacket(sbusPacket, ppm, false, (qsp.deviceState == DEVICE_STATE_FAILSAFE));
|
|
||||||
// Serial1.write(sbusPacket, SBUS_PACKET_LENGTH);
|
|
||||||
|
|
||||||
// sbusTime = currentMillis + SBUS_UPDATE_RATE;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// * This routine updates RX device state and updates one of radio channels with RSSI value
|
|
||||||
// */
|
|
||||||
// if (currentMillis - lastRxStateTaskTime > RX_TASK_HEALTH) {
|
|
||||||
// lastRxStateTaskTime = currentMillis;
|
|
||||||
// updateRxDeviceState(&rxDeviceState);
|
|
||||||
// ppm[RSSI_CHANNEL - 1] = map(rxDeviceState.rssi, 0, 255, 1000, 2000);
|
|
||||||
|
|
||||||
// if (qsp.deviceState == DEVICE_STATE_FAILSAFE) {
|
|
||||||
// digitalWrite(LED_BUILTIN, HIGH);
|
|
||||||
// } else {
|
|
||||||
// digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// * RX_HEALTH QSP frame
|
|
||||||
// */
|
|
||||||
// if (
|
|
||||||
// currentMillis - qsp.lastFrameTransmitedAt[QSP_FRAME_RX_HEALTH] > RX_RX_HEALTH_FRAME_RATE &&
|
|
||||||
// !transmitPayload &&
|
|
||||||
// qsp.protocolState == QSP_STATE_IDLE
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// qspClearPayload(&qsp);
|
|
||||||
// encodeRxHealthPayload(&qsp, &rxDeviceState);
|
|
||||||
// qsp.frameToSend = QSP_FRAME_RX_HEALTH;
|
|
||||||
|
|
||||||
// transmitPayload = true;
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
if (qsp.canTransmit && transmitPayload)
|
if (qsp.canTransmit && transmitPayload)
|
||||||
{
|
{
|
||||||
radioPacketStart();
|
radioPacketStart();
|
||||||
@@ -413,16 +430,6 @@ void loop(void)
|
|||||||
transmitPayload = false;
|
transmitPayload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Here we do state handling and similar operations
|
|
||||||
*/
|
|
||||||
#ifdef DEVICE_MODE_RX
|
|
||||||
if (abs(currentMillis - qsp.lastFrameReceivedAt[QSP_FRAME_RC_DATA]) > RX_FAILSAFE_DELAY) {
|
|
||||||
qsp.deviceState = DEVICE_STATE_FAILSAFE;
|
|
||||||
} else {
|
|
||||||
qsp.deviceState = DEVICE_STATE_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LORA_HARDWARE_SPI
|
#ifdef LORA_HARDWARE_SPI
|
||||||
|
|||||||
21
qsp.cpp
21
qsp.cpp
@@ -204,19 +204,6 @@ void qspDecodeIncomingFrame(QspConfiguration_t *qsp, uint8_t incomingByte, int p
|
|||||||
qsp->lastFrameReceivedAt[frameId] = millis();
|
qsp->lastFrameReceivedAt[frameId] = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qsp->debugConfig & DEBUG_FLAG_SERIAL) {
|
|
||||||
Serial.print("Frame ");
|
|
||||||
Serial.print(frameId);
|
|
||||||
Serial.println(" received");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qsp->debugConfig & DEBUG_FLAG_LED) {
|
|
||||||
digitalWrite(LED_BUILTIN, HIGH);
|
|
||||||
delay(10);
|
|
||||||
digitalWrite(LED_BUILTIN, LOW);
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (frameId) {
|
switch (frameId) {
|
||||||
case QSP_FRAME_RC_DATA:
|
case QSP_FRAME_RC_DATA:
|
||||||
qspDecodeRcDataFrame(qsp, ppm);
|
qspDecodeRcDataFrame(qsp, ppm);
|
||||||
@@ -224,12 +211,6 @@ void qspDecodeIncomingFrame(QspConfiguration_t *qsp, uint8_t incomingByte, int p
|
|||||||
|
|
||||||
case QSP_FRAME_RX_HEALTH:
|
case QSP_FRAME_RX_HEALTH:
|
||||||
decodeRxHealthPayload(qsp, rxDeviceState);
|
decodeRxHealthPayload(qsp, rxDeviceState);
|
||||||
if (qsp->debugConfig & DEBUG_FLAG_SERIAL) {
|
|
||||||
Serial.print("RX RSSI: ");
|
|
||||||
Serial.println(rxDeviceState->rssi);
|
|
||||||
Serial.print("RX SNR: ");
|
|
||||||
Serial.println(rxDeviceState->snr);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSP_FRAME_PING:
|
case QSP_FRAME_PING:
|
||||||
@@ -251,6 +232,8 @@ void qspDecodeIncomingFrame(QspConfiguration_t *qsp, uint8_t incomingByte, int p
|
|||||||
//TODO do something in this case
|
//TODO do something in this case
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qsp->transmitWindowOpen = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,12 +11,9 @@
|
|||||||
#define RX_TASK_HEALTH 200 //5Hz should be enough
|
#define RX_TASK_HEALTH 200 //5Hz should be enough
|
||||||
#define RSSI_CHANNEL 11
|
#define RSSI_CHANNEL 11
|
||||||
|
|
||||||
#define RX_RX_HEALTH_FRAME_RATE 503
|
|
||||||
#define TX_TRANSMIT_SLOT_RATE 57 //ms
|
#define TX_TRANSMIT_SLOT_RATE 57 //ms
|
||||||
#define RX_FAILSAFE_DELAY (TX_TRANSMIT_SLOT_RATE * 8)
|
#define RX_FAILSAFE_DELAY (TX_TRANSMIT_SLOT_RATE * 8)
|
||||||
|
|
||||||
#define TX_PING_RATE 2007
|
|
||||||
|
|
||||||
#define CHANNEL_ID 0x01
|
#define CHANNEL_ID 0x01
|
||||||
#define QSP_PREAMBLE 0x51
|
#define QSP_PREAMBLE 0x51
|
||||||
#define QSP_PAYLOAD_LENGTH 32
|
#define QSP_PAYLOAD_LENGTH 32
|
||||||
@@ -82,6 +79,7 @@ struct QspConfiguration_t {
|
|||||||
uint8_t debugConfig = 0;
|
uint8_t debugConfig = 0;
|
||||||
uint32_t frameDecodingStartedAt = 0;
|
uint32_t frameDecodingStartedAt = 0;
|
||||||
uint32_t lastTxSlotTimestamp = 0;
|
uint32_t lastTxSlotTimestamp = 0;
|
||||||
|
bool transmitWindowOpen = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RxDeviceState_t {
|
struct RxDeviceState_t {
|
||||||
|
|||||||
Reference in New Issue
Block a user