ESP32 & Arduino Mega 2560 R3 verbinden?

Hallo, ich hab zur zeit vor eine Terrarium-steuerung zu bauen.
im vorfeld habe ich mir einige gedanken gemacht und habe mir dafür folgende teile besorgt:

  • Arduino Mega 2560 R3 1x
  • ELEGOO 8-kanal-relaiskarte 1x
  • mehrere DS18B20 sensoren
  • mehrere DHT11 Sensoren
  • Mosfet IRF520
  • 12V lüfter
  • PIR sensor
  • Magnetkontakte
  • etliche LED´s
  • usw (mehr oder weniger nichts spezielles mehr)

ich habe alle module schon einzeln programmieren können und auch über den serial monitor auslesen können.
die zusammen setzung des codes ist aber gerade ein anderes problem.
eigentlich war geplant das ganze an ein raspberry pi zu schließen und von dem aus dann alles zu verwalten bzw zu steuern.
was aber im nachhinein eher zu unzuverlässig ist für so ein projekt.
deshalb dachte ich daran ein ESP32 D1 R32 (welches hier noch unbenutzt rum liegt) mit dem Arduino Mega 2560 R3 zu verbinden nur wie ?
damit ihr versteht was ich da genau vor augen habe versuche ich es grob zu beschreiben.

Das Raspberry Pi dient als log server welches daten verarbeitet und speichert (welches protokol ist mir in erster linie egal )
das ESP32 steuert das Arduino mega und holt sich von dort auch die sensor daten um diese gegebenenfalls (bei höchst werten zb) direkt weiter zu verarbeiten und zum raspberry pi schickt.
ich hätte gerne eine web oberfläche (ESPeasy habe ich gute erfahrungen gemacht) von denen ich aus die parameter fürs terrarium aktualisieren/anpassen kann.

mein problem ist in erster linie die verbindung, welche methode ist die geeigneste ? und dann wie wird diese programmiert und verkabelt ?

mir ist bewusst das es für meine anwendung möglich wäre nur das esp zu nutzen was vieles vereinfachen würde aber ich habe mir diese methode ausgewählt weil ich die pins (am mega und auch eventuell am ESP) die übrig sind in zukunft bestimmt noch gebrauchen werde da ich für dieses projekt noch einige erweiterungs pläne habe.

ich hoffe ihr könnt mir helfen, vielen dank
mfg
olla59

Einen Vorschlag hätte ich...
Über I2C !?!?
Der ESP als Master, denn er ist erheblich leistungsfähiger.

habe ich auch schon dran gedacht, hast du da eine anleitung für mich ?

Sowohl Arduino, als auch ESP bringen eine Wire Doku mit.
Sogar mit gut funktionierenden Beispielen.
Da solltest du anfangen! (würde ich mal sagen)

wo finde ich die ? :smiley:

https://docs.espressif.com/projects/arduino-esp32/en/latest/api/i2c.html

Übrigens:
Du wirst einen I2C Levelshifter benötigen

Wozu brauchst Du einen PIR und Magnetkontakte?
Die Relaismodule sind größtenteils für 230V AC nicht geeignet.
Der IRF520 ist ungeeignet da die 5V des Arduino ihn nicht 100% durchschalten. Verwende einen Logic Level MOSFET wie zB den IRLZ44.
Für welche Tiere soll das Terrarium sein?
Denke an Sicherheitstermostate die die Heizung bei Ausfall der regelung abschalten bevor die Tiere sterben.

ESP:
Auch RXTX wäre möglich. in beiden Fällen (RXTX oder I2C) ist eine Pegelwandlung notwendig.

Grüße Uwe

vielen dank,schau ich mir direkt an.

Ich habe bartagame(trockenterrarium)
die magnetkontakte werden an die scheiben angebracht der PIR nach aussen gerichtet über die scheiben umzuerkennen ob sich während eine oder beide scheiben offen sind noch jemand in der nähe befindet.
falls das nach einem bestimmten zeitraum nicht mehr der fall ist soll ein alarm geschaltet werden.
in der vergangenheit ist es mal vorgekommen das man diese nicht ganz zu gemacht hat und eine bartagame abhauen konnte (raum ist so weit es geht Bartagamen sicher) und bei meinem alten terrarium habe ich auch schon beobachtet das eins der tiere die scheibe ein paar cm auf gekriegt hat.

eine heizung ist in dem sinne nicht vorhanden, ich habe dort HQI´s (1x 150W, 1x 70W) und Halogen strahler diese wollte ich über das programm schalten lassen und gegebenen falls bei überhitzung abschalten. eventuell wollte ich noch eine aktive lüftung einbauen mit einem rohrventilator der im ernstfall die warme luft absaugt.

das mosfet ist derzeit nur eingeplant für einen 12V lüfter der das gehäuse der steuerung lüftet. meine ersten versuchsaufbauten (nur mit lüfter,mosfet und arduino) haben problem los funktioniert deshalb glaube ich das dieses modul ausreichend ist. später wollte ich damit ein T5HO vorschaltgerät dimmen bzw das 1-10V signal regeln um zu dimmen.

RXTX ? Das ist UART oder ? die pegelumwandlung habe ich schon gesehen und die schaltung irgendwo gespeichert.

ich konnte bisher (in einzelnen,getrennten versuchen) erreichen das ich alle aktoren über den seriellen monitor auslesen und ansteuern konnte. ist das nicht das protokoll welches ich auch bei TX RX benutzen würde ?

achso die relais, ich habe eins von ELEGOO welches wohl für 230V ausreicht,hat in kleinen versuchen auch gut funktioniert. ich habe hier ja keine induktiven lasten. glaube ich zumindest.
andere dieser marke habe ich für kleinere projekte im gebraucht. für 230v und weniger.

Ich gehöre zur Fraktion "keep it simple" und würde versuchen alles nur mit dem ESP32 zu machen. Wenn du dir mal zu deiner Liste einfach die Pins dazuschreibst, dann siehst du ob es mit Pins wirklich knapp werden würde.

Sollte wirklich weitere Pins benötigt werden
a) nimm statt dem Mega echte I2C Portexpander dazu, die brauchst nur ansteuern und du brauchst keine Software für die Slave Seite schreiben.
b) nimm statt dem ESP32 D1 R32 ein Modul mit mehr rausgeführten Pins. Das ist nur ein Beispiel

Jede Minute die du dir für die Mega Programmierung sparst kannst du in die Verbesserung der ESP Software investieren.

  • I²C: SCL mit SCL und SDA mit SDA über Levelshifter miteinander verbinden. Der Mega2560 hat 10 kΩ PullUp-Widerstände drauf, sind also nicht extra notwendig.
  • UART: U2-RX mit TX2 und U2-TX mit RX2 über Levelshifter verbinden.

Für was man sich entscheidet, hängt von den eigenen Erfahrungen ab. Ich würde Datenstrukturen per I²C übertragen und dies als den einfacheren Weg ansehen. UART erscheint zunächst transparenter, weil man direkt sieht, was verschickt wird, dafür muß man sich selbst ein Protokoll ausdenken.

Ich nutze die Tabs von Fips, eventuell hilft Dir meine Anleitung: Einführung zu fipsok.de.

Der Rest, den ich geschrieben hätte, steht in #11 :slightly_smiling_face:

Wenn ich sehe, wie groß das Versagen (die Schwierigkeiten) hier im Forum sind, sehe ich dabei massive Probleme, Zudem hängen da offensichtlich Leben dran.

Und wenn doch UART, dann empfehle ich den den CmdMessenger

1 Like

Rechtlich betrachtet sind Bartagamen nur Sachen, die man zwar nicht quälen darf, die sonst aber wenig geschützt sind.

Wer solche Tiere hält, sollte sie aber über den rechtlichen Rahmen hinaus lieben und seiner Verantwortung mehr als gerecht werden. Das setze ich als selbstverständlich voraus :slightly_smiling_face:

Daher sollten Sicherheiten eingebaut und auch ausgiebig getestet werden. Aus eigener Erfahrung weiß ich, man kann nicht so dumm denken, wie es kommen kann :flushed: :thinking:

An I²C könnten beim Mega2560 auch Sensoren als Slaves dranhängen, da stellt sich die Frage, wer Master sein soll. Wenn es der ESP32 sein soll, dann könnte der auch gleich die Meßwerte lesen und verarbeiten. Oder muß der ESP32 die Meßwerte an den Mega2560 schicken, damit dann da was passiert. Oder doch den Mega2560 als Master, damit der die Initiative ergreifen kann?


Ergänzung 20220301 15:17:

Der ESP32 möchte mit Core 1.0.6 kein Slave sein, mit Core 2.0.1 funktioniert es hingegen. Wenn man in den IDE-Voreinstellungen bei "Zusätzliche Boardverwalter-URLs" "https://dl.espressif.com/dl/package_esp32_index.json" durch "https://github.com/espressif/arduino-esp32/releases/download/2.0.1/package_esp32_index.json" ersetzt, wird im Boardverwalter nach Suche von "ESP32" auch Core 2.0.1 angeboten.

Mega2560 als I2C-MASTER

#include <Wire.h>

const byte SLAVEADDRESS = 8;

const byte BYTEZAHL = 2 * sizeof(int);
union {
  byte bytes[BYTEZAHL];
  struct {
    uint16_t Wert_1;
    uint16_t Wert_2;
  };
} tx;

