Kommunikation zwischen ATtiny und ESP32 via HC-12

Hallo,

Ich möchte zwischen den o.g. Boards eine Kommunikation via HC-12/433MHz aufbauen.

Der Aufbau soll grundsätzlich so aussehen, dass der "Server" (ESP32) Daten von verschiedenen Clients empfangen und den Erhalt entsprechend bestätigen soll.

Im ersten Schritt bin ich dabei, den Empfang hier im und ums Haus zu testen um zu sehen, ob ich überall dort Empfang habe, wo ich ihn brauche.

Dazu habe ich einen Client (ATtiny85), der einfach nur eine Ping-Nachricht verschickt und der Server schickt ein OK zurück, wenn er etwas empfängt. Aktuell wird aber der Inhalt der Nachrichten gar nicht ausgewertet. Im Grunde checken beide einfach nur, ob sie etwas empfangen und reagieren dann wie gewünscht.

Grundsätzlich funktioniert das, aber nachdem ich jetzt mal den Inhalt der Nachrichten lesen wollte, habe ich am Server festgestellt, dass wohl nur Kauderwelsch ankommt. Zumindest zeigt mit der Serial Monitor nur "������" an.
Ich hatte vorher einen Arduino Uno als Server, da hat alles gut geklappt.

Hier mal der Server-Code:

#include <SoftwareSerial.h>
#define RXD2 D7	//(RX2)
#define TXD2 D6	//(TX2)
SoftwareSerial softSerial(RXD2, TXD2);  //RX, TX

void setup() {
  Serial.begin(115200);
  softSerial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    //Eingabe am Serial Monitor and send over HC-12
    String input = Serial.readString();
    Serial.print("Send: ");
    Serial.println(input);
    // Senden über HC-12
    softSerial.println(input);
  }
  if (softSerial.available() > 1) {
    //Empfang am HC-12
    String input = softSerial.readString();

    // Ausgabe am Serial Monitor
    Serial.println(input);
    softSerial.println("OK");
  }
  delay(20);
}

Und hier der Client-Code:

#include <SoftwareSerial.h>

SoftwareSerial softSerial(4, 3);  //RX, TX
int nextMessage=0;
int ledPin=2;

void setup() {
  Serial.begin(115200);
  softSerial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    //Eingabe am Serial Monitor and send over HC-12
    String input = Serial.readString();
    Serial.print("Send: ");
    Serial.println(input);
    // Senden über HC-12
    softSerial.println(input);
  }
  if(nextMessage>=0 && nextMessage<=millis()){
    softSerial.println("PING");
    nextMessage=-1;
  }

  if (softSerial.available() > 1) {
    //Empfang am HC-12
    String input = softSerial.readString();
    // Ausgabe am Seral Monitor
    Serial.println(input);
    nextMessage=0;
    digitalWrite(ledPin, HIGH);
    delay(100);
    digitalWrite(ledPin, LOW);
    delay(100);
    digitalWrite(ledPin, HIGH);
    delay(100);
    digitalWrite(ledPin, LOW);
  }
  delay(20);
}

Hat jemand eine Idee, woran das liegen könnte?

Danke

Evtl. an der Taktfrequenz des ATtiny. SoftwareSerial arbeitet erst ab 8 MHz Taktfrequenz.

Und weiteres ist zu beachten: Bei "Mehrsender-Betrieb" musst du sicher sein, dass nur ein Sender zur Zeit sendet, sonnst kommt nix brauchbare an.

Edit:
Beim ESP32 brauchst du kein SoftwareSerial, da kannst du eine weitere Hardware serielle verwenden.

Der läuft mit 8MHz
Und wie ich schon geschrieben hatte, lief es sauber, als ich einen Uno als Server verwendet hatte.
Da wurde der empfangene String sauber erkannt und auch ausgegeben.

Das ist natürlich ungut... Da muss ich mal überlegen, was ich da machen kann, um das zu verhindern.
Danke für den Hinweis.

Dann liegt es an der Schnittstelle der ESP

Vom Server die Daten anfordern.

Einfachste Variante: Der Master fordert die Sendung von einem Teilnehmer an und nur der darf antworten.

Gruß Tommy

Zeig doch (Link) mal, welches Board du verwendest. Die Pins D6 und D7 passen da nicht so recht.
Genauere, eindeutige Angaben sind immer GPIO zu verwenden.

Beim Client Code die Ausgabe von Serial mal von 115200 auf 9600 runter stellen.

Also nachdem ich jetzt mal meinen "mobilen Client" nochmal an mein Entwicklungsboard angestöpselt habe, damit ich von beiden Systemen einen Serial Monitor habe, funktioniert es jetzt komischerweise ohne Probleme, ohne dass ich bewusst etwas geändert habe...

Ich nutze für den Server dieses Board hier:

Das hatte ich auch schon überlegt...
Aber die meisten Clients schlafen den Großteil ihrer Zeit, und senden nur, wenn sie relevante Daten/Statusänderungen haben, daher würden sie entsprechende Aufforderungen gar nicht mitbekommen...

Meine aktuelle Idee wäre, dass der Server alle x Sekunden einen "offenen Slot" kommuniziert (Jeder Sensor hat seinen eigenen Slot) und wenn ein Sensor etwas senden möchte, muss er warten, bis er dran ist und darf dann senden. Das könnte dann im worst case bis zu 30 Sekunden dauern, aber das sollte vertretbar sein

Wie willst Du den Gleichlauf der Zeiten zwischen den Sensoren und dem Server synchronisieren?

Gruß Tommy

Ich verstehe leider nicht genau, was Du meinst.

Wenn der Sensor schläft, woher soll er dann wissen, wann sein offener Slot ist?
Also müssen Zeitabläufe synchronisiert werden, was beim Schlafen nicht geht.
Du hast Da ein konzeptionelles Problem.

Gruß Tommy

Mein Plan wäre folgender:

  • Der Server hat eine Liste von Sensoren, die er ständig durchgeht
  • Der Server kommuniziert alle 3 Sekunden einen neuen offenen Slot
  • Sensor 3 wacht auf und möchte etwas schicken.
  • Sensor 3 wartet so lange, bis er vom Server die Info bekommt, dass der Slot für "Sensor 3" jetzt offen ist.
  • Sensor 3 schickt seine Daten und legt sich wieder schlafen

Ok, der ist also munter, weil er etwas schicken will, wartet bis er die Aufforderung vom Server zum Senden bekommt, sendet und schläft weiter.
Wie sich das auf einen Batteriebetrieb auswirkt, musst Du austesten. Es verringert auf alle Fälle die Laufzeit.

Gruß Tommy

Ja, ist sicher nicht optimal, aber irgendeinen Tod muss man halt sterben, wenn man Daten verschicken möchte :smiley:

Eine bessere Lösung habe ich bisher noch nicht gefunden.
Ein Teil meiner Sensoren ist halt außerhalb meines WLANs und ich bin schon froh, dass ich überhaupt eine Funkverbindung hinbekomme

Wenn der Sensor etwas melden will,schläft er nicht, sondern wartet, bis er vom Master eine Aufforderung ("Slot") bekommt. Wann das genau ist, kann ihm ziemlich egal sein.

Master-Slave ist etwas anderes als Client-Server.
Der Master bestimmt, welcher Slave senden darf.
(Client-Server braucht noch eine Schicht, wo Kollisionen abgefangen werden)

Das ist es ganz sicher nicht, aber du wirst es schon schaffen.
Und nochmal, verwende zukünftig die Bezeichnung "GPIO", das ist eindeutig.
Und nutze auf dem ESP32 die Hardware Serielle und nicht deinen Mischmasch mit SoftwareSerial auf den Pins der UART. Da hast du gleich weniger Probleme.
Und was war dein Problem, dass es seriell nicht funktionierte ?

Das initiale Problem war, dass der String, der am Server/Master empfangen wurde, "korrupt" war. Es kam nicht das an, was gesendet wurde, bzw wurde nur als "������" ausgegeben. Auch ein Vergleich mit empfangenerString == erwarteterString ist fehlgeschlagen.
Aber nachdem ich meinen Client auf mein Entwicklerboard umgesteckt hatte, hat alles wieder funktioniert.
Ich hatte aber vorher einen Uno als Server/Master, da hat alles ohne Probleme funktioniert.
Also nochmal zusammengefasst:

  • Server/Master mit Arduino Uno => alles ok
  • Änderung des Server-Boards auf ESP32C3 => Empfangene Daten sind korrupt
  • Umstecken/Reboot des Clients => alles wieder ok

Wenn Breadboards involviert sind, ist da auch kein Wunder. Da gibt es halt immer mal wieder Probleme, die nicht sofort erkennbar sind. Auch Jumperkabel sind mehrfach zu prüfen.