Zwei Wege Kommunikation mit 433mhz

Moin,
momentan versuche ich krampfhaft zwei Arduinos mit jeweils einem 433mhz Empfänger und Sender dazu zu bringen, miteinander zu sprechen. Ich möchte gerne des öfteren ein Byte übertragen, um jeweils beim anderen Gerät eine Aktion auszuführen.
Eigenartiger Weise funktioniert dies jedoch ab einem Punkt plötzlich nicht mehr. Also Daten werden zwar gesendet, jedoch nicht empfangen.
Gibt es da einen geheimen Trick?
Probiert habe ich es mit den Bibliotheken VirtualWire und Switch (oder wie die hieß). Mit beiden kein Erfolg.

Danke für eure Hilfe :slight_smile:

Woher weißt du das gesendet wurde wenn du nichts empfangen kannst? Und die Programme sowie Schaltplan/Pinbelegung wären auch als Hilfe zur Hilfe nicht verkehrt.

Gruß

Und wichtig ist auch, welche Arduinos und 433 MHz-Module setzt du ein. Letzteres ist ein Link notwendig.

Und je nach dem, was du übertragen möchtest, nimmst du die VirtualWire oder die RCSwitch.
Für Schaltfunktionen ist die RCSwitch besser geeignet.

Jendrik:
Eigenartiger Weise funktioniert dies jedoch ab einem Punkt plötzlich nicht mehr.

Dann lasse diesen verdammten Punkt doch weg, ab dem es nicht mehr funktioniert!

Das war ja einfach!

:smiley:

HI,
danke für die schnellen Antworten. Ich hatte die Details erstmal ausgespart, für den Fall das mein Vorhaben technisch eh nicht realisierbar ist.
Die Funkmodule

Momentan laufen ein Uno als Schloss, die Sensoren als Nano und Uno. Die angehängten Bilder zeigen die Verkabelung.

Das Schloss empfängt die Daten/Befehle der Sensoren. Später soll er dann noch einen Motor ansteuern. Das ist hier aber noch nicht drin, weil erstmal die Beleuchtung stimmen muss.
Pro angemeldeten Sensor soll eine Diode aufleuchten. Wenn die Anmeldezeit um ist oder der Button gedrückt wird, startet das Main-Programm. Ein Sensor sendet ein "AN" Signal, wenn ein bestimmter Abstand gemessen wird. Daraufhin schaltet das Schloss die entsprechende Zahl Dioden an. Diese ist von der Anzahl der angemeldeten Sensoren abhängig. Es sind 16 Dioden, Anzahl der Dioden die leuchten = 16/angemeldete Sensoren.

Der Sensor (Ultraschall Abstandssensor), später sollen vier davon laufen können. Ich möchte es aber variabel halten, so dass man 1-4 verwenden kann, ohne am Code was zu ändern. Daher der Anmeldeprozess. Ich habe auch einen Code, der per Funk den Sensoren ihre AN und AUS Daten mitteilt, da aber das Versenden & Empfangen nicht klappt wie es soll, ist der erstmal obsolet.

Code Schloss

#include <Adafruit_NeoPixel.h>
#include <VirtualWire.h>
#include "SensorModul.h"

#define PIN 6


Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_GRB + NEO_KHZ800);

unsigned long vorherigeMillis = 0;
long dauer = 2*60*1000; //erste Zahl sind die "Minuten" bis Anmeldezeit der Sensoren vorbei ist
bool open = false;
bool sensorenAngemeldet = false;
int anzahlSensoren = 0;
int tasterPin = 11;
SensorModul sensorModule[4];

const int transmit_pin = 5;
const int receive_pin = 12;
const int transmit_en_pin = 3;


void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  pinMode(tasterPin,INPUT);

   vw_set_tx_pin(transmit_pin);
   vw_set_rx_pin(receive_pin);
   vw_set_ptt_pin(transmit_en_pin);
   vw_set_ptt_inverted(true); // Required for DR3100
   vw_setup(4000);	 // Bits per sec

   vw_rx_start();
}

void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if(!sensorenAngemeldet){
    unsigned long aktuelleMillis = millis();
    if(dauer > aktuelleMillis) {
      sensorenRegistrieren();
      wechselSignaleSenden();
    }else{
      sensorenAngemeldet = true;
      ringIlluminieren();
    }

    if (digitalRead(tasterPin)==HIGH){
      sensorenAngemeldet = true;
      ringIlluminieren();
    }

  }else{
    if (!open) {
      vw_wait_rx();
      if(vw_get_message(buf, &buflen)){
        int value = (int) buf[0];
        if(value%2 == 1){
          sensorAn(value);
        }
        else{
          sensorAus(value);
        }
      }
      vw_send((uint8_t*)1,1); 
      vw_wait_tx();
    }
    ringIlluminieren();
  }
}