void loop()
{
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  if (jetzt - vorhin >= 1000)
  {
    vorhin = jetzt;
    tx.Wert_1 = random(150, 300);
    tx.Wert_2 = random(0, 1000);
    Wire.beginTransmission(SLAVEADDRESS);
    Wire.write(tx.bytes, sizeof(tx));
    Wire.endTransmission();
    Serial.print(F("\ttx.Wert_1: ")); Serial.print(tx.Wert_1); Serial.print(F("\ttx.Wert_2: ")); Serial.println(tx.Wert_2);
  }
}

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  //Wire.setClock(400000L); //setzt die I²C Taktfrequenz auf 400kHz
  delay(1000);
  Serial.println(F("\nStart"));
  Serial.print(F("BYTEZAHL Byte für int: ")); Serial.println(sizeof(int));
}

ESP32 als I2C-SLAVE

#include <Wire.h>
const byte SLAVEADDRESS = 8;
const byte BYTEZAHL = 4;
union {
  byte bytes[BYTEZAHL];
  struct {
    int16_t Wert_1;
    int16_t Wert_2;
  };
} rx;

volatile int32_t rxWert_1 = 0;
volatile int32_t rxWert_2 = 0;
bool neu = false;

void setup()
{
  Wire.begin(SLAVEADDRESS);
  Wire.onReceive(receiveEvent);
  Serial.begin(115200);
  Serial.println(F("\nStart"));
}

void receiveEvent(int numBytes)
{
  if (BYTEZAHL == numBytes)
  {
    for (byte j = 0; j < numBytes; j++)
    {
      rx.bytes[j] = Wire.read();
    }
    rxWert_1 = rx.Wert_1;
    rxWert_2 = rx.Wert_2;
    neu = true;
  }
}

void loop()
{
  if (neu)
  {
    neu = false;
    for (byte j = 0; j < BYTEZAHL; j++)
    {
      Serial.print(rx.bytes[j], HEX); Serial.print(' ');
    }
    Serial.print(F("\trxWert_1: ")); Serial.print(rxWert_1); Serial.print(F("\trxWert_2: ")); Serial.println(rxWert_2);
  }
}

Anzeige Mega2560:

tx.Wert_1: 193	tx.Wert_2: 427
tx.Wert_1: 182	tx.Wert_2: 444
tx.Wert_1: 241	tx.Wert_2: 198
tx.Wert_1: 152	tx.Wert_2: 856

Anzeige ESP32:

C1 0 AB 1 	rxWert_1: 193	rxWert_2: 427
B6 0 BC 1 	rxWert_1: 182	rxWert_2: 444
F1 0 C6 0 	rxWert_1: 241	rxWert_2: 198
98 0 58 3 	rxWert_1: 152	rxWert_2: 856

Ergänzung 20220301 16:46:

Mega2560 als UART-Sender

uint16_t wert_1;
uint16_t wert_2;

