Schlechte 433MHz-Funkverbindung - wo ist das Problem?

Verständnisprobleme 433MHz-Funkverbindung

Hallo zusammen,

ich habe Probleme bei der Optimierung einer Funkverbindung mehrerer Sender (Mini Pro) und einem Empfänger (Mega 2560).

Ich habe mit einem Sender angefangen. Da lief noch alles reibungslos und ausnahmslos jedes Datenpaket wurde empfangen. Das wurde mit jedem weiteren Sender schlechter, obwohl sich die Position von Sender und Empfänger nicht verändert haben.

Erste Annahme: Die Funkverbindung ist schlecht
Ist sie nicht. Hab ich geprüft. Alle Sender haben Antennen und funktionieren autark über 20 Meter im Haus. Wenn nur ein Sender alle 4 Sekunden ein Signal schickt, dann wird jedes Paket empfangen. Senden alle 5 Sender werden viele der jeweiligen Pakete ausgelassen.

Zweite Annahme: Datenmüll wegen zeitgleichen Sendens
Gecheckt und ausgeschlossen. Die Sender schicken nur alle paar Sekunden Daten und definitiv nicht zeitgleich. Dazu müsste ich sie zeitgleich einschalten und das ist nicht der Fall. Auch kommen ja Daten aller Sender an - aber eben nur ein Bruchteil der Pakete.

Dritte Annahme: Die Übertragung dauert so lange, dass das nächste Paket nicht empfangen werden kann.
Hab ich durch Serial-Ausgaben am Anfang und Ende des Datenempfangs gecheckt. Der Mega empfängt und verarbeitet die Daten blitzschnell. Er wartet danach nur sehr lange auf neue Daten. Da kommt dann einfach nichts.

Ich weiß nicht, wo ich noch suchen soll und komme einfach nicht drauf, was das Problem sein könnte. Vielleicht kann jemand von Euch helfen.

Sender:
https://www.amazon.de/gp/product/B010SR8J4I/ref=oh_aui_detailpage_o05_s01?ie=UTF8&psc=1

Empfänger:
http://www.ebay.de/itm/381199588108

Code folgt im weiteren Beitrag. Zeichenzahl wird überschritten.

Hier ein Sketch eines der Sender (alle ähnlich):

#include <VirtualWire.h>
#include <LowPower.h>

char Array[128];

volatile int sleepcounter = 0; // Schlafzyklen mitzählen
volatile int doorstatus3 = 0;

// INSTALLATION MAGNET SENSOR PART

const int switchPin = 6;    // Reed switch to digital pin 2
int buttonState = 0;         // variable for reading the pushbutton status

// ENDE MAGNET SENSOR PART


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  vw_setup(4000);  // Bits per sec
  vw_set_tx_pin(9);     // Datenleitung

// MAGNET SENSOR PART ---------------------------

    pinMode(switchPin, INPUT); // switchPin is an input
    digitalWrite(switchPin, HIGH); // Activate internal pullup resistor

// MAGNET SENSOR ENDE ---------------------------


  pinMode(7, OUTPUT);   // VCC 5V
  digitalWrite(7, HIGH);
  pinMode(8, OUTPUT);   // GND 0V
  digitalWrite(8, LOW);


}

void loop() {

     counter5 ++;

 if (counter5 == 32000) {counter5 = 0;}

     sleepcounter ++;  

     Serial.println (sleepcounter);

    // Enter power down state for 2 s with ADC and BOD module disabled
    LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);  


  if (sleepcounter == 1) {

    int buttonState = digitalRead(switchPin);
    int temperature = 0;
    int humidity = 0;
    int brightness = 0;
    int rain = 0;
    int doorstatus1;
    int doorstatus2 = 0;
    int batterystatus1 = 0;
    int batterystatus2 = 0;
    int counter1 = 0;
    int temperature2 = 0;
    int humidity2 = 0;
    int motion1 = 0;
    int counter2 = 0;
    int counter3 = 0;
    int counter4 = 0;
    int doorstatus3 = buttonState;

    String (counter5, DEC);


    Serial.println("____________ STATUS _____________");
    Serial.println();
    Serial.print("buttonState: "); Serial.println(buttonState);
    Serial.print("doorstatus3: "); Serial.println(doorstatus3);
    Serial.print("counter5: "); Serial.println(counter5);  
    Serial.println();
    Serial.println("____________________________________");
    Serial.println();



    sprintf(Array, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d.", temperature, humidity, brightness, rain, doorstatus1, doorstatus2, batterystatus2, batterystatus1, counter1, temperature2, humidity2, motion1, counter2, counter3, counter4, doorstatus3, counter5);
     vw_send((uint8_t*)Array, strlen(Array));
     vw_wait_tx(); 


    sleepcounter = 0;
    }


}

