PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : nodeMCU an Arduino



Moppi
17.08.2018, 07:09
Ich denke gerade über Möglichkeiten nach und frage daher mal, vielleicht hat jemand Erfahrung was geht und was nicht geht. :confused:

1) Geräte wie nodeMCU mit Arduino über RX/TX verbinden?
2) Analog Ein/Ausgänge unterschiedlicher Boards verbinden?
3) Digital Ein/Ausgänge unterschiedlicher Boards verbinden?

Wenn man diese 3 Möglichkeiten betrachtet, was müsste man jeweils beachten, damit nichts kaputt geht?

Grüße

Ceos
17.08.2018, 07:21
Grundsätzlich darauf achten dass man Boards gleicher Spannung verwendet und mit mindestens gemeinsamer Masse verbindet, besser auch mit der gleichen Versorgung

zu 3. kann man einfach einen Widerstand dazwischen hängen. Klein genug damit evtl. verwndete PullUp oder PullDown auch sauber bedient werden und groß genug damit im Falle eines direkten Kurzschluss nicht mehr Strom fließt als die Pins/Port verkraften können. ein 5k bei 5V oder ein 3.3k bei 3.3V und man ist mit 1mA Kurzschlusstrom absolut sicher, solange die Pull UP/DOWN nicht zu klein sind, ansonsten einfach mal in das Datenblatt der Controller schauen was sie verkraften und den R etwas kleiner wählen.

Bei Analog fehlt mir die Erfahrung aber es gibt wohl auch je nach Einstellung Eingänge die einem zu viel Spannung übel nehmen.

Es gibt auch Controller die 5V tolerant sind und mit 5V Pegel trotz 3.3V Versorgung angesprochen werden können ohne schaden zu nehmen.

Bei RX/TX würde ich wie bei GPIO einfach einen Widerstand dazwischen hängen für maximale Sicherheit :)

Moppi
17.08.2018, 07:33
Ja, so in etwa ging mir das auch durch Kopf. Bei TTLs habe ich zur Not dann Optokoppler genommen, bei Digitalen Ein/Ausgängen. Aber ich denke, das muss nicht unbedingt sein. Gleiche Spannungsversorgung vorausgesetzt. Sonst kann man die Pins ja noch messen, was dort anliegt. Aber RX/TX sollte doch funktionieren, wenn man es direkt verbindet?

So weit ich gesehen habe, arbeitet nodeMCU ja nur mit 3.3V. Aber Arduino mit 5V.

Ceos
17.08.2018, 07:41
es gibt Arduino Klone mit variierender Spanung, daher die Warnung

wegen RX/TX, das ist nichts weiter als ein Schaltpin wie die GPIOs nur dass dahinter ein wenig Logik steckt die ungestört arbeitet während dein Programm die CPU beansprucht. Also würde ich da einfach die gleichen Sicherheitsmaßnahmen treffen, falls du beim verkabeln mal was vertauschst oder ein Programm den Pin unter bestimmten Umständen vll. anders bedient als du das erwartest.

Dass du den TX des einen an den RX des anderen und umgekehrt anschließen musst ist dir aber bewusst?

Nur weil RX auf dem Pins steht bedeutet das übrigens nicht dass der auch mal auf Ausgang als GPIO stehen kann :)

Moppi
17.08.2018, 08:36
Danke für die Hinweise! RX/TX über Kreuz war klar, ja.

Moppi
15.09.2018, 09:23
Der Vollständigkeit halber habe ich das heute mal ausprobiert.

Wenn der Arduino Uno mit 3.3V betrieben wird, sollte er als LOW-Pegel 0V und als HIGH-Pegel 3.3V liefern.
Wenn der Arduino Uno mit 5V betrieben wird, liefert er als LOW-Pegel 0V und als HIGH-Pegel 5V.

Das nodeMCU liefert als LOW-Pegel 0V und als HIGH-Pegel 3.3V.

Die Ausgänge des nodeMCU passen vom Pegel zum Arduino Uno. So dass man von einem nodeMCU-Ausgang direkt auf einen Arduino-Eingang gehen kann.
Sollte der Arduino 5V-HIGH-Pegel liefern, hilft ein 732kOhm Widerstand zwischen Ausgang des Arduino und Eingang des nodeMCU. Mit den ca. 730kOhm werden die 5V auf ca. 2.8V reduziert, womit das nodeMCU gut zurecht kommt.
820kOhm Widerstand wäre etwas gängiger in der Größe und müsste auch noch funktionieren, um einen High-Pegel über 2.4V sicherzustellen, allerdings dann als Metallschichtausführung. 680kOhm wären etwas zu wenig, wenn das nodeMCU nicht mehr als 3.3V am Eingang verträgt.

Ceos
15.09.2018, 13:17
Mit den ca. 730kOhm werden die 5V auf ca. 2.8V

kannst du mir das mal erläutern?

Angenommen du meinst R = U / I ... dann müsste bei U 5-2,8V / R 730k = 0,003mA Strom fließen

Angenommen der TX Ausgang wäre 5V, der RX Eingang des Empfängers ist aber undefiniert hoch, denn es ist ein Eingang, da fließt (eigentlich) kein Strom! Bestenfalls fließt Strom über Schutzdioden ab aber die sollte man am besten garnicht erst dazu bringen überhaupt durchzuschalten.

Was du meinst wäre vermutlich ein Spannungsteiler von 5V TX auf 3.3V RX, das wäre besser berechenbar.
Für die andere Richtung von 3.3V TX auf 5V RX würde ich das Risiko eingehen und einfach direkt anschließen, denn die meisten 5V Eingänge erkennen ab 2.7V einen High Pegel, im schlimmsten Fall empfängst du halt nichts, dann müsste man über eine Lösung dafür nachdenken aber ich bin sicher dass es funktioniert.

Moppi
15.09.2018, 14:35
Ceos, ich habe es ausprobiert :-) Am einem Ausgang des Arduino Uno verschiedene Widerstände angeschlossen und durchgemessen, nachdem der Ausgang auf High geschaltet war. Ich weiß, dass dort kaum ein Strom fließt, das ist auch gut so. Das nodeMCU benötigt an den Eingängen offenbar nur die Spannung, keine Leistung. Um über einen Widerstand die Spannung zu reduzieren, muss dieser sehr groß gewählt sein, in Folge fließt kaum mehr ein Strom. Deshalb, wenn man Stromfluss benötigt, setzt man auch Spannungsteiler ein. Also, hier ging es mir primär um die Frage, was man an das nodeMCU anschließen kann, wie man Pegel transportiert und diese möglichst einfach anpassen kann. Das nodeMCU "misst" an einem digitalen Eingang die Spannung, geht die auf LOW-Pegel, schaltet der Eingang auf LOW um und bleibt auch auf LOW, selbst wenn man an dem Pin nichts mehr anschließt oder die Verbindung trennt. Erkennt der Eingang ein HIGH (>2.4V), dann kippt er auf HIGH um und bleibt auf HIGH. Das bezieht sich auf die digitalen Ein-/Ausgänge (nodeMCU D1 + D2, GPIO4 + CPIO5, normale I/O Pins). Manche Eingänge haben auch einen Pull-Up oder Pull-Down-Widerstand auf dem Board verbaut. TX und RX ist wieder etwas anders: TxD (GPIO1): Serieller Ausgang des ESP über 470Ω mit dem USB-UART verbunden, RxD (GPIO3) Serieller Eingang des ESP über 470Ω mit dem USB-UART verbunden.

Nun gibt es verschiedene Ausführungen, hier die, die ich verwende:

33637

Ceos
16.09.2018, 08:42
Um über einen Widerstand die Spannung zu reduzieren, muss dieser sehr groß gewählt sein, in Folge fließt kaum mehr ein Strom

worauf ich hinaus wollte, war dass ein Widerstand bei undefinierter Stromaufnahme (und das ist sogar von hergestelltem Chip zu Chip unterschiedlich wieviel Leckstrom dort herrscht) nichts bewirkt sondern eher unerwartete Störungen produziert, ein Spannungsteiler ist definitiv die bessere Lösung.

Was du beschreibst ist ungefähr so als würdest du sagen, wenn ich mit einem Vorschlaghammer gegen eine Rohrleitung schlage, wird einem nach 730km nichts passieren wenn man sein Ohr direkt an die Leitung legt ... das kann stimmen, muss aber nciht, kommt drauf an wie die Leitung verlegt ist und wie gut sie dämpft ... aber es kann dir auch mal das Trommelfell zerreißen.

Wenn ich jetzt einen definierten Strom über einen Spannungsteiler nach GND fließen lasse kann ich genau einstellen wie stark die Spannung abfällt egal ob der Chip einen Leckstrom vom 3uA, 100uA poder nur 0.5uA hat.

Als Gesamtwiderstand wären 5V / 500uA = 10kOhm wohl Sinnvoll und das Verhältnis wäre dann 2/3, da der Leckstrom selten >50uA wird und somit nur maximal 10% Einfluss auf den Gesamtstrom und die Genauigkeit deines Spannungsteilers hat.

also 5V TX -> 4kOhm -> 3.3V RX + 6kOhm -> GND

Moppi
16.09.2018, 11:05
Hier erst meine 1-Wire-Lösung (mit 220k- und 470kOhm-Widerstand). Damit kann der Arduino Daten zum nodeMCU schicken:

Ausgabe vom nodeMCU serial port:

Hello, world: 275!
Hello, world: 276!
Hello, world: 277!
Hello, world: 278!
Hello, world: 279!
Hello, world: 280!
Hello, world: 281!
Hello, world: 282!
Hello, world: 283!
Hello, world: 284!


meine Beschaltung:
33641

Code fürs nodeMCU:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 5); // RX, TX

void setup() {

// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {}

// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
}

void loop() { // run over and over
if (mySerial.available()) {
Serial.write(mySerial.read());
}
}


und Code für Arduino:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(3, 2); // RX, TX
int a;

void setup() {
// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
}

void loop() { // run over and over
delay(3000);
a++;
mySerial.print("Hello, world: ");
mySerial.print(a);
mySerial.println("!");
}




Nun muss es auch vom nodeMCU zum Arduino funktionieren, Daten zu übertragen

Deshalb die Software auf den Geräten vertauscht und eine zweite Leitung, vom nodeMCU zum Arduino, hinzugefügt:
33642

Ausgabe vom Arduino serial port:

Hello, world: 77!
Hello, world: 78!
Hello, world: 79!


Code für nodeMCU:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 5); // RX, TX for nodeMCU
//SoftwareSerial mySerial(3, 2); // RX, TX for Arduino

int a;

void setup() {
// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
}

void loop() { // run over and over
delay(3000);
a++;
mySerial.print("Hello, world: ");
mySerial.print(a);
mySerial.println("!");
}


Code für Arduino:

#include <SoftwareSerial.h>

//SoftwareSerial mySerial(4, 5); // RX, TX for nodeMCU
SoftwareSerial mySerial(3, 2); // RX, TX for Arduino

void setup() {

// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {}

// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
}

void loop() { // run over and over
if (mySerial.available()) {
Serial.write(mySerial.read());
}
}


Funktioniert die Kommunikation nach den vorherigen Voraussetzungen auch per RX + TX - Pins

Das musste ich auch noch wissen. Beide Verbindungskabel habe ich umgesteckt, so dass jetzt RX und TX vom Arduino genutzt werden können:

33643

Die Pins am nodeMCU bleiben dieselben, an der Beschaltung hat sich dort nichts verändert.

Damit ich die Verbindung hin und zurück testen kann, muss der Arduino nun Daten auf dem seriellen Port lesen und wieder ausgeben. Das nodeMCU schickt die Daten und wartet, bis sie zurückkommen.

geänderter Code für Arduino:

//#include <SoftwareSerial.h>

//SoftwareSerial mySerial(4, 5); // RX, TX for nodeMCU
//SoftwareSerial mySerial(3, 2); // RX, TX for Arduino

void setup() {
// set the data rate for the SoftwareSerial port
//mySerial.begin(4800);

//der Arduino arbeitet nur noch über die norm. serielle Schnittstelle
//die wir hier zur Kommunikation öffnen
Serial.begin(4800);
//und dann warten wir, bis das geklappt hat
while (!Serial) {}
}

void loop() { // run over and over
//der Arduino soll Daten vom nodeMCU empfangen und zurück schicken
//deshalb schauen wir, ob was angekommen ist
//und wenn, dann lesen wir das und schicken es zurück
while(Serial.available()){
Serial.write(Serial.read());
}
}


geänderter Code für nodeMCU:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 5); // RX, TX for nodeMCU
//SoftwareSerial mySerial(3, 2); // RX, TX for Arduino

int a;

void setup() {

// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {}
Serial.println();

// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
}

void loop() { // run over and over
// Kontrollzähler
a++;
//nodeMCU verwendet hier andere Pins statt der echten RX, TX
//weil die ser. Schnittstelle zur Ausgabe genutzt wird
//deshalb Senden über Software Serial Port zum Arduino
mySerial.print("Hello, world: ");
mySerial.print(a);
mySerial.println("!");

//Arduino wird das empfangen und zurückschicken
//deshalb warten wir mal kurz, bis was zurück kommt
while(mySerial.available()==0){
delay(1000);
Serial.print("."); //Zeigen, dass gewartet wird
mySerial.print("."); //falls Verbindung getrennt wird, um aus der Schleife auszubrechen
}

//Schauen, ob auf dem Software Serial Port etwas angekommen ist
//wenn ja, dann wird das eingelesen und zur Kontrolle ausgegeben
//auf dem norm. seriellen Port
while(mySerial.available()){ //solange Zeichen verfügbar
char c=mySerial.read(); //ein Zeichen lesen
Serial.print(c); //Zeichen ausgeben
}

}


Und nach etwas Fummelei funktioniert auch das, die Ausgabe vom nodeMCU serial port:

Hello, world: 16030!
Hello, world: 16031!
Hello, world: 16032!
Hello, world: 16033!
Hello, world: 16034!
Hello, world: 16035!
Hello, world: 16036!
Hello, world: 16037!
Hello, world: 16038!
Hello, world: 16.....................

HaWe
16.09.2018, 12:32
also geht es jetzt in beien Richtungen? auch gleichzeitig (voll-duplex) oder per Handshake, abwechselnd?

(Ist aber sicher kein 1-Wire, das ist ein eigenes Protokoll, sondern Arduino-Serial = UART, eben einfache oder doppelte Richtung)

Moppi
16.09.2018, 12:55
also 5V TX -> 4kOhm -> 3.3V RX + 6kOhm -> GND

Der Spannungsteiler funktioniert ebenfalls. Wie sieht es damit aus, wenn Eingänge am nodeMCU schon mit einem Pull-Up- oder Pull-Down-Widerstand versehen sind? Diese Widerstände müssten sicherlich eingerechnet werden.

Ceos
17.09.2018, 06:47
ja klar, wenn da irgendwelche Beschaltung mit am Pin ist muss man das mit einrechnen ;)

Moppi
17.09.2018, 07:28
Zum Abschluss, zusammenfassend:

1. nodeMCU: Ausgang Low = 0V, Ausgang High = 3.3V
2. Arduno Uno: Ausgang Low = 0V, Ausgang High = 5V

3. Möglichkeiten Pegelanpassung von einem Arduino-Ausgang zum nodeMCU-Eingang:
einfacher Widerstand ca. 680kOhm bis 800kOhm, Spannungsteiler (vom Ausgang über ca. 4kOhm (4.7k) zum Eingang, von dort mit ca. 6kOhm (6.2k) gegen Ground), richtiger Pegelwandler.

Die Pegelanpassung vom nodeMCU zum Arduino ist nicht notwendig. Bei der Pegelanpassung vom Arduino zum nodeMCU, über Wiederstände, kann es zur Signalverfälschung kommen. Insbesondere Spannungsteiler geben Rechtecksignale nicht sauber weiter, das Signal gleicht dann eher einem abgerundeten Sägezahn. Das nodeMCU ist hier aber unempfindlich an den Eingängen, diese zeigen nach außen das Verhalten einer bistabilen Kippstufe, die den Zustand bei Überschreiten der Low- oder High-Spannungsgrenze ändert. Insofern nodeMCU-Pins bereits mit Widerständen beschaltet sind (in techn. Dokumentation nachschauen), sollte man das bei der Berechnung eines äußeren Spannungsteilers berücksichtigen. Die Möglichkeit, echte elektronische Pegelwandler einzusetzen, ist sicher die Sauberste, aber bei Verwendung von Fertigmodulen für Arduino etc. auch die kostspieligste Variante. Pegelwandler können dann sinnvoll sein, wenn man Logiksignale absolut sauber weitergeben muss, wie schnellere Taktsignale.

4. Serielle Kommunikation: Verbindung der Boards über normale Digital-I/O-Pins, dann mit SoftwareSerial.h.
5. Serielle Kommunikation: Verbindung der Boards über RX/TX-Pins, dann ohne SoftwareSerial.h unter Nutzung der normalen seriellen Schnittstelle, Pegelanpassung wie oben beschrieben möglich.

Die serielle Kommunikation ist mit einer Verbindung sowohl vom Arduino zum nodeMCU, als auch vom nodeMCU zum Arduino möglich. Oder beides, falls notwendig. Wird nur die Verbindung in eine Richtung hergestellt, kann auch nur in diese Richtung gesendet werden.

oberallgeier
17.09.2018, 07:46
.. Eingänge am nodeMCU schon mit einem Pull-Up- oder Pull-Down-Widerstand versehen sind? Diese Widerstände müssten sicherlich eingerechnet werden.Ergänzung/Anregung zu Ceos´ Beitrag:
Die Frage hatte ich mir auch mal gestellt und Klärung bringt das Datenblatt. ABER beim - beispielsweise - mega328p stehen im Datenblatt unter [Common DC Characteristics .. I/O Pin Pull-up Resistor] Werte von 20 kΩ Min. und 50 kΩ Max. Ähhhhh - und was nehme ich dann? (Anm.: ich bin manchmal recht pingelig, auch neugierig)

Ich hatte bei meinem Controller das DMM genommen und einen Pin als Eingang mit PullUp konfiguriert. Ergebnis (grad nochmal am nano-Clone gemessen) a) Spannung ist 5,01 V, Kurzschlussstrom ist 14 mA. *gg* Not bad - die 35,8 k sind ja fast haarscharf die Mitte! Bei DEM GEMESSENEN Pin!

Ceos
17.09.2018, 08:00
die internen Pull-Ups sind absolute Schätzeisen und nur da um dir für I2C oder andere LowActive High Impedance Signale den externen PullUp zu schenken :D

Da UART aber PushPull macht, kannst du darauf gut verzichten.

Das Erlebnis mit den Sägezähnen sollte bei Push Pull ebenfalls extrem minimal ins Gewischt fallen (Am Oszi mag man eine minimale Verscheleifung sehen aber sonst sollte das keinen Einfluss haben)

Was Pegelwandler angeht, ich habe hier einen ganz simplen Chip, einen 74HCT132E, das ist ein 4 NAND-Gate mit Schmitt Trigger Eingängen. So kann man zumindest sauber und in deutlich höherer Frequenz im Vergleich zu einer Transistorstufe von 3V auf 5V umsetzen ohne Verschleifung (Ich habe es mit einem Oszilloskop vermessen und treibe die Daten-/Clockleitung meiner 5V APA102 @4MHz von einem ATXMega bei 3.3V aus an, dank der 2 Extra Gates sogar mit Enable und ohne Invertierung)

Chips aus der 74er Reihe mit Schmitttriggern gibt es viele und vielleicht auch Varianten mit 2 Richtungen bzw. Spannungsstufen, die kosten i.d.R. auch nicht viel und gibt es meist sogar noch im Breadboard freundlichem PDIP Gehäuse

Moppi
14.10.2018, 09:30
Doch noch nicht Ende.

Auf der Suche nach Schnittstellen tun sich noch Möglichkeiten auf, das nodeMCU direkt mit dem Arduino/Atmega zu verbinden. Das nodeMCU-Board kann mit 3.3V versorgt werden und die IOs können direkt verbunden werden:

33706

Verbunden über die SPI-Schnittstelle. Ich fand einen Beitrag dazu im Netz. Leider ist dann mein Rechner runtergefahren, weil ich das nodeMCU mit der Versorgung falsch angeschlossen habe und alles am USB angeschlossen war, deshalb keine Quelle an dieser Stelle. Dort kam auch die Frage nach dem 3.3V-Logikpegel, mit der Antwort, der 8266 sei gegenüber 5V an den Eingängen tolerant und würde dadurch nicht zerstört.
Vielleicht ist es aber doch besser, dann den Atmega auch mit 3.3V zu betreiben.

-----------------------------------------------------------------------------------

Dazu noch mal ein Nachtrag von mir:

Also das Datenblatt gibt es nicht her, es ist auch bekannt, dass dort nur 3.3V stehen, die man als Input an einem nodeMCU anlegen soll. Allerdings sollen Schutzdioden vorhanden sein, die nur nicht überlastet werden dürfen. Hierzu mal folgender Text eines Users:

"It is true, and the data sheet even eludes to the fact, that the GPIO are 5V tolerant but here's the rub. The pins have protection clamping diodes on the pins that protect the circuitry from over voltage. The problem is that they usually can only take 20-25ma of current. If you want to use these pins with 5V it is best to include a series resistor. This technique has been used many times in some uncomfortably puckering situations. One ap-note I read from Atmel many years ago used an AVR input pin to sense the AC line directly to get the mains line frequency as a time base for a digital clock. They actually put a several meg ohm resistor on one of the I/O lines and plugged it into the wall!! On that processor The current was limited to 25ma max so as long as the series resistor limited the current to less than 25 ma all was fine.
I use a similar technique on my ESP designs to interface the 5V 315mhz receivers to the ESP8266. I run everything through 10K ohm resistors and it all works happy."

Quelle: http://www.letscontrolit.com/forum/viewtopic.php?t=1882

Sieht so aus, dass eine Widerstandsbeschaltung am Eingang durchaus praktikabel ist. Das hatten wir hier ja schon woanders durch, wo dann auch Widerstandsnetzwerke als Vorschlag kamen. Sicherer wird es wohl sein, zumindest einen Vorwiderstand an den IOs des nodeMCU zwischen zu schalten, wenn einem das dann doch zu heiß ist, direkt 5V-Signale an die Eingänge zu legen.


MfG
Moppi





PS: Danke @Searcher, der mich auf die SPI-Schnittstelle aufmerksam machte!