diff --git a/README.md b/README.md index ed08d5a..e101224 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ Development, not yet functional | 0010 | 0x2 | Request receiver configuration | TX -> RX | | 0011 | 0x3 | Receiver configuration | RX -> TX | | 0100 | 0x4 | Set receiver configuration | TX -> RX | +| 0101 | 0x5 | PING frame | TX -> RX | +| 0110 | 0x6 | PONG frame | RX -> TX | ### `RC_DATA` frame format @@ -47,3 +49,9 @@ Total length of `RC_DATA` payload is 9 bytes | 4 | RX analog input 1 sent in 0,1V | | 5 | RX analog input 2 sent in 0,1V | | 6 | Last received packet ID | + +### `PING` and `PONG` frames + +`PING` and `PONG` frames are to determine packet roundrip between **TX** and **RX** module. +**TX** sends `PING` frame with curent `micros`. If **RX** receives `PING` frame, it respons +its payload as `PONG` frame. \ No newline at end of file diff --git a/crossbow.ino b/crossbow.ino index 20d6911..83da749 100644 --- a/crossbow.ino +++ b/crossbow.ino @@ -5,7 +5,7 @@ // #define DEVICE_MODE_RX #define DEBUG_SERIAL -#define DEBUG_LED +// #define DEBUG_LED // #define WAIT_FOR_SERIAL #include @@ -171,13 +171,18 @@ void setup(void) Serial.println("Pins Set"); #endif -if (!LoRa.begin(868E6)) + if (!LoRa.begin(868E6)) { #ifdef DEBUG_SERIAL Serial.println("LoRa init failed. Check your connections."); #endif while (true); } + + LoRa.setSignalBandwidth(250E3); + LoRa.setSpreadingFactor(7); + LoRa.setCodingRate4(5); + #ifdef DEBUG_SERIAL Serial.println("Init done"); #endif @@ -302,7 +307,37 @@ void loop(void) uint32_t currentMillis = millis(); bool transmitPayload = false; + if ( + qsp.forcePongFrame && + !transmitPayload && + qsp.protocolState == QSP_STATE_IDLE + ) + { + qsp.forcePongFrame = false; + qsp.lastFrameTransmitedAt[QSP_FRAME_PONG] = currentMillis; + qsp.frameToSend = QSP_FRAME_PONG; + transmitPayload = true; + } + + #ifdef DEVICE_MODE_TX + + //PING frame + if ( + currentMillis - qsp.lastFrameTransmitedAt[QSP_FRAME_PING] > TX_PING_RATE && + !transmitPayload && + qsp.protocolState == QSP_STATE_IDLE + ) + { + qsp.lastFrameTransmitedAt[QSP_FRAME_PING] = currentMillis; + + qspClearPayload(&qsp); + encodePingPayload(&qsp, micros()); + qsp.frameToSend = QSP_FRAME_PING; + + transmitPayload = true; + } + /* * RC_DATA QSP frame */ @@ -355,14 +390,12 @@ void loop(void) if (qsp.canTransmit && transmitPayload) { - transmitPayload = false; - radioPacketStart(); qspEncodeFrame(&qsp); radioPacketEnd(); #ifdef DEBUG_SERIAL - Serial.print("Packet frame "); + Serial.print("Frame "); Serial.print(qsp.frameToSend); Serial.println(" sent"); #endif @@ -376,6 +409,7 @@ void loop(void) delay(10); digitalWrite(LED_BUILTIN, LOW); #endif + transmitPayload = false; } /* diff --git a/qsp.cpp b/qsp.cpp index 3145d8b..9a0590d 100644 --- a/qsp.cpp +++ b/qsp.cpp @@ -248,6 +248,25 @@ void qspDecodeIncomingFrame(QspConfiguration_t *qsp, uint8_t incomingByte, int p } break; + case QSP_FRAME_PING: + qsp->forcePongFrame = true; + break; + + case QSP_FRAME_PONG: + if (qsp->debugConfig & DEBUG_FLAG_SERIAL) { + + uint32_t incoming = 0; + + incoming = qsp->payload[0]; + incoming += (uint32_t) qsp->payload[1] << 8; + incoming += (uint32_t) qsp->payload[2] << 16; + incoming += (uint32_t) qsp->payload[3] << 24; + + Serial.print("Rountrip: "); + Serial.println((micros() - incoming) / 1000); + } + break; + default: //Unknown frame //TODO do something in this case @@ -293,4 +312,13 @@ void qspEncodeFrame(QspConfiguration_t *qsp) { //Finally write CRC qsp->hardwareWriteFunction(qsp->crc, qsp); +} + +void encodePingPayload(QspConfiguration_t *qsp, uint32_t currentMicros) { + qsp->payload[0] = currentMicros & 255; + qsp->payload[1] = (currentMicros >> 8) & 255; + qsp->payload[2] = (currentMicros >> 16) & 255; + qsp->payload[3] = (currentMicros >> 24) & 255; + + qsp->payloadLength = 9; } \ No newline at end of file diff --git a/qsp.h b/qsp.h index 8dd171f..aa60e94 100644 --- a/qsp.h +++ b/qsp.h @@ -12,4 +12,6 @@ void encodeRcDataPayload(QspConfiguration_t *qsp, PPMReader *ppmSource, uint8_t uint8_t qspGetPacketId(void); void qspDecodeIncomingFrame(QspConfiguration_t *qsp, uint8_t incomingByte, int ppm[], RxDeviceState_t *rxDeviceState); void qspClearPayload(QspConfiguration_t *qsp); -void qspEncodeFrame(QspConfiguration_t *qsp); \ No newline at end of file +void qspEncodeFrame(QspConfiguration_t *qsp); + +void encodePingPayload(QspConfiguration_t *qsp, uint32_t currentMicros); \ No newline at end of file diff --git a/variables.h b/variables.h index afcaa84..091c6b2 100644 --- a/variables.h +++ b/variables.h @@ -10,6 +10,8 @@ #define TX_RC_FRAME_RATE 1000 //ms #define RX_FAILSAFE_DELAY (TX_RC_FRAME_RATE * 4) +#define TX_PING_RATE 2000 + #define CHANNEL_ID 0x01 #define QSP_PREAMBLE 0x51 #define QSP_PAYLOAD_LENGTH 32 @@ -19,7 +21,9 @@ #define QSP_FRAME_GET_RX_CONFIG 0x2 #define QSP_FRAME_RX_CONFIG 0x3 #define QSP_FRAME_SET_RX_CONFIG 0x4 -#define QSP_FRAME_COUNT 0x5 +#define QSP_FRAME_PING 0x5 +#define QSP_FRAME_PONG 0x6 +#define QSP_FRAME_COUNT 0x7 #define RX_ADC_PIN_1 A0 #define RX_ADC_PIN_2 A1 @@ -66,6 +70,7 @@ struct QspConfiguration_t { void (* hardwareWriteFunction)(uint8_t, QspConfiguration_t*); uint8_t lastReceivedPacketId = 0; bool canTransmit = false; + bool forcePongFrame = false; uint8_t debugConfig = 0; };