Sketch des Empfängers siehe Dateiupload (nur als Download, da über 9.000 Zeichen)

receiver.txt (19.4 KB)

Hauptproblem könnte deine eingestellte Baudrate sein. VirtualWire ist nur für 2000 Bps sicher, darüber ist Zufall.

Und wenn du mehrere Sender frei nacheinander alle 5 Sek. senden lässt, treffen die sich irgend wann. das funktioniert so nicht, jedenfalls nicht sicher.

Okay... Baudrate bei den Sendern oder dem Empfänger? Oder klappt das auch unterschiedlich? 1200 ist zum Verarbeiten der Daten ziemlich langsam…

daniel_e:
Okay... Baudrate bei den Sendern oder dem Empfänger? Oder klappt das auch unterschiedlich? 1200 ist zum Verarbeiten der Daten ziemlich langsam…

Das ist leider so.
Wenn es nicht reicht, musst du mit anderen Modulen (FSK) arbeite, da geht es schneller.
Und wenn du mit Transceivern arbeitest, kannst du vom "Master" die "Clients" zum Senden auffordern.
Dann gibt es keine Störungen.

Okay. Hab gerad alle Sender und den Empfänger auf Baudrate 1200 umgestellt. Unveränderte Situation. Ein Sender alleine sendet verlässlich alle Pakete. Kommen weitere Sender hinzu werden plötzlich manche Sender sekundenlang ignoriert, dann wieder ein paar Pakete empfangen und dann wieder nicht. Passiert mit allen Sendern mal. Eine Überlagerung der Daten kann ich weiter ausschließen. Selbst wenn ich alle Sender auf alle 8 Sekunden senden umstelle bleiben teilweise viele Pakete aus. Und bei 8 Sekunden ist es so gut wie unmöglich, dass die Daten von (aktuell 3) Sendern sich überschneiden.

Das Problem muss woanders liegen.

Hallo,
arbeiten alle Sender/Empfänger mit der gleichen Übertragungsrate?
Wenn ja- woher weißt Du das? Wo hast Du das eingestellt?

Arbeiten alle Sender/Empfänger auf dem selben Kanal? z.B. 433.92MHz?
Findet etwas wie FrequentHopping statt?
Die Dinger müssen sich ja zu erkennen geben. Kann es sein, das einige die gleiche "Kennung"
haben?
Hast Du mal einen Link zu den Datenblättern? Nein?
Funk ohne Datenblatt ist RätselRaten...
Gruß und Spaß
Andreas

daniel_e:
Das Problem muss woanders liegen.

Funk geht oftmals seltsame Wege.
Dann mach die Pausen länger oder verabschiede dich von den "einfachen" Modulen.
Oder nimm Master/Slave.

Und hier der Sketch des Empfängers (nur als Download, da über 9.000 Zeichen):
https://we.tl/NryMrv9sqh

Ich werde keine Lizenzbedingungen eines Fremdanbieters bestätigen, nur um deinen Code sehen zu können.

Arbeiten alle Sender/Empfänger auf dem selben Kanal? z.B. 433.92MHz?
Findet etwas wie FrequentHopping statt?
Die Dinger müssen sich ja zu erkennen geben. Kann es sein, das einige die gleiche "Kennung"
haben?

Die Sender und auch die Empfänger sind zu doof für solche Spielchen.
Nein, das können sie nicht.

daniel_e:
Und hier der Sketch des Empfängers (nur als Download, da über 9.000 Zeichen):

Warum hängst du das nicht als txt-Datei an, dann kann man da wenigstens rein sehen.

Als Download bei einem Fremdanbieter ist eine ganz schlechte Idee.

Sorry mit dem Download. Hab den für mich im Alltag üblichen Weg gewählt. Den Upload hab ich bisher nicht bemerkt. Ist korrigiert und die txt nun als Direktdownload im Beitrag oben aktualisiert.

Aus welchem Grund hast du Pin23 für den Empfänger-Datenpin gewählt ?

Evtl. hast du damit Probleme. Nur eine Vermutung, da ich den Mega nicht weiter kenne.

Teste doch mal einen anderen Pin, in vielen Beispielen wird Pin D2 für den Empfänger verwendet.

Hier findest du noch interessante Informationen zu VirtualWire.

Oder du nimmst die neuere Alternative: Radiohead
Da habe ich bisher allerdings keine Erfahrung.

Wie viele Bytes sendest du eigentlich? Da Virtual-Wire nicht gerade schnell ist, ist eine Kollision gar nicht so unwahrscheinlich. Die ProMini haben wahrscheinlich Resonatoren, so dass sie alle etwas unterschiedlich schnell laufen und so es früher oder später zu Kollisionen kommt, ähnlich wie im Alltag bei zwei Autos vor einer Ampel, die ähnlich schnell blinken und im Laufe der Zeit mal gleichzeitig und mal gegenphasig blinken.

Hast du den Effekt auch, wenn deine Sender zwischen dem Senden nicht schlafen, sondern warten?

Ich habe keine Erfahrung mit den Pinzuständen während der einzelnen Sleepmodes,
ein unbeabsichtigtes HIGH auf dem Sendepin könnte dir den Äther füllen…

Was hängt an Pin 7 und 8?

  pinMode(7, OUTPUT);   // VCC 5V
  digitalWrite(7, HIGH);
  pinMode(8, OUTPUT);   // GND 0V
  digitalWrite(8, LOW);

Wenn es der Sender ist, könntest du vor dem Sleep den Saft abdrehen.

Ich muss gestehen, deinen "Sleepmodus" durchblicke ich nicht.
Was bezweckst du damit ?
Ist der zum gezielten Senden, z.b. alle 8 Sekunden.
Warum sollen die Sender so schnell aufeinander folgend, senden.

Hallo,
viel Ahnung vom Programmieren habe ich nicht- aber Dein Empfänger-Sketch
gehört- so wie er ist in die Tonne!
Das schafft nicht einmal ein Mega!

Zuerst würde ich mal die "VirtualWire.h" nicht benutzen. Der Mega hat echte
serielle Schnittstellen die um einiges schneller sind.

Dann nutzt Du die "Adafruit_GFX.h". Die ist langsamer als der Mega.
So etwas ist tötlich:

tft.setCursor(245, 60);
    tft.setTextColor(LIGHTGREY);
    tft.setFont(&Open_Sans_Light_12);
    tft.fillRect(237, 50, 45, 12, NEUTRALWHITE);

während das noch gemalt wird, macht der Mega schon lange etwas anders. Kommt
er dabei auf eine neue Malerei, bevor die alte fertig ist, dann rauscht es.

Dann werden in jedem Durchlauf eine Unmenge von Strings verarbeitet. Wenn
mich nicht alles täscht, dann legt der Mega davon eine Kopie im dynamischen
Speicher ab. Ich kann mir gut vorstellen, das dieser innerhalb von Sekunden
zugemüllt ist.

Zum Testen würde ich nur "Serial.print" verwenden- und alle TFT-Befehle
auskommentieren. Wenn "Serial.print" fehlerfrei läuft dann das raus-
und nur die TFT-Befehle nutzen.

So wie sich das liest, funken die Dinger ja wie wild in der Gegend unkonrolliert
rum. Verpasse denen doch selbst eine Kennung.

Also Du nennst einen Sender z.B. SenderA, einen anderen SenderB
Dann bastelst Du Dir im Mega eine EmpfangsRoutine die nur auf die Kennung
abfragt.
ist SenderA, dann verarbeite die Daten
Wenn alle Daten verarbeitet sind, dann erst gibst Du die Abfrage für den
nächsten Sender frei.
So kannst Du einen Sender nach dem nächsten verarbeiten.
Du sagtest ja, das es mit einem funktioniert.
Gruß und Spaß
Andreas

SkobyMobil:
Hallo,
viel Ahnung vom Programmieren habe ich nicht- aber Dein Empfänger-Sketch
gehört- so wie er ist in die Tonne!
Das schafft nicht einmal ein Mega!

Zuerst würde ich mal die "VirtualWire.h" nicht benutzen. Der Mega hat echte
serielle Schnittstellen die um einiges schneller sind.

Ohhh...

Du willst die Serielle für eine 433 MHz-Funkübertragung verwenden.
Das mag bei speziellen Modulen funktionieren, aber nicht bei den hier verwendeten.

Hallo,
"Output signal: TTL electric level signal entire transmit"
hoh, hoh, hooh- hört sich an wie Weihnachten...

Der Empfänger hat also einen "VirtualWire.h" Ausgang- und keinen Seriellen?
Das versuch mir einmal zu erklären. (dünnes Eis)
Gruß und Spaß dabei
Andreas

SkobyMobil:
Hallo,
"Output signal: TTL electric level signal entire transmit"
hoh, hoh, hooh- hört sich an wie Weihnachten...

Der Empfänger hat also einen "VirtualWire.h" Ausgang- und keinen Seriellen?

Naja, seriell ist der schon, allerdings wird in der Library mehr als nur Daten auslesen gemacht.
Diese werden in der Library auch entsprechend codiert/decodiert. dadurch sparst du dir weiteren eigenen Code. Beschreibung

Puh! Also erst mal danke für die rege Teilnahme!

Ich versuche das mal aufzudröseln:

Whandall:
Hast du den Effekt auch, wenn deine Sender zwischen dem Senden nicht schlafen, sondern warten?

Ich habe keine Erfahrung mit den Pinzuständen während der einzelnen Sleepmodes,
ein unbeabsichtigtes HIGH auf dem Sendepin könnte dir den Äther füllen...

Was hängt an Pin 7 und 8?

Wenn es der Sender ist, könntest du vor dem Sleep den Saft abdrehen.

Es gibt einzelne Sender, die direkt am Strom hängen (weil dort verfügbar) - die schlafen nicht, sondern sind daueraktiv, verlieren aber auch Datenpakete.

Der Hinweis mit der Sleepmode ist gut - ich checke mal, wie die Pins im Schlaf reagieren.

Pin 7 und 8 sind VCC und GND für den Magnetsensor, weil am Pro Mini diese Pins schon vom Sender belegt sind. Ich versuche das mal umzulegen und den Strom vor dem Schlafen auszuschalten. Super Hinweis!

HotSystems:
Ich muss gestehen, deinen "Sleepmodus" durchblicke ich nicht.
Was bezweckst du damit ?
Ist der zum gezielten Senden, z.b. alle 8 Sekunden.
Warum sollen die Sender so schnell aufeinander folgend, senden.

Der Sleepmodus ist vor allem zum Stromsparen. Ich habe die Pro Mini durch Sleepmodes und Entfernen der LEDs auf 0,09 mAh bekommen. Damit verbrauchen sie 24mAh pro Tag und halten mit 4 Akkus über ein Jahr.

Alle 8 Sekunden senden nur die Sensoren, die für Türen oder Fenster sind. Die sollen relativ häufig einen Status abgeben. Das ist nicht schnell, wenn sie nur wenige Millisekunden zum Senden brauchen.

SkobyMobil:
viel Ahnung vom Programmieren habe ich nicht- aber Dein Empfänger-Sketch
gehört- so wie er ist in die Tonne!
Das schafft nicht einmal ein Mega!

Zuerst würde ich mal die "VirtualWire.h" nicht benutzen. Der Mega hat echte
serielle Schnittstellen die um einiges schneller sind.

Dann nutzt Du die "Adafruit_GFX.h". Die ist langsamer als der Mega.

Gute Hinweise... muss ich alles checken.
Ich glaube aber nicht, dass die Adafruit GFX das Problem ist. Die Icons erscheinen nämlich super schnell und erst, wenn Daten überhaupt empfangen wurden. Die Wartezeit wird davon nicht beeinflusst.

Die VirtualWire.h nicht nutzen, sondern die serielle Schnittstellen? Aber es ist doch gerade der Sinn, dass ich kabellos arbeiten möchte. :slight_smile: