Added code tested with radio modules.

This commit is contained in:
jakeg00dwin 2024-09-27 16:21:55 -07:00
parent ac4666a633
commit 544a29f705
1 changed files with 141 additions and 70 deletions

View File

@ -23,97 +23,144 @@ TinyGPSPlus gps; // TinyGPS++ object to process GPS data
RH_RF95 rf95(RFM9X_CS, RMF9X_INT); // Radio instance. RH_RF95 rf95(RFM9X_CS, RMF9X_INT); // Radio instance.
typedef struct Msg{
uint8_t id;
double latitude;
double longitude;
uint8_t crc;
}Msg;
// Variables // Variables
static int prevHeading = -1; // Store previous heading to avoid frequent updates static int prevHeading = -1; // Store previous heading to avoid frequent updates
unsigned long lastUpdate = 0; // Time tracking for updates unsigned long lastUpdate = 0; // Time tracking for updates
const int updateInterval = 500; // Update interval in milliseconds (500ms = 0.5s) const int updateInterval = 500; // Update interval in milliseconds (500ms = 0.5s)
NodeId node = {
id = 0; typedef struct MSG{
name = "name"; 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) { uint8_t db; //Used to hold the current setting for the TX power.
pinMode(RFM9X_RST, OUTPUT); uint8_t buffer[sizeof(MSG)];
digitalWrite(RFM9X_RST, HIGH);
while(!rf95.init()){} MSG msg_out;
Serial.println("radio: Initialized"); msg_out.id = 0; //Put the system ID here
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);
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); digitalWrite(RFM9X_RST, LOW);
delay(10); delay(10);
digitalWrite(RFM9X_RST, HIGH); digitalWrite(RFM9X_RST, HIGH);
delay(10); delay(10);
} }
uint8_t Radio_Setup(void) {
Serial.println("Radio_Setup()");
int Radio_SendData() { pinMode(RFM95_RST, OUTPUT);
int8_t tx_power = RF9X_MIN_DB; digitalWrite(RFM95_RST, HIGH);
uint8_t received_id = 0;
//Set the radio output to lowest power. Radio_Reset();
rf95.setTxPower(tx_power, false);
//Set the radio into TX mode. while (!rf95.init()) {
rf95.setModeTx(); Serial.println("Radio_Setup(): Failed to initialize");
Serial.println("Check SPI connections!");
return Err;
}
Serial.println("LoRa radio init OK!");
return Ok;
}
//Try transmitting data uint8_t Radio_Configure(void) {
Serial.println("Radio: Sending data..."); // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
rf95.send(node.id, 1); 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);
return Ok;
}
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(); rf95.waitPacketSent();
//Wait for ACK or Radio Msg. (Timeout Should be included). return Ok;
//On timeout increase the transmit power and re-attempt. }
if(!rf95.waitAvailbleTimeout(RF9X_TIMEOUT)) {
if(rf95.recv(reciver_buffer, RF9X_BUF_SZ)) {
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{ else{
//Failed to receive the message. Serial.print("TX Power set to:");
Serial.println("Radio: Error failed to receive msg."); Serial.println(db);
} }
} }
else {
//No reply of any kind. //We "delay" for 1 seconds by calling the radio check twice.
Serial.println("Radio: Error no reply."); if(Radio_CheckForMsg(&msg_in) == Ok) {
Radio_SendMsg(&msg_out);
} }
//Set the radio mode to idle.
rf95.setModeIdle();
}
int Radio_ReceiveData() {
//Set radio into RX mode.
rf95.setModeRx();
//Check if radio has traffic
if()
//Set the radio mode to idle.
rf95.setModeIdle();
} }
@ -136,6 +183,24 @@ void setup(void) {
// GPS Setup // GPS Setup
gpsSerial.begin(GPS_BUADRATE); 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() { void loop() {
@ -145,12 +210,14 @@ void loop() {
if (gpsSerial.available() > 0) { // Check if data is available from the GPS module if (gpsSerial.available() > 0) { // Check if data is available from the GPS module
gps.encode(gpsSerial.read()); // Decode the GPS data gps.encode(gpsSerial.read()); // Decode the GPS data
if (gps.location.isValid()) { // Check if GPS location data is valid if (gps.location.isValid()) { // Check if GPS location data is valid
double latitude = gps.location.lat(); // Get latitude //double latitude = gps.location.lat(); // Get latitude
double longitude = gps.location.lng(); // Get longitude //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.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.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 { } else {
Serial.println("Waiting for valid GPS data..."); // GPS signal lost or invalid 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 updateDisplay(); // Placeholder: Update the central TFT display with GPS data
lastUpdate = currentTime; // Reset the last update time lastUpdate = currentTime; // Reset the last update time
} }
//Handle the Radio data.
} }
// Function to update the LED ring based on heading direction // Function to update the LED ring based on heading direction
@ -220,6 +290,7 @@ void sendGPSData() {
// - Format the data for transmission // - Format the data for transmission
// - Use the LoRa library to send the data to the paired device // - 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 // Future function to receive GPS data from the other device via LoRa - See adafruit LORA code examples