NRF24L01 mit NEO6M-GPS Programmierhilfe (Mobiles Fencing System)

Hallo zusammen,

ich würde gerne eine Art mobiles Fencing System bauen.
Ich habe mir das folgendermaßen vorgestellt. Das System besteht aus zwei Arduinos.

Arduino 1: Fungiert als Sender: Dieses übermittelt permanent den eigenen Standort. Der
Standort wird mit dem NEO6M ermittelt und per NRF24L01 an Arduino 2 gesendet. Der Standort besteht aus Breiten- und Längengrad.

Arduino 2: Fungiert als Empfänger und ist ebenfalls mit den selben Modulen ausgestattet. Arduino 2 soll ebenfalls permanent die eigene Position ermitteln und ein Signal ausgeben, sobald sich Arduino 1 in einem bestimmten Umfeld von Arduino 1 befindet. Das Signal äußert sich durch ein blinkendes LED-Licht.

Ich bin so weit gekommen, dass ich die GPS-Koordinaten (Breiten- und Längengrad) an das Empfänger-Modul (Arduino 2) übermitteln kann. Das funktioniert soweit auch ganz gut. Allerdings stoße ich hier auf die Grenzen meiner Programmierverständnisse.

Mir fehlt: Die Ermittlung der Standortdaten von Arduino 2, also dem Empfänger Modul. Diese Daten müssen dann mit den Standortdaten von Arduino 1 verglichen werden und gegebenenfalls ein Signal ausgegeben werden. Die Logik hinter der Signalausgabe sollte folgendermaßen aussehen:

If Distanz < (z.B.) 100m, dann LED Blinken
Else LED aus
mit Distanz = Wurzel von ( dxdx + dydy)
mit dx = 71,5 *(Längengrad1 - Längengrad2) (Längengrad 1 = Längengrad von Arduino 1 usw.)
mit dy = 111,3 *(Breitengrad1-Breitengrad2)

Code Sender:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>


TinyGPSPlus gps;
SoftwareSerial ss(4, 3);
RF24 radio(8, 7); // CE, CSN


struct dataStruct{
  double latitude;
  double longitude;
}gpsData;


void setup() {
  Serial.begin(115200);
  ss.begin(9600);
  
  Serial.println("Setting up radio");
  //  Setup transmitter radio
  radio.begin();
  radio.openWritingPipe(00002);
  radio.setChannel(0x76);
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.stopListening();
  radio.enableDynamicPayloads();
  radio.powerUp();
  Serial.println("Starting to send");
}


void loop() {
  while (ss.available() > 0){
    if (gps.encode(ss.read())){
      getInfo();
     radio.write(&gpsData, sizeof(gpsData));
    }
  }
} 


void getInfo(){
  if (gps.location.isValid()){
    gpsData.longitude = gps.location.lng();
    gpsData.latitude = gps.location.lat();
  }
  else{
    gpsData.longitude = 0.0;
    gpsData.latitude = 0.0;
  }
}

Code Empfänger:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>


RF24 radio(8, 7); // CE, CSN

struct dataStruct{
  double latitude;
  double longitude;
}gpsData;

void setup() {
  Serial.begin(115200);
  //  Setup receiver radio
  radio.begin();
  radio.openReadingPipe(1, 00002);
  radio.setChannel(0x76);
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();
  radio.enableDynamicPayloads();
  radio.powerUp();
}

void loop() {
  if (radio.available()) {
    radio.read(&gpsData, sizeof(gpsData));
    Serial.print("Location: ");
    Serial.print(gpsData.latitude, 6);
    Serial.print(", ");
    Serial.print(gpsData.longitude, 6);
}
}

Im Voraus vielen Dank!

Lucas97de: Mir fehlt: Die Ermittlung der Standortdaten von Arduino 2, also dem Empfänger Modul.

Nein, das fehlt Dir ganz gewiss nicht.

Wenn denn der Empfänger mit den gleichen Modulen wie der Sender ausgestattet ist - sprich eine eigenes GPS hat: Was hindert Dich daran, denselben Code wie beim Sender einzusetzen?

Du brauchst halt das Ergebnis nicht zu versenden, sondern kannst es zum Vergleich mit den empfangenen Daten von #1 einsetzen.

Aber auf welche Variablen beziehe ich mich dann in der Berechnung?

gpsData.longitude beschreibt den Längengrad des Empfänger-Moduls

Werden die Koordinaten des Sende-Moduls in der variablen double latitude und longitude gespeichert?

Ich habe versucht den Sender-Code anzupassen.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>


TinyGPSPlus gps;
SoftwareSerial ss(4, 3);
RF24 radio(8, 7); // CE, CSN


struct dataStruct{
  double latitude;
  double longitude;
}gpsData;


void setup() {
  Serial.begin(9600);
  ss.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("Setting up radio");
  //  Setup transmitter radio
  radio.begin();
  radio.openWritingPipe(00002);
  radio.setChannel(0x76);
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();
  radio.enableDynamicPayloads();
  radio.powerUp();
  Serial.println("Starting to send");
}


void loop() {
  while (ss.available() > 0){
    if (gps.encode(ss.read())){
      getInfo();
     radio.read(&gpsData, sizeof(gpsData));
     getDifference();
    }
  }
} 


void getInfo(){
  if (gps.location.isValid()){
    gpsData.longitude = gps.location.lng();
    gpsData.latitude = gps.location.lat();
  }
  else{
    gpsData.longitude = 0.0;
    gpsData.latitude = 0.0;
  }
}
void getDifference(){
  if (sqrt(((71,5*(gpsData.longitude-longitude)*(71,5*(gpsData.longitude-longitude))+(111,3(gpsData.latitude-latitude)*(111,3(gpsData.latitude-latitude)))) < 100{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
  }
  else{
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Allerdings bekomme ich nun den Fehler: “longitude was not declared in this scope”.
Ich weiß nicht, wie ich ich mich auf die empfangenen Daten beziehe…

Okay ich habe einfach eine neue dataStruct angelegt..

Jetzt bekomm ich zwar einen anderen Fehler, aber ich denke, das könnte so funktionieren.

War ich zu langsam:

Okay ich habe einfach eine neue dataStruct angelegt..

Okay.

Da geht was durcheinander; dieses Knäuel kann aber entwirrt werden.

Dein ursprünglicher Sender und Empfänger aus dem Eröffnungspost haben soweit funktioniert? D.h. die seriellen Ausgaben beim Empfänger in der Loop geben die Position des Senders an?

Dann solltest Du am Sender nichts mehr verändern - er erfüllt ja die Anforderung.

In #3 schreibst Du von Veränderungen am Sender, das ist ja eigentlich nicht das, was Du willst. Der Empfänger soll ja die über das Radio empfangene Position mit seiner eigenen vergleichen. Also nehmen wir mal an, dass #3 den Empfänger beschreibt.

Dann braucht der natürlich zwei Variablen vom Typ 'struct DataStruct', einmal für die empfangene (Sender) und einmal für seine eigene (tinyGPS). Als Anregung - und möglichst dicht an Deinem Code:

struct dataStruct{
  double latitude;
  double longitude;
};
struct dataStruct radioGpsData;   // vom Sender-Arduino über Radio
struct dataStruct ownGpsData;  // vom eigenen GPS-Empfänger

...

void loop() {
  while (ss.available() > 0) {
    if (gps.encode(ss.read())) {
// Das sollte dann die Struktur ownGpsData befüllen
      getInfo();

// ACHTUNG: Dieses Radio-Read wird nur aufgerufen, wenn vom GPS-Empfänger Daten vorliegen
     radio.read(&radioGpsData, sizeof(struct dataStruct));

// ACHTUNG: Dieses wird nur aufgerufen, wenn vom GPS-Empfänger Daten vorliegen
     getDifference();
    }
  }
}

Das Anpassen von getInfo() und getDifference() solltest Du selbst hinkriegen können. Dann verschwindet auch der Fehler mit der fehlenden Variable longitude wie von selbst.

'Code schön machen' kommt dann danach wenn es funktioniert.