void sensorAn(int anSignal){

  for(int i=0;i<anzahlSensoren;i++){
    if(anSignal == sensorModule[i].getAnSignal()){
      sensorModule[i].setAngeschaltet(true);
      break;
    }
  }

}

void sensorAus(int ausSignal){

  for(int i=0;i<anzahlSensoren;i++){
    if(ausSignal == sensorModule[i].getAusSignal()){
      sensorModule[i].setAngeschaltet(false);
      break;
    }
  }
}

void ringIlluminieren(){
  for(int pos = 0; pos < anzahlSensoren; pos++){

      int start = pos*(16/anzahlSensoren);
      int ende = (start)+(16/anzahlSensoren);
      for(int i = start; i<ende;i++){
        if(sensorModule[pos].isAngeschaltet())
          strip.setPixelColor(i, 0, 255, 255);
        else
          strip.setPixelColor(i, 0, 0, 0);
      }
      strip.setBrightness(20);
      strip.show();
    
  }
}

void sensorenRegistrieren(){

    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

   if (vw_get_message(buf, &buflen)) {
      int value = (int) buf[0];
      if(!isAngemeldet(value)){
        switch(value){
          case 10:
            setSensorModule(11, 12, 13);
            break;
          case 20:
            setSensorModule(21, 22, 23);
            break;
          case 30:
            setSensorModule(31, 32, 33);
            break;
          case 40:
            setSensorModule(41, 42, 43);
            break;
        }
      }
   }
}

void setSensorModule(int anSignal, int ausSignal, int wechselSignal){
    SensorModul sensor(anSignal, ausSignal, wechselSignal);
    anzahlSensoren++;
    sensorModule[anzahlSensoren-1] = sensor;

    for(int i = 0; i<anzahlSensoren; i++){ //eine Bestätigungslampe pro angemeldeten Sensor
      strip.setPixelColor(i, 255, 0, 0);
      strip.setBrightness(20);
      strip.show();
    }
}

bool isAngemeldet(int anSignal){
  for(int i =0; i<anzahlSensoren; i++){
    if(sensorModule[i].getAnSignal() == anSignal)
      return true;
    else
      return false;
  }
}

void wechselSignaleSenden(){
  for(int i=0; i<anzahlSensoren; i++){
    uint8_t wechselSignal = sensorModule[i].getWechselSignal();
    vw_send(&wechselSignal,1);
    vw_wait_tx();
  }
}

Code vom Sensor

Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
int DistanceIn;
int DistanceCm;

//Funkmodul initialisieren
const int transmit_pin = 5;
const int receive_pin = 7;
const int transmit_en_pin = 3;

bool angemeldet = false;
bool anmeldungGesendet = false;
uint8_t anmeldeCode = 20;
uint8_t wechselCode = 23;
uint8_t anSignal = 21;
uint8_t ausSignal = 22;

bool statusAenderung = false;
bool aktiviert = false;

void setup()   // Setup um den Arduino zu konfigurieren
{
  vw_set_tx_pin(transmit_pin);
  vw_set_rx_pin(receive_pin);
  vw_set_ptt_pin(transmit_en_pin);
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(4000);	 // Bits per sec
  vw_rx_start();
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}


void loop()     // Loop für die Messung der Werte, läuft endlos
{
 if(!angemeldet){
  pixelSteuerung(1);
  if(!anmeldungGesendet){
    vw_send(&anmeldeCode,1);
    vw_wait_tx();
    anmeldungGesendet = true;
  }else{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if(vw_get_message(buf, &buflen)){
      int value = (int) buf[0];
      if(value==wechselCode){
        angemeldet = true;
        pixelSteuerung(0);
      }
    }
  }
}else{

    delay(100); 
    if(DistanceCm < 60 && !aktiviert){
      aktiviert = true;
      statusAenderung = true;
    }
    else if(DistanceCm > 60 && aktiviert){
      aktiviert = false;
      statusAenderung = true;
    }
 }
 senden();
}

void senden(){
  if(statusAenderung){
    if(aktiviert){
      pixelSteuerung(2);
      vw_send(&anSignal,1); 
      vw_wait_tx();
     
    }else{
      pixelSteuerung(0);
      vw_send(&ausSignal,1);
      vw_wait_tx();
      
    }
    statusAenderung = false;
    vw_wait_rx();
  }
}

void pixelSteuerung(int farbe){
  switch(farbe){
    case 0:
      strip.setPixelColor(0, 0, 0, 0); //aus
      break;
    case 1:
      strip.setPixelColor(0, 255, 0, 0); //rot
      break;
    case 2:
      strip.setPixelColor(0, 0, 255, 0); //grün
      break;
  }
  strip.setBrightness(20);
  strip.show();
}

Der Vollständigkeit halber noch die Header-Datei zu den SensorModul-Objekten

class SensorModul{
  public:
    SensorModul(int anSignal, int ausSignal, int wechselSignal);
    SensorModul();
    int getAnSignal();
    int getAusSignal();
    int getWechselSignal();
    bool isAngeschaltet();
    void setAngeschaltet(bool angeschaltet);

  private:
    int anSignal;
    int ausSignal;
    int wechselSignal;
    bool angeschaltet;
};

Die Codes sind noch nicht optimiert. Hier und da kann man noch Methoden ergänzen um doppelten Code zu vermeiden. Entschuldigt bitte den Flickenteppich.

Nochmal danke für eure Zeit :slight_smile:

Ergänzung:
Mit dem derzeitigen Code schafft es ein Sensor sich anzumelden. Die Rückmeldung vom Schloss kommt aber schon nicht mehr beim Sensor an. Es schafft kein weiterer Sensor sich anzumelden.
Das erkenne ich daran, welche Dioden leuchten und in welchen Farben.

Da du keine Kommentare im Sketch hast, ist der schwer zu verstehen.

Ich vermute, dass ein Sensor ständig sendet und damit für die anderen keine Möglichkeit besteht, sich anzumelden.

Für dein Projekt sind die von dir verwendeten Module sehr schlecht. Die Empfänger taugen dafür nicht.
Die Empfänger sind von sehr schlechter Qualität.

Wie kommst du da drauf, dass es mit 4000 Bits funktioniert?
Meine Erfahrung hat gebracht, dass eine sicher Übertragung nur bis 2000 Bits möglich ist.
Da drüber nur bei einer mehrmaligen Aussendung.

Für dein Vorhaben solltest du dich für Transceiver im 868 MHz-Bereich entscheiden. Das arbeitet sicher, weil dafür entwickelt.

Andernfalls musst du es anders lösen und dein "Schloss" als Master nehmen und die Sensoren (Slave) zum Senden auffordern.

Hier gibt es passende Module: Transceiver

Edit:
Mir ist gerade aufgefallen, beim Sensor hast du keine "VirtualWire.h" eingebunden.
Vergessen?

Hi,
danke für deine Antwort.
Die 4000 bit hatte ich irgendwann testweise eingestellt, weil 2000 nicht funktioniert hat.
Mist, die Kommentare habe ich noch nicht geschrieben. Sorry.

Der Kauf von Transceivern ist erstmal keine Option. Es sei denn, es geht wirklich nicht anders. Ich habe hier schon diverse Sets liegen - so um die 10...

Die Master - Slave Variante wäre dann sowas wie:

M: Meldet euch an
S: ich melde mich an
M: verstanden
S: (angemeldet, warten)

M: alle angemeldet
S: verstanden, (aktiviere Sensor)

M: hat jemand Änderung? S: ich habe Änderung M: gib her S: sende Änderung M: verstanden

Hab ich das so richtig verstanden?

Die VirtualWire.h habe ich eingebunden. Hatte vorhin beim Code kopieren ein Kommentar rausgeworfen und dabei vermutlich den include gelöscht.

Jendrik:
danke für deine Antwort.
Die 4000 bit hatte ich irgendwann testweise eingestellt, weil 2000 nicht funktioniert hat.

Das deutet darauf hin, dass in deinem Umfeld starke Störungen vorhanden sind. Deine Empfänger sind Pendler mit einem sehr schlechten Großsignalverhalten.
Dadurch wird die Übertragung etwas sicherer, wenn diese schneller abläuft.

Noch sicherer wird das mit besseren Empfängern. Beispiel: 433 MHz-Empfänger

Der Kauf von Transceivern ist erstmal keine Option. Es sei denn, es geht wirklich nicht anders. Ich habe hier schon diverse Sets liegen - so um die 10...

Naja, der Preis ist ja zu verkraften, aber dennoch sind die Empfänger eine schlechte Wahl.

Die Master - Slave Variante wäre dann sowas wie:

M: Meldet euch an
S: ich melde mich an
M: verstanden
S: (angemeldet, warten)

M: alle angemeldet
S: verstanden, (aktiviere Sensor)

M: hat jemand Änderung? S: ich habe Änderung M: gib her S: sende Änderung M: verstanden

Die VirtualWire.h habe ich eingebunden. Hatte vorhin beim Code kopieren ein Kommentar rausgeworfen und dabei vermutlich den include gelöscht.

Ja, so ungefähr. Du musst da nur jeden Sensor einzeln ansprechen und auf Antwort warten.

Noch eine Frage zu deinem Sketch "Schloss".
Warum hast du die Anweisungen zum Daten einlesen nochmal in der Funktion "sensorenRegistrieren" eingesetzt. Dazu reicht normaler weise eine einmalige Anweisung in der Loop und eine entsprechende Verzweigung auf die Funktionen. Ich könnte mir vorstellen, dass auch dadurch ein Fehler auftreten kann.

Hi nochmal,
nachdem ich völlig verzweifelt bin, habe ich deinen Ratschlag befolgt und die Tranceiver gekauft. RF69CW aus deinem Link.
Natürlich bekomme ich sie nicht zum laufen. Kann mir jemand einen einfachen Sketch geben, der ganz simpel einen String hin und her schickt? Meine Arduinos scheinen nix zu versenden, jedenfalls wird auf der Empfängerseite nichts ausgegeben.
Verkabelt habe ich wie in diesem Bild hier.
Auf einer Seite habe ich die Empfehlung gelesen, dass man einen 10k Widerstand an D10, also NSS hängen soll.

Hier mein Ansatz für "einfach einen String verschicken"

#include <RFM69.h>

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     23  //the same on all nodes that talk to each other
#define RECEIVER      77    //unique ID of the gateway/receiver
#define SENDER        0
#define NODEID        SENDER  //change to "SENDER" if this is the sender node (the one with the button)
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
#define FREQUENCY     RF69_868MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
//*********************************************************************************************
#define SERIAL_BAUD   115200
RFM69 radio;

void setup() {
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.encrypt(ENCRYPTKEY);
}

void loop() {
  radio.sendWithRetry(SENDER, "Hallo",5);
}

Empfänger:

#include <RFM69.h>

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     23  //the same on all nodes that talk to each other
#define RECEIVER      77    //unique ID of the gateway/receiver
#define SENDER        0
#define NODEID        RECEIVER//change to "SENDER" if this is the sender node (the one with the button)
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
#define FREQUENCY     RF69_868MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
//*********************************************************************************************
#define SERIAL_BAUD   115200
RFM69 radio;

void setup() {
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.encrypt(ENCRYPTKEY);
}

void loop() {
  if (radio.receiveDone()){
    String message = String((char*)radio.DATA);
    Serial.println(message);
    if (radio.ACKRequested())
        radio.sendACK();
  }
}

Was mir aktuell auffällt, du verwendest nicht die "SPI.h"-Library.

Ein System mit viele Sendern funktoniert nur wen immer nur 1 Sender sendet. Ist das bei Deinen Sendern so?
Grüße Uwe

Ja, es soll immer nur einer zur Zeit senden.
Allerdings muss jedes Mitglied der Gruppe mal senden.

Die SPI Bib benutze ich ja nicht. In wie weit müsste ich sie denn einbinden?

Jendrik:
Die SPI Bib benutze ich ja nicht. In wie weit müsste ich sie denn einbinden?

Dann sieh dir mal die Beispiele aus deinem Link (RFM69-Bibliothek) an, da kannst du alles erkennen.
Evtl. kannst du aus den Beispielen auch noch andere Fehler in deinem Sketch erkennen.

Jo, die Beispiele habe ich gesehen. Manche verwenden die SPI.h garnicht, zB diese.
Daher ist mir nicht wirklich klar wozu die denn gut ist.

Wenn ich das Gateway-Beispiel zusammen mit dem Node-Beispiel laufen lasse (hier wird die SPI Header verwendet), springt mir die Frage "SPI Flash MEM not found (is chip soldered?)..." entgegen. Und ja, diese Frage kann ich definitiv mit ja beantworten.
Es sei denn die Belegung von dem Link aus meinem ersten Post ist Unsinn.

Kannst du mir einen Hinweis geben?

Jendrik:
Ja, es soll immer nur einer zur Zeit senden.
Allerdings muss jedes Mitglied der Gruppe mal senden.

Aber wenn er nicht sendet, Emitiert der sender auch keine Hochfrequenz?
Grüße Uwe

Argh, ich habe alles direkt angeschlossen und vermute das der Chip 5V auf die Mütze bekommt. Vielleicht hab ich die Chips jetzt zerstört?