From 544a29f705e7d4d3f8e66c8e8b05a481f56658b2 Mon Sep 17 00:00:00 2001 From: jakeg00dwin Date: Fri, 27 Sep 2024 16:21:55 -0700 Subject: [PATCH] Added code tested with radio modules. --- src/main.cpp | 211 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 141 insertions(+), 70 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 40e67e1..e019636 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,97 +23,144 @@ TinyGPSPlus gps; // TinyGPS++ object to process GPS data RH_RF95 rf95(RFM9X_CS, RMF9X_INT); // Radio instance. -typedef struct Msg{ - uint8_t id; - double latitude; - double longitude; - uint8_t crc; -}Msg; - - // Variables static int prevHeading = -1; // Store previous heading to avoid frequent updates unsigned long lastUpdate = 0; // Time tracking for updates const int updateInterval = 500; // Update interval in milliseconds (500ms = 0.5s) -NodeId node = { - id = 0; - name = "name"; + +typedef struct MSG{ + uint8_t id; + double latitude; + double longitude; +}MSG; + + +enum result { + Ok = 0, + Err, + ReceiveFailed, + NoReply, }; -uint8_t reciver_buffer[RF9X_BUF_SZ]; -void Radio_setup(void) { - pinMode(RFM9X_RST, OUTPUT); - digitalWrite(RFM9X_RST, HIGH); +uint8_t db; //Used to hold the current setting for the TX power. +uint8_t buffer[sizeof(MSG)]; - while(!rf95.init()){} - Serial.println("radio: Initialized"); - - if(rf95.setFrequency(RF9X_FREQ)) { - Serial.println("radio: Error could not set frequency"); - while(true){} //Loop forever - } - Serial.print("radio: Frequency = "); - Serial.println(RF9X_FREQ); +MSG msg_out; +msg_out.id = 0; //Put the system ID here - rf95.setTxPower(RF9X_MIN_DB, false); + +void MSG_Print(MSG *msg) { + Serial.print("ID: "); + Serial.println(msg->id); + + Serial.print("Latitude: "); + Serial.println(msg->latitude); + + Serial.print("Longitude: "); + Serial.println(msg->longitude); } - -void Radio_reset(void) { +void Radio_Reset(void) { digitalWrite(RFM9X_RST, LOW); delay(10); digitalWrite(RFM9X_RST, HIGH); delay(10); } +uint8_t Radio_Setup(void) { + Serial.println("Radio_Setup()"); -int Radio_SendData() { - int8_t tx_power = RF9X_MIN_DB; - uint8_t received_id = 0; + pinMode(RFM95_RST, OUTPUT); + digitalWrite(RFM95_RST, HIGH); - //Set the radio output to lowest power. - rf95.setTxPower(tx_power, false); + Radio_Reset(); - //Set the radio into TX mode. - rf95.setModeTx(); - - //Try transmitting data - Serial.println("Radio: Sending data..."); - rf95.send(node.id, 1); - rf95.waitPacketSent(); - - //Wait for ACK or Radio Msg. (Timeout Should be included). - //On timeout increase the transmit power and re-attempt. - if(!rf95.waitAvailbleTimeout(RF9X_TIMEOUT)) { - if(rf95.recv(reciver_buffer, RF9X_BUF_SZ)) { - - } - else { - //Failed to receive the message. - Serial.println("Radio: Error failed to receive msg."); - } - } - else { - //No reply of any kind. - Serial.println("Radio: Error no reply."); - } - - //Set the radio mode to idle. - rf95.setModeIdle(); + while (!rf95.init()) { + Serial.println("Radio_Setup(): Failed to initialize"); + Serial.println("Check SPI connections!"); + return Err; + } + Serial.println("LoRa radio init OK!"); + return Ok; } +uint8_t Radio_Configure(void) { + // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM + if(!rf95.setFrequency(RF95_FREQ)) { + Serial.println("Radio_Configure(): failed to set frequency"); + return Err; + } + Serial.print("Set Freq to: "); Serial.println(RF95_FREQ); + rf95.setTxPower(TX_POWER_LOW, false); -int Radio_ReceiveData() { - //Set radio into RX mode. - rf95.setModeRx(); + return Ok; +} - //Check if radio has traffic - if() +uint8_t Radio_SendMsg(MSG *msg) { + Serial.println("Radio_SendMsg()"); + Serial.println("Sending Message: "); + Serial.print("Message size: "); + Serial.println(sizeof(MSG)); + + MSG_Print(msg); + + rf95.send((uint8_t *)msg, sizeof(MSG)); + + Serial.println("waiting for packet sent..."); + delay(10); + rf95.waitPacketSent(); + + return Ok; +} + +uint8_t Radio_CheckForMsg(MSG *msg) { + Serial.println("Radio_CheckForMsg()"); + + //Now we wait for an packet. + if (rf95.waitAvailableTimeout(1000)) { + // Should be a reply message for us now + if (rf95.recv(buffer, sizeof(MSG))) { + Serial.print("Received reply: "); + + msg->id = (uint8_t) buffer[0]; + msg->latitude = *(double *) &buffer[1]; + msg->longitude = *(double *) &buffer[5]; + + MSG_Print(msg); + + Serial.print("RSSI: "); + Serial.println(rf95.lastRssi(), DEC); + } else { + Serial.println("Receive failed"); + return ReceiveFailed; + } + } else { + Serial.println("No reply"); + return NoReply; + } + return Ok; +} + +//The algo below allows us to minimize the needed TX power. +void Radio_Main(MSG *msg_out, MSG *msg_in) { + for(db = RF9X_MIN_DB; db <= RF9X_MAX_DB; db++) { + Radio_SendMsg(&msg_out); + if(Radio_CheckForMsg(&msg_in) == Ok) { + break; + } + else{ + Serial.print("TX Power set to:"); + Serial.println(db); + } + } + + //We "delay" for 1 seconds by calling the radio check twice. + if(Radio_CheckForMsg(&msg_in) == Ok) { + Radio_SendMsg(&msg_out); + } - //Set the radio mode to idle. - rf95.setModeIdle(); } @@ -136,6 +183,24 @@ void setup(void) { // GPS Setup gpsSerial.begin(GPS_BUADRATE); + + // Setup the Radio module. + + //Retry until sucsess. + for(uint8_t i = 0; i < RETRIES; i++) { + delay(100); + if(Radio_Setup() == Ok){ + break; + } + } + + //Retry configuration until success + for(uint8_t i = 0; i < RETRIES; i++) { + delay(100); + if(Radio_Configure() == Ok){ + break; + } + } } void loop() { @@ -145,12 +210,14 @@ void loop() { if (gpsSerial.available() > 0) { // Check if data is available from the GPS module gps.encode(gpsSerial.read()); // Decode the GPS data if (gps.location.isValid()) { // Check if GPS location data is valid - double latitude = gps.location.lat(); // Get latitude - double longitude = gps.location.lng(); // Get longitude + //double latitude = gps.location.lat(); // Get latitude + //double longitude = gps.location.lng(); // Get longitude + msg_out.latitude = gps.location.lat(); + msg_out.longitude = gps.location.lat(); Serial.print("Lat: "); // Output latitude for debugging - Serial.println(latitude, 6); // Print latitude with 6 decimal places + Serial.println(msg_out.latitude, 6); // Print latitude with 6 decimal places Serial.print("Lon: "); // Output longitude for debugging - Serial.println(longitude, 6); // Print longitude with 6 decimal places + Serial.println(msg_out.longitude, 6); // Print longitude with 6 decimal places } else { Serial.println("Waiting for valid GPS data..."); // GPS signal lost or invalid } @@ -176,6 +243,9 @@ void loop() { updateDisplay(); // Placeholder: Update the central TFT display with GPS data lastUpdate = currentTime; // Reset the last update time } + + //Handle the Radio data. + } // Function to update the LED ring based on heading direction @@ -219,7 +289,8 @@ void sendGPSData() { // - Get the current GPS coordinates // - Format the data for transmission // - Use the LoRa library to send the data to the paired device - // Example: LoRa.beginPacket(); LoRa.print(latitude); LoRa.print(longitude); LoRa.endPacket(); + // Example: LoRa.beginPacket(); LoRa.print(latitude); LoRa.print(longitude); LoRa.endPacket(); + } // Future function to receive GPS data from the other device via LoRa - See adafruit LORA code examples