void loop()
{
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  if (jetzt - vorhin >= 1000)
  {
    vorhin = jetzt;
    wert_1 = random(150, 300);
    wert_2 = random(0, 1000);
    char buf[100] = {"\0"};
    snprintf(buf, sizeof(buf), "W1:%u;W2:%u\n", wert_1, wert_2);
    Serial2.print(buf);
    Serial.print(buf);
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println(F("\nStart"));
  Serial2.begin(9600);
}

ESP32 als UART-Empfänger

const unsigned int READ_BUFFER_SIZE = 100;  // an die Bedürfnisse anpassen!

char * readLine(Stream& stream) {
  static byte index;
  static char buffer[READ_BUFFER_SIZE];
  while (stream.available()) {
    char c = stream.read();
    if (c == '\n') {         //wenn LF eingelesen
      buffer[index] = '\0';  //String terminieren
      index = 0;
      return buffer;         //melden dass String fertig eingelesen wurde
    }
    else if (c >= 32 && index < READ_BUFFER_SIZE - 1) {  //solange noch Platz im Puffer ist
      buffer[index++] = c;    //Zeichen abspeichern und Index inkrementieren
    }
  }
  return nullptr;           //noch nicht fertig
}

void loop()
{
  int16_t wert_1 = 0;
  int16_t wert_2 = 0;
  char * eingabe = readLine(Serial2);
  if ( nullptr != eingabe )
  {
    Serial.println(eingabe);
    if ( 1 < sscanf ( eingabe, "W1:%u;W2:%u", &wert_1, &wert_2 ))
    {
      char buf[READ_BUFFER_SIZE] = {"\0"};
      snprintf( buf, sizeof(buf), "Wert 1: %u\tWert 2: %u", wert_1, wert_2 );
      Serial.println(buf);
    }
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println(F("\nStart"));
  Serial2.begin(9600);
}

Ausgabe Mega2560:

16:48:49.431 -> W1:251;W2:285
16:48:50.434 -> W1:171;W2:526
16:48:51.390 -> W1:222;W2:63
16:48:52.394 -> W1:174;W2:806

Ausgabe ESP32:

16:48:49.431 -> W1:251;W2:285
16:48:49.431 -> Wert 1: 251	Wert 2: 285
16:48:50.434 -> W1:171;W2:526
16:48:50.434 -> Wert 1: 171	Wert 2: 526
16:48:51.437 -> W1:222;W2:63
16:48:51.437 -> Wert 1: 222	Wert 2: 63
16:48:52.441 -> W1:174;W2:806
16:48:52.441 -> Wert 1: 174	Wert 2: 806

Nun hast Du die Qual der Wahl :sweat_smile:

Ich finde, Deine Bartagamen haben sich ein extra Leckerli verdient :green_salad:

Ob's funktioniert oder Normgerecht gebaut mit Sicherheitsabständen und genügend Leiterquerschnitte für den Strom und relativer Zertifizierung sind 2 total verschiedene Sachen.

Außerden fand ich: auf https://www.rieste.com/blog/hqi-strahler/
"HQI Strahler mit Metalldampflampen haben den schon erwähnten Vorteil der geringen Betriebskosten. Als Kompromiss haben Metalldampflampen eine gewisse Aufwärmphase vor sich um die volle Helligkeit zu erreichen. Diese Aufwärmphase ermöglicht nicht den Betrieb mit Bewegungsmeldern, was für viele Menschen ein umdenken in der Handhabung darstellt."

Hab jetzt nicht verstanden wieso das sein soll, aber wollte es Dir zu bedenken für weitere Recherchen geben.
Welche Einschaltcharakteristik die HQI's haben weiß ich nicht. Die Halogenstrahler haben im einschaltmoment einen Kleinen Widerstand und darum einen Hohen Stromfluß, was Relaiskontakten nicht gerade gut tut.

Lampen

nunja :smiley: ich möchte dafür definitiv den mega 2560 nutzen da dieser unteranderen 5V liefert und auch damit klar kommt (wichtig für die langen kabel der temperatursensoren,diese kann ich nicht so verlegen das ich bei jedem kabel die 1m mit 3,3V nicht überschreite und gleichzeitig von den doch sehr warmen bereichen in und um das terrarium fernhalte.)
die erweiterungsmöglichkeiten die ich von haus aus mit dem mega habe macht es eigentlich perfekt für dieses projekt.
ich verstehe aufjedenfall was du meinst möchte jetzt aber bis auf einen levelshifter (den ich mit wiederständen vorrüber gehend ersetzen würde) mit dem klar kommen was ich mir da ausgesucht und bestellt habe :smiley:

ich habe relativ wenig erfahrung mit den arduino boards,habe mich etwas mit den raspberry pi´s beschäftigt womit ich auch mittlerweile gut klar komme.
ich bin nur auf das arduino board gekommen weil es "zuverlässiger" ist als das raspberry.
einfach schon weil da viel mehr programme fehler produzieren könnten.
da es in meinem fall um tiere geht ist es einfach die sicherere wahl.

welche methode ist eigentlich egal, für mich ist nur wichtig das ich es auch geschrieben kriege. ich hab mir zu beiden methoden schon etliche videos angeguckt aber keins gefunden um diese wirklich zu verstehen(auch weil es für diese kombination aus mega 2560 und esp32 kaum beispiele gibt.. gelesen habe ich auch viel aber wie ich schon sagte nichts gefunden was mir verständlich macht wie dies funktioniert (ich glaube es sind grundlegende dinge die einfach nicht erklärt werden die mir dann fehlen um die zusammenhänge zuverstehen)

Im grunde ist eine weboberfläche gar nicht nötig da ich sowieso ein raspberry pi im netzwerk habe welches die weboberfläche hosten könnte(was viel einfacher zu programmieren ist) dafür müsste ich die Sensor daten usw dann eigentlich nur per mqtt oder so auf das raspberry pi bekommen (was sowieso passieren sollte da ich diese dort auf lange sicht loggen will)

ich glaube mein problem ist nicht die verbindung aufzubauen, oder signale zu senden oder zu empfangen, sondern eher wie ich die nachrichten verarbeite und zuordne.
zb was sagt das esp zum mega um relaisXY einzuschalten :smiley:

ich hatte nie vor die HQI´s mit bewegungsmeldern zu verbinden :smiley:
der bewegungsmelder soll nur sobald eine scheibe geöffnet wurde nach einer gewissen zeit ohne bewegung vor dem terrarium eine erinnerung/einen alarm auslösen :smiley: und eventuell auch loggen das die tür geöffnet wurde

I²C oder UART?