NodeMCU
Allgemeines
Nachdem ich mit den ESP8266-Basismodulen (ESP-01(S)) ein wenig gespielt habe, probiere ich heute mal eine NodeMCU.
Die NodeMCU ist eigentlich nichts anderes als ein Breakout-Board für ein ESP-12(E)-Modul mit einem integrierten USB-Adapter (CP2102), einem Spannungsregler (3,3V) und zwei Tasten (Flash,Reset).
Um PlatformIO (Ja, keine ArduinoIDE. Wechselt! Je eher, desto besser) einzurichten, hat man beim Board-Explorer die Wahl zwischen NodeMCU 0.9 (ESP-12) und NodeMCU 1.0 (ESP-12E). Um das zu unterscheiden, mal kurz bei Tante Google vorbeigeschaut.
Ein sehr gelungener Ueberblick
Diese Seite kann evtl. auch Klarheit bringen, obwohl die Unterscheidung ESP-12(X) nicht daraus hervorgeht.
Es gibt auch schon eine ESP-12F-Variante.
Die Unterschiede liegen in der Beschaltung (einige wenige Kondensatoren und Widerstaende) und dem Boardlayout (Position der Komponenten, Wireroutes, ...). Das meiszte liegt allerdings unter der HF-Abschirmung (Metallcover) verborgen, so dass man ohne Demontage keine Aussage zur Unterscheidung treffen kann. Das Einzige was ich entdecken konnte, war die etwas andere Form der PCB-Antenne, so dass ich mich in meinem Fall fuer ein 12E entschieden habe.
Check-Liste der Unterscheidungsmerkmale:
- Layout der Antenne
- Aufdruck auf dem Schirmblech
- ....
Bitte schickt mir Fotos mit Beschreibung eurer Module, dann wird die Check-Liste eindeutiger.
Framework
Bei der Anlage eines neuen Projektes bekommt man auch 4 Frameworks zur Wahl gestellt. Die Beschreibungen auf der Seite empfand ich als wenig hilfreich. Zum jetzigen Zeitpunkt genuegt es mir zu erkennen, dass es sich bei den Alternativen zu Arduino um Real-Time-Operating-Systeme (RTOS) handelt. TODO: RTOS-Unterscheidungstabelle.
Arduino
Arduino Wiring-based Framework allows writing cross-platform software to control devices attached to a wide range of Arduino boards to create all kinds of creative coding, interactive objects, spaces or physical experiences
ESP8266 Non-OS SDK
The non-OS SDK provides a set of application programming interfaces (APIs) for core ESP8266 functionalities such as data reception/transmission over Wi-Fi, TCP/IP stack functions, hardware interface functions and basic system management functions
ESP8266 RTOS SDK
ESP8266 SDK based on FreeRTOS, a truly free professional grade RTOS for microcontrollers
Simba
Simba is an RTOS and build framework with aims to make embedded programming easy and portable
Programme
Wo will ich eigentlich hin?
Die NodeMCUs sollen als WLAN-Clients in meinem Garten verschiedene Schalt- und Steuerungsaufgaben übernehmen. Und bestimmt auch dieses ELV-eQ3-BidCos-Geraffel ersetzen.
Also taste ich mich ueber verschiedene Testprogramme mal an ein paar Notwendigkeiten heran.
WLAN-Client
Client, nicht AP. Ich stelle mir vor, dass ich einen "Außen-AP" nutzte, um alle Clients einzufangen.
DHT
Jeder Client kann gerade, wenn er schon dabei ist, auch ein paar Umweltdaten mitliefern.
MQTT
Natuerlich koennte ich ein Protokoll entwerfen und auf meine Wunesche anpassen. So was mit ESC-Sequenzen ueber ein simples Client-Server-Programm-Paerchen. Dann faengt man aber bei jedem Vorhaben fast wieder von vorne an. Also am besten gleich MQTT.
TLS
Nicht nur die Anmeldung am AP und die WLAN-Kommunikation sollen abgesichert sein, sondern auch die Steuerinformationen an sich. Darueber hinaus werde ich das Garten-WLAN in ein eigenes Subnetz, oder gleich in ein eigenes VLAN verfrachten.
Stufe 1: Blink
Was mir gleich auffaellt ist, dass das #include <Arduino.h> zu Beginn des Programms fehlt.
Quellcode (Blink.ino) in main.cpp unter src einkopieren und compilieren.
Na prima, ein Fehler.
src/main.cpp: In function 'void setup()': src/main.cpp:12:11: error: 'LED_BUILTIN' was not declared in this scope 12 | pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
Ja, klar. Woher soll das Programm auch wissen, was LED_BUILTIN ist.
Diese Seite beleuchtet diesen Umstand, erbringt aber keine Loesung fuer mein Problem.
Irgendwo auf der Festplatte muss ein Datei (.h) vorhanden sein, die BUILTIN_LED und OUTPUT definiert.
locate .platformio
cd <PATH>/.platformio
find . -type f -exec grep -l "define LED_BUILTIN" {} \;
Das Ergebnis ist unter anderen eine Datei namens pins_arduino.h
./packages/framework-arduinoespressif8266/variants/nodemcu/pins_arduino.h
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
Modified for ESP8266 platform by Ivan Grokhotkov, 2014-2015.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#define PIN_WIRE_SDA (4)
#define PIN_WIRE_SCL (5)
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
#define LED_BUILTIN_AUX 16
static const uint8_t D0 = 16;
static const uint8_t D1 = 5;
static const uint8_t D2 = 4;
static const uint8_t D3 = 0;
static const uint8_t D4 = 2;
static const uint8_t D5 = 14;
static const uint8_t D6 = 12;
static const uint8_t D7 = 13;
static const uint8_t D8 = 15;
static const uint8_t D9 = 3;
static const uint8_t D10 = 1;
#include "../generic/common.h"
#endif /* Pins_Arduino_h */
Da diese Datei nur LED_BUILTIN, aber nicht OUTPUT definiert -> weitersuchen.
find . -type f -exec grep -l "define OUTPUT" {} \;
Aha!
./packages/framework-arduinoespressif8266/cores/esp8266/Arduino.h
Als wenn ich es geahnt haette. Es fehlt das #include <Arduino.h > am Programmanfang. Warum auch immer.
Eingefuegt. Compiliert. Klappt (erst mal).
Uebertragen. Fehler!
Auto-detected: /dev/ttyUSB0 Uploading .pio/build/nodemcuv2/firmware.bin esptool.py v3.0 Serial port /dev/ttyUSB0 Traceback (most recent call last): File "/home/chris/.platformio/penv/lib64/python3.6/site-packages/serial/serialposix.py", line 322, in open self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) PermissionError: [Errno 13] Permission denied: '/dev/ttyUSB0'
ll /dev/ttyUSB0 crw-rw---- 1 root dialout 188, 0 Aug 28 08:21 /dev/ttyUSB0
chmod a+rw /dev/ttyUSB0
ll /dev/ttyUSB0 crw-rw-rw- 1 root dialout 188, 0 Aug 28 08:21 /dev/ttyUSB0
Man kann natuerlich auch per chown die User oder Gruppenzurgehoerigkeit anpassen, oder gleich dem Hinweis:
Warning! Please install `99-platformio-udev.rules`. More details: https://docs.platformio.org/page/faq.html#platformio-udev-rules
folgen.
Trotzdem noch ein Fehler!
... Auto-detected: /dev/ttyUSB0 Uploading .pio/build/nodemcuv2/firmware.bin esptool.py v3.0 Serial port /dev/ttyUSB0 Connecting.... Traceback (most recent call last): File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 3969, in <module> _main() File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 3962, in _main main() File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 3552, in main esp.connect(args.before, args.connect_attempts) File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 519, in connect last_error = self._connect_attempt(mode=mode, esp32r0_delay=False) File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 499, in _connect_attempt self.sync() File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 438, in sync timeout=SYNC_TIMEOUT) File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 386, in command p = self.read() File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 331, in read return next(self._slip_reader) File "/home/chris/.platformio/packages/tool-esptoolpy/esptool.py", line 2632, in slip_reader read_bytes = port.read(1 if waiting == 0 else waiting) File "/home/chris/.platformio/penv/lib64/python3.6/site-packages/serial/serialposix.py", line 596, in read 'device reports readiness to read but returned no data ' serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?) *** [upload] Error 1 ========================== [FAILED] Took 2.04 seconds ==========================
Ohje! Stimmt! Ich habe minicom noch in einem anderen Terminal laufen.
Jetzt hat's geklappt.
Auto-detected: /dev/ttyUSB0 Uploading .pio/build/nodemcuv2/firmware.bin esptool.py v3.0 Serial port /dev/ttyUSB0 Connecting.... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: 9c:9c:1f:47:34:a7 Uploading stub... Running stub... Stub running... Configuring flash size... Compressed 265040 bytes to 195056... Writing at 0x00000000... (8 %) Writing at 0x00004000... (16 %) Writing at 0x00008000... (25 %) Writing at 0x0000c000... (33 %) Writing at 0x00010000... (41 %) Writing at 0x00014000... (50 %) Writing at 0x00018000... (58 %) Writing at 0x0001c000... (66 %) Writing at 0x00020000... (75 %) Writing at 0x00024000... (83 %) Writing at 0x00028000... (91 %) Writing at 0x0002c000... (100 %) Wrote 265040 bytes (195056 compressed) at 0x00000000 in 17.3 seconds (effective 122.9 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin... ========================= [SUCCESS] Took 20.75 seconds =========================
Was mir auffaellt ist, dass es mit 17 Sekunden, doch recht langsam ist ein so kleines Programm zu uebertragen. Aber was soll ich sagen, es blinkt (Die blaue LED neben der Antenne des ESP-Moduls);-)
Stufe 2: WLAN
Das Testprogramm ist Teil des A Beginner's Guide to the ESP8266 Pieter P, 08-03-2017
Irgendwie fehlt da schon wieder das #include <Arduino.h>. Mal abwarten. Irgendetwas uebersehe ich.
#include <ESP8266WiFi.h> // Include the Wi-Fi library
const char* ssid = "SSID"; // The SSID (name) of the Wi-Fi network you want to connect to
const char* password = "PASSWORD"; // The password of the Wi-Fi network
void setup() {
Serial.begin(115200); // Start the Serial communication to send messages to the computer
delay(10);
Serial.println('\n');
WiFi.begin(ssid, password); // Connect to the network
Serial.print("Connecting to ");
Serial.print(ssid); Serial.println(" ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
delay(1000);
Serial.print(++i); Serial.print(' ');
}
Serial.println('\n');
Serial.println("Connection established!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
}
void loop() { }
Da hier keine "allgemeinen" Defines drin sind, compiliert es auch ohne Arduino.h ohne Fehler.
Der Upload funktionert ebenfalls und das Programm zaehlt munter hoch.
SSID und Passwort ergaenzt und siehe da.
Willkommen zu minicom 2.7.1 Optionen: I18n Port /dev/ttyUSB0, 10:25:12 Drücken Sie CTRL-A Z für Hilfe zu speziellen Tasten 3 4 5 Connection established! IP address: 192.168.178.70
Laeuft, weiter geht's. Die MultiAccess-Moeglichkeit und AP-Mode lasse ich auszer Acht, da ich erst mal nur den Client-Mode benoetige.
Stufe 3: DHT
Zur Orientierung.
Ich habe einen DHT11 (BreakoutBoard) griffbereit und vergewissere mich des Pinouts.
Der DHT11-Sensor (blaues Gehaeuse) hat vier Pins.
- 1 VCC Sapnnungsversorgung Volt-Range 3-5,5 V
- 2 Data
- 3 NC (not connected)
- 4 GND Masse
Wen es genauer interessiert hier klicken. Hier ist auch das 40 Bit Datenformat der Messwerte erklaert. Aber diese Arbeit nimmt uns ja die Library ab.
Bei der Pinbelegung des Breakoutboards ist allerdings Vorsicht geboten, diese kann von Modul zu Modul abweichen.
DEBO BO DHT 11
Der DHT11 ist ein einfacher, extrem kostengünstiger digitaler Temperatur- und Feuchtigkeitssensor. Besonders geeignet für Raspberry und Arduino.
Technische Daten
Betriebsspannung: 5V Messmöglichkeiten: Temperatur, Luftfeuchtigkeit Chipsatz: DHT11 Kommunikationsprotokoll: 1-Wire Messbereich Luftfeuchtigkeit: 20 - 90% Messbereich Temperatur: 0 - 50°C Abtastrate: 2 Sekunden Maße: 16 x 27 x 9 mm
Ein Beispiel fuer Falschmeldungen, die Verwirrung stiften.
Unter https://funduino.de/anleitung-dht11-dht22 ist folgender Satz zu finden:
Zwischen der 5V und Pin Verbindung muss ein 10K Ohm Widerstand eingebaut werden.
Im Datenblatt (vertrauenswuerdiger) findet man:
When the connecting cable is shorter than 20 metres, a 5K pull-up resistor is recommended; when the connecting cable is longer than 20 metres, choose a appropriate pull-up resistor as needed
Noch doller (ja,d) wirds bei https://cdn-learn.adafruit.com/downloads/pdf/dht.pdf
Simply ignore pin 3, its not used. You will want to place a 10 Kohm resistor between VCC and the data pin, to act as amedium-strength pull up on the data line. The Arduino has built in pullups you can turn on but they're very weak, about20-50K
Da geht viel durcheinander. Ohje.
Auch interessant, dass das Datenblatt zum DHT11 keine Angaben zur Zaehlrichtung der Pins macht. Ich muss wohl annehmen, dass bei Draufsicht auf den Sensor von links nach rechts gezaehlt wird. Das Breakoutboad aber den rechten Pin als Pin 1 markiert!
Mein Breakoutboard (KY-015 Kombi-Sensor Temperatur+Feuchtigkeit mit ASAIR DHT11) hat folgende Pinbelegung: Draufsicht, Pins nach rechts, von oben nach unten:
- 1 GND
- 2 V+
- 3 Signal
Nach der Verkabelung noch schnell die empfohlenen Library dazugepackt und ab dafuer.
[env:nodemcuv2] platform = espressif8266 board = nodemcuv2 framework = arduino lib_deps = adafruit/Adafruit Unified Sensor@^1.1.4 adafruit/DHT sensor library@^1.4.2
Das Beispiel der Seite hat prompt einen Fehler.
Wenn man eine Funktion erst nach ihrem Aufruf definiert, kann das nur schief gehen. Grrrrrrrr!
Entweder man definiert sie vorher, oder setzt eine Deklaration vor den ersten Aufruf.
Patch: /*Put your SSID & Password*/ const char* ssid = "YourNetworkName"; // Enter SSID here const char* password = "YourPassword"; //Enter Password here void handle_OnConnect(); void handle_NotFound(); String SendHTML(float Temperaturestat,float Humiditystat); ESP8266WebServer server(80); ...
Mit angeschlossenem D8 erhalte ich einen UPLOAD-Timeout.
Aber soweit so schlecht.
Ueber die Integer-Darstellung auf der HTML-Seite und den Formatierungsfehler sehe ich mal hinweg.
Mein Blink-Alive zeigt aber deutlich die Nachteile einer delay-Programmierung.
Aber weiter im Text.
Stufe 4: MQTT
Das Basic ESP8266 MQTT Example der PubSubClient-Library hat ein paar kleinere Fehler.
Ich habe die fuer mich notwendigen Bestandteile extrahiert und in mein Codebeispiel (WLAN-MQTT-DHT) gepackt.
Fehlerliste:
- In callback
for (unsigned int i = 0; i < length; i++) { Serial.print((char)payload[i]); }
- LED_BUILTIN nach LED_BUILTIN getauscht
- long int value = 0;
Aber was soll ich sagen, es laeuft.
#include <Arduino.h> // in den DHT examples benutzt
#include <Ticker.h> // in den DHT examples benutzt
#include <ESP8266WiFi.h> // Include the Wi-Fi library
#include <PubSubClient.h>
#include "DHT.h"
//WLAN
WiFiClient espClient;
const char* ssid = "CLX_HO"; // The SSID (name) of the Wi-Fi network you want to connect to
const char* password = "444289439767"; // The password of the Wi-Fi network
//MQTT
const char* mqtt_server = "192.168.178.12";
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
long int value = 0;
//DHT
Ticker ticker;
DHT11 sensor; // change to DHT22 if needed!
volatile float humidity = 0;
volatile float temperature = 0;
volatile uint8_t error = 0;
volatile int8_t result = 0;
int grad = 248;
void readDHT() {
sensor.read();
}
// this callback will be called from an interrupt
// it should be short and carry the ICACHE_RAM_ATTR attribute
void IRAM_ATTR handleData(float h, float t) {
humidity = h;
temperature = t;
result = 1;
}
// this callback will be called from an interrupt
// it should be short and carry the ICACHE_RAM_ATTR attribute
void IRAM_ATTR handleError(uint8_t e) {
error = e;
result = -1;
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (unsigned int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is active low on the ESP-01)
} else {
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200); // Start the Serial communication to send messages to the computer
delay(10);
Serial.println('\n');
//sensor.setup(D4);
sensor.setPin(D8);
sensor.onData(handleData);
sensor.onError(handleError);
ticker.attach(30, readDHT);
WiFi.mode(WIFI_STA);// ist scheinbar der defaultwert wird in letzter Version nicht benutzt
WiFi.begin(ssid, password); // Connect to the network
Serial.print("Connecting to ");
Serial.print(ssid); Serial.println(" ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
delay(1000);
Serial.print(++i); Serial.print(' ');
}
randomSeed(micros());
Serial.println('\n');
Serial.println("Connection established!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (result > 0) {
Serial.printf("Humid: %g %%\n", humidity);
Serial.println();
Serial.printf("Temp: %3.1f %cC\n", temperature,grad);
Serial.println();
} else if (result < 0) {
Serial.printf("Error: %s\n", sensor.getError());
}
result = 0;
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("outTopic", msg);
}
}
Der Screenshot zeigt schoen das Zusammenspiel von NodeMCU, Minicom, FHEM-Eventmonitor und mosquitto_pub.
Stufe 4: I2C PCF8574
Jetzt geht es darum ueber MQTT zu schalten und zu melden.
Dazu erst mal wieder ein Blick auf die GPIO der NodeMCU.
https://www.electronicwings.com/nodemcu/nodemcu-gpio-with-arduino-ide
https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/
Wie man sieht hat man nicht gerade die rieszige Auswahl.
Da ich fuer eine Anwendung mindestens 6 Ausgaenge benoetige muss wohl ein PCF8574 her.
Mal die Library PCF8574 by Rob Tillaart probieren.
Ich bin ueberrascht, oder aber doch nicht. Zu dem Port-Expander von ELV 9631229 ist im Internet nix zu finden, daher ein kleiner [[PCF8574] Ausflug]PCF8574.
Im Datenblatt des AMS117 steht was von bis zu 1 A Belastbarkeit drin. Da ich die NodeMCU ueber USB (max 500 mA) sollte das reichen. Bei angenommenen 20 mA pro LED ist das wohl ausreichend.
Weiterhin kann man dem Datenblatt des PCF8574 einen Spannungsbereich von 2,5 V bis 6 V entnehmen, also dann mal mutig direkt an 3,3 V der NodeMCU betrieben.
Adressverwirrung
Warum steht dann
PCF8574 PCF_39(0x39); // add leds to lines (used as output)
im Example der PCF8574-Library drin. Das gibt Abzuege in der B-Note. Und warum uGW unterscheidet man die Adressen von read und write.
PCF8574 PCF_38(0x38); // add switches to lines (used as input) PCF8574 PCF_39(0x39); // add leds to lines (used as output)
Bin mal gespannt.
Der I2C Scanner lieferte Adressen von 0x20 bis 0x27. Die Slave-Adresse setzt sich aus 0100 und A2A1A0RW zusammen. Schreiben (write) ist 0 und lesen (read) ist 1.
Als bei AX auf GND ist die Schreibadresse 0x40 und die Lese Adresse 0x41.
Texas Instruments’ (TI) PCF8574 and PCF8574A are two-wire I2C-bus to8-bit parallel bus I/O expanders from TI’s I2C logic portfolio. They aredesigned to provide a simple and cost-effective method to monitor andcontrol several peripheral signals. The difference between the PCF8574and PCF8574A is the I2C address:•PCF8574 has addresses ranging from 0x20 to 0x27 (up to eight PCF8574 devices may be used on the same I2C bus).•The PCF8574 and PCF8574A have addresses ranging from 0x38 to 0x3F (up to eight PCF8574A devices may be used on the same I2C bus).•A total of 16 PCF8574 and PCF8574A devices may be used on the same I2C bus.
Also scheint es mindestens 3 verschiedene Typen von PCF8574 zu geben. Ich habe den 0x20er. OK, also die Adresse 0x40.
Es klappt. Videobeweis folgt.
Als nächstes kommt eine Relaiskarte dran. TODO
Da an dieser Stelle alle grundsaetzlichen Fragestellungen geklaert scheinen und jetzt das grosze Bereinigen und Implementieren folgt geht es auf einer neuen WLAN Schaltsteckdose Seite weiter.