An elegant automatic stair lighting (part 3)

Hello and welcome to a continuation of the series elegant stair lighting. Today expand like the maximum number of stairs that our controller can control from just 16 to Fulminate 992 steps!
Thus, even owners of a longer stairway should be able to easily adjust the control for their purposes according to your needs and wishes.

This adjustment is done easily and conveniently by adjusting the program variables "Overall_Stages" to the desired number of stairs from 1 to 992.

Well, one or the other may wonder how I reach this large number of PWM outputs at just 20 available outputs of an AZ-Delivery Nano V3. The secret lies in the 6 address bits of the PCA9685. Each PCA9685 can provide 16 PWM channels. The board's daisy-chain layout prevents cable chaos and allows the up to 62 controllers to connect comfortably.

By binary addressing the boards, one of a total of 62 addresses in the range of 40h to 7Eh can be assigned to a module counting upwards. This results in the maximum possible 992 outputs with 16 outputs per module.

The code has been written by me so that the addressing of the modules is abstracted by the user and is calculated automatically. It is only the total sum of the stairs to be specified in a variable and an appealing number of modules to be attached as a daisy chain to the I2C bus. In the case of the modules, attention must be paid to an ascending addressing of the modules.

In the following image you can see how the modules have to be connected and addressed:

Structure as A Daisy-Chain

 

 

For our current project we need:

Number

Description

Note

2

Pir Module HC-SR501 PIR

Motion sensor

up to 62

PCA9685 16 Channel 12 Bit PWM Driver

Number depending on the number of stairs /16

1

Nano V3

 

1

MB102 Power Supply Adapter

For breadboard setup

up to 992

IRF520 MOS Driver Module 0-24V 5A

Number depending on the number of stairs

1

Power supply for LED/lamps for the steps

Maximum 24 volts

 

Please note that the circuit was not tested with full assembly, but only with 2 modules of type PCA9685. A full assembly with 62 modules is therefore only Theoretically Described. In practice, maximum I2C bus lengths, fault safety, clean signal transmission, sufficiently sized power supplies, cables, secure connections and more must be taken into account. All references to this from the previous parts apply in particular in today's part.

Here is the updated code for today's part:

 

Code by Tobias Kuch 2019 mailto:tobias.kuch@googlemail.com
Code under GPL 3.0

#include <Wire.H>

#define PWM_Module_Base_Addr 0x40 10000000b The last bit of the address byte defines the operation to be performed. When set to logical 1 0x41 module 2 etc.. Address range0x40 - 0x47 
selects a read operation while a logical 0 selects a write operation.
#define OE_Pin  8           Pin for Output Enable 
#define CPU_LED_Pin 13
#define PIRA_Pin 2
#define PIRB_Pin 3
#define Num_Stages_per_Module 16
#define Delay_Stages  5
#define Delay_ON_to_OFF  2  Minimum Delay_ON_to_OFF in Seconds


Int Overall_Stages =  16; maximum number of steps: 62 x 16 = 992
Int delay_per_Stage_in_ms = 200;



Int Pwm_Channel = 0;
Int Pwm_Channel_Brightness = 0;
Bool Motion_Trigger_Down_to_Up = False;
Bool Motion_Trigger_Up_to_Down = False;
Bool On_Delay = False;
Byte PWMModules = 0;
Byte StagesLeft = 0;
interrupt Control
Byte A60telSeconds24 = 0;
Byte Seconds24;

Isr(TIMER1_COMPA_vect)
{   A60telSeconds24++;   If (A60telSeconds24 > 59)   {     A60telSeconds24 = 0;     Seconds24++;     If (Seconds24 > 150)     {       Seconds24 = 0;     }   }
}

Void ISR_PIR_A()
{   Bool PinState = digitalRead(PIRA_Pin);   If (PinState)   {     if (!(Motion_Trigger_Up_to_Down) and !(Motion_Trigger_Down_to_Up))     {       digitalWrite(CPU_LED_Pin, HIGH);       Motion_Trigger_Down_to_Up = true;     } // PIR A ausgelöst   } else   {     digitalWrite(CPU_LED_Pin, LOW);   }
}

void ISR_PIR_B()
{   bool PinState = digitalRead(PIRB_Pin);   if (PinState)   {     if (!(Motion_Trigger_Down_to_Up) and !(Motion_Trigger_Up_to_Down))     {       digitalWrite(CPU_LED_Pin, HIGH);       Motion_Trigger_Up_to_Down = true;     } // PIR B ausgelöst   } else   {     digitalWrite(CPU_LED_Pin, LOW);   }
}

void Init_PWM_Module(byte PWM_ModuleAddr)
{   pinMode(OE_Pin, OUTPUT);   pinMode(CPU_LED_Pin, OUTPUT);   digitalWrite(OE_Pin, HIGH); // Active LOW-Ausgangsaktivierungs-Pin (OE).   Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren   Wire.write(0x00);                       //   Wire.write(0x06);                       // Software Reset   Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit   delay(400);   Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren   Wire.write(0x01);                       // Wähle  Mode 2 Register (Command Register)   Wire.write(0x04);                       // Konfiguriere Chip: 0x04:  totem pole Ausgang 0x00: Open drain Ausgang.   Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit   Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren   Wire.write(0x00);                      // Wähle Mode 1 Register (Command Register)   Wire.write(0x10);                      // Konfiguriere SleepMode   Wire.endTransmission();                // Stoppe Kommunikation - Sende Stop Bit   Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren   Wire.write(0xFE);                       // Wähle PRE_SCALE register (Command Register)   Wire.write(0x03);                       // Set Prescaler. Die maximale PWM Frequent ist 1526 Hz wenn das PRE_SCALEer Regsiter auf "0x03h" gesetzt wird. Standard : 200 Hz   Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit   Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren   Wire.write(0x00);                       // Wähle Mode 1 Register (Command Register)   Wire.write(0xA1);                       // Konfiguriere Chip:  ERrlaube All Call I2C Adressen, verwende interne Uhr,                                           // Erlaube Auto Increment Feature   Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit
}


void Init_PWM_Outputs(byte PWM_ModuleAddr)
{   digitalWrite(OE_Pin, HIGH); // Active LOW-Ausgangsaktivierungs-Pin (OE).   for ( int z = 0; z < 16 + 1; z++)   {     Wire.beginTransmission(PWM_ModuleAddr);     Wire.write(z * 4 + 6);      // Wähle PWM_Channel_ON_L register     Wire.write(0x00);                     // Wert für o.g. Register     Wire.endTransmission();     Wire.beginTransmission(PWM_ModuleAddr);     Wire.write(z * 4 + 7);      // Wähle PWM_Channel_ON_H register     Wire.write(0x00);                     // Wert für o.g. Register     Wire.endTransmission();     Wire.beginTransmission(PWM_ModuleAddr);     Wire.write(z * 4 + 8);   // Wähle PWM_Channel_OFF_L register     Wire.write(0x00);        // Wert für o.g. Register     Wire.endTransmission();     Wire.beginTransmission(PWM_ModuleAddr);     Wire.write(z * 4 + 9);  // Wähle PWM_Channel_OFF_H register     Wire.write(0x00);             // Wert für o.g. Register     Wire.endTransmission();   }   digitalWrite(OE_Pin, LOW); // Active LOW-Ausgangsaktivierungs-Pin (OE).
}

void setup()
{   //Initalisierung   Serial.begin(115200);   pinMode(PIRA_Pin, INPUT);   pinMode(PIRB_Pin, INPUT);   Serial.begin(9600);   while (!Serial) {     ; // wait for serial port to connect. Needed for native USB   }   PWMModules = Overall_Stages / 16;   StagesLeft = Overall_Stages % 16;   if (StagesLeft >= 1) {     PWMModules++;   }   Wire.begin(); // Initalisiere I2C Bus A4 (SDA), A5 (SCL)   for (byte ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Init_PWM_Module(PWM_Module_Base_Addr + ModuleCount);     Init_PWM_Outputs(PWM_Module_Base_Addr + ModuleCount);   }   noInterrupts();   attachInterrupt(0, ISR_PIR_A, CHANGE);   attachInterrupt(1, ISR_PIR_B, Change);   TCCR1A = 0x00;   TCCR1B = 0x02;   TCNT1 = 0;      Initialize register with 0   OCR1A =  33353;      Pre-documents Output Compare Register   TIMSK1 |= (1 << OCIE1A);  Enable Timer Compare Interrupt   Interrupts();
}

Void Down_to_Up_ON()
{   Serial.println("Down_to_Up_ON");   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   for (Byte ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     If ((StagesLeft >= 1) and (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     else     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = 0;     Pwm_Channel_Brightness = 0;     while (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Wire.beginTransmission( PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 8);   Select PWM_Channel_0_OFF_L register       Wire.Write((Byte)Pwm_Channel_Brightness & 0xff);        Value for above register       Wire.endTransmission();       Wire.beginTransmission( PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 9);  Select PWM_Channel_0_OFF_H register       Wire.Write((Pwm_Channel_Brightness >> 8));             Value for above register       Wire.endTransmission();       If (Pwm_Channel_Brightness < 4095)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages;         If (Pwm_Channel_Brightness > 4095) {           Pwm_Channel_Brightness = 4095;         }       } else If ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 0;         Delay(delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}

Void Up_to_DOWN_ON()
{   Serial.println("Up_to_DOWN_ON ");   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCount = PWMModules - 1;   while (ModuleCount >= 0)   {     Pwm_Channel_Brightness = 0;     If ((StagesLeft >= 1) and (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module =  StagesLeft;     }     else     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     while (Pwm_Channel > -1)     {       Wire.beginTransmission( PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 8);   Select PWM_Channel_0_OFF_L register       Wire.Write((Byte)Pwm_Channel_Brightness & 0xff);        Value for above register       Wire.endTransmission();       Wire.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 9);  Select PWM_Channel_0_OFF_H register       Wire.Write((Pwm_Channel_Brightness >> 8));             Value for above register       Wire.endTransmission();       If (Pwm_Channel_Brightness < 4095)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages;         If (Pwm_Channel_Brightness > 4095) {           Pwm_Channel_Brightness = 4095;         }       } else If ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness = 0;         Delay(delay_per_Stage_in_ms);         Pwm_Channel--;         If ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Break;         }       }     }     ModuleCount = ModuleCount - 1;   }
}


Void Down_to_Up_OFF()
{   Serial.println("Down_to_Up_OFF");   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   for (Byte ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     If ((StagesLeft >= 1) and (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     else     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     while (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Wire.beginTransmission( PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 8);   Select PWM_Channel_0_OFF_L register       Wire.Write((Byte)Pwm_Channel_Brightness & 0xff);        Value for above register       Wire.endTransmission();       Wire.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 9);  Select PWM_Channel_0_OFF_H register       Wire.Write((Pwm_Channel_Brightness >> 8));             Value for above register       Wire.endTransmission();       If (Pwm_Channel_Brightness > 0)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages;         If (Pwm_Channel_Brightness < 0) {           Pwm_Channel_Brightness = 0;         }       } else If ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 4095;         Delay(delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}


Void Up_to_DOWN_OFF()
{   Serial.println("Up_to_DOWN_OFF");   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCount = PWMModules - 1;   while (ModuleCount >= 0)   {     Pwm_Channel_Brightness = 4095;     If ((StagesLeft >= 1) and (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     else     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     while (Pwm_Channel > -1)     {       Wire.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 8);   Select PWM_Channel_0_OFF_L register       Wire.Write((Byte)Pwm_Channel_Brightness & 0xff);        Value for above register       Wire.endTransmission();       Wire.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Wire.Write(Pwm_Channel * 4 + 9);  Select PWM_Channel_0_OFF_H register       Wire.Write((Pwm_Channel_Brightness >> 8));             Value for above register       Wire.endTransmission();       If (Pwm_Channel_Brightness > 0)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages;         If (Pwm_Channel_Brightness < 0) {           Pwm_Channel_Brightness = 0;         }       } else If ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness =  4095;         Delay(delay_per_Stage_in_ms);         Pwm_Channel--;         If ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Break;         }       }     }     ModuleCount = ModuleCount - 1;   }
}

Void Loop()
{   If ((Motion_Trigger_Down_to_Up) and !(On_Delay) )   {     Seconds24 = 0;     On_Delay = True;     Down_to_Up_ON();   }   If ((On_Delay) and (Seconds24 > Delay_ON_to_OFF) and (Motion_Trigger_Down_to_Up) )   {     Down_to_Up_OFF();     Motion_Trigger_Down_to_Up = False;     On_Delay = False;     Seconds24 = 0;   }   If ((Motion_Trigger_Up_to_Down) and !(On_Delay) )   {     Seconds24 = 0;     On_Delay = True;     Up_to_DOWN_ON();   }   If ((On_Delay) and (Seconds24 > Delay_ON_to_OFF) and (Motion_Trigger_Up_to_Down))   {     Up_to_DOWN_OFF();     Motion_Trigger_Up_to_Down = False;     On_Delay = False;     Seconds24 = 0;   }
}

 

 

I wish you a lot of fun with the replica and until the next part of the series. As always, you can find all previous projects under the GitHub page https://github.com/kuchto

For arduinoProjects for advancedSensors

8 comments

Muharrem

Muharrem

@ Markus ich möchte dein Vorhaben auch realisieren. Könntest du mir bitte behilflich sein.
Ich bedanke mich im Voraus

Markus

Markus

Material:
xx ws2812b Leds (xx = Anzahl je nachdem wieviele man verbrauchen will), Strips oder einzelne
1 Arduino Nano
1 Bluetooth Modul HC-06
2 Bewegungsmelder HC-SR501
1 Lichtsensor
1 Netzteil 5V xx Ampere ( Je nachdem wie viele Leds man verbraucht)
Led Kabel 5 Adrig
Lötkolben und Zinn
Phantasie

Vorwort:
Überlegung war ein Treppenlicht zu bauen, was erkennt wenn oben oder unten jemand die Treppe benutzen möchte. Beim Bauen viel mir immer mehr ein was man machen könnte, so wurde es immer komplexer. So ist das Endergebnis mit Bluetooth mit dem Handy verbunden worden um Farben oder Effekte, sowie verschiedene Daten zu übermitteln. Ein Lichtsensor wurde verbaut, damit die Beleuchtung nicht andauernd anspringt, sondern nur wenn es dunkel genug ist.
Weitere Überlegungen:
Was brauche ich? In meiner zweiten Version habe ich Kabelkanäle genommen, da passte sogar der Nano und das BT Modul rein. Löcher für die Leds in der richtigen Lage der Stufen gebohrt und eingeklebt. Da im Nachhinein noch der Lichtsensor eingebaut wurde, muss ich durch den Kanal ein 5 adriges Led Kabel verlegen. Erste das 5V, Zweite GND, Dritte Datenkabel Leds, Vierte BW2, Fünfte der Lichtsensor. BW1 wird direkt an den nano gemacht.
Hab noch mehrere Versionen in laufe der Entwicklung erstellt, so hab ich auch welche mit Holzleisten gemacht, oder mit einer Fräse unten in den Treppenstufen eine Nut rein gefräst. Möglichkeiten sollte es genug geben. Man muss nur seine Phantasie spielen lassen.
Effekte wurden nach und nach eingebaut. Z.B. Wenn man die Treppe benutzt das die Treppen nach und nach der Richtung die man läuft angehen, und wenn man oben ankommt die langsam hinter sich ausgehen (sieht gut aus). Notbeleuchtung eingebaut, die die Treppe soweit beleuchten das man den Weg findet, man kann die Farbe der Beleuchtung ändern, die Zeiten etc. . Partybeleuchtung eingebaut. Es gibt auch hier noch etliche Möglichkeiten die einem einfallen. Die einzelnen Effekte konnte man dann mit einer App verändern oder ein oder ausschalten.
Meine nächsten Versionen, benutzen den Esp8266 (Wlan statt Bluetooth), so dass ich die Beleuchtung auch in meine Homeautomation per MQTT steuern kann. Dies ist aber noch in der Mache, das verschling doch ganz schön viel Zeit.
Ich weiß das einige nun wahrscheinlich den Code oder die App oder sonst was haben möchte. Ich habe damit aber so viel Zeit verbracht das ich das so nicht machen werde, bin aber bereit zu helfen wenn es im Eigenbau zu Fragen oder Problemen kommt.

Dirk

Dirk

Hallo an alle,
ich komme hier mit einer vielleicht etwas peinlichen Frage weil ich mich vielleicht einfach nur verrechne. Aber ich bin mir unsicher über den Kabelquerschnitt bei der Stromversorgung für die Lampen. Ich möchte Led Ringe verwenden, die wollen 5 Volt und ziehen 0,24 A wenn ich das aus dem Datenblatt richtig lese. Wenn ich jetzt 16 (16 Stufen) Stück parallel mit der nötigen Leistung versorgen will, welchen Kabelquerschnitt braue ich ich dann ohne diese zu Überlasten ? Das sind dann ja schon knapp 20 Watt und das bei 3 Meter Leitungslänge. Will ja nicht die Treppe abfackeln. Oder sollte man mit mehreren Reihenschaltungen und mehr Volt arbeiten. Wäre sehr dankbar für einen Tipp.
Gruß, Dirk

Tobias

Tobias

Hallo Georg,
Die Beleuchtung kommt sehr nahe an das Video, jedoch variiert die Ausschalt Sequenz der Treppe ein bisschen, da immer die nächste Treppenstufe erst dann anfängt, hoch oder herunterzudimmen, wenn die vorherige bereits Ihren Endzustand (aus oder ein) erreicht hat. Im Video passiert das augenscheinlich parallel in der Ausschalt Sequentz. Ich helfe, soweit es zeitlich im Rahmen bleibt, gerne weiter . Mailadresse: tobias.kuch@googlemail.com.
Gruß
Tobias

Tobias

Tobias

Hallo Markus,

Könntest du dein tolles Projekt mit Code für Nano und Handyapp, Aufbauanleitung und Beschreibung dann nicht auch uns allen zur Verfügung stellen ? So hätten auch andere etwas davon
Gruß
Tobias

Uwe

Uwe

Lieber Tobias, hallo AZ-Team,
zuerst Mal danke für die Beiträge und die Mühe damit. Nach den Kommentaren von Wolfgang und Thomas habe ich auch noch einige Ideen.

Zunächst einmal wäre es sinnvoll, bei Fortsetzungen einer Beitragsreihe die Kommentare zu konsolidieren. Es gibt Leser, die auch aus den Kommentaren vielleicht noch Ideen schöpfen können.

Aus den Fragen und Anregungen der Kommentatoren ist zu entnehmen, dass es auch andere Vorschläge gibt. Ich gehe davon aus, dass AZ diese auch gerne veröffentlichen würde, wenn man diese einreicht. Hier wäre vielleicht ein Hinweis angebracht, wie man das macht.

Nun ist der Interessenkreis hier sehr verschieden: AZ-Delivery lebt vom Vertrieb von Komponenten und nutzt die Beiträge dazu, Interesse für sein Portal zu wecken, Es gibt Leser, die sich für die Elektronik interessieren, die jedoch Nachhilfe bei der Programmerstellung benötigen, andere suchen einfach eine Idee zum Nachbauen. Wieder andere haben vielleicht mit Mechanik keinerlei Probleme, denen ist Strom jedoch ein Rätsel. Dazwischen sitzt der Autor und kann es keinem richtig Recht machen – eigentlich wollte er ja nur an seiner Idee teilhaben lassen.

Ich finde die hier vorgestellte Idee super (würde mir auch den Vorschlag von Markus ansehen wollen) – habe als Kybernetiker mit dem Verständnis von Automaten, Startbedingungen und Betrachtung (was wäre wenn…) keine Probleme. Nur habe ich mich nie mit der Programmentwicklung in der Tiefe beschäftigt. Für mich wäre es hilfreich, wenn im Code einige Kommentare drin wären, die das Verständnis des Codes für eine evtl Adaption erleichtern. Hierfür wäre ich sogar bereit, einen Obulus zu bezahlen. Die Anregung hier: vielleicht könnte man unter der Rubrik Literatur ein komplettes “Make” für ?? anbieten, dann mit ausführlichen Hinweisen zu VDE, Code, mechanischer Sicherheit etc?

Georg L.

Georg L.

Hallo Markus, kannst deine Lösung auch gerne teilen, dann können alle nachvollziehen, ob es einfacher ist. @Tobias, funktioniert die Beleuchtung dann wie im Video des ersten Teiles zu sehen?

Markus

Markus

Ich finde das alles zu umständlich, habe selber schon mehrere Treppenbeleuchtung gebaut und programmiert. Habe aber die WS2812 genommen, nano mit Bluetooth Verbindung (mit einer selbstgeschriebenden App um Veränderungen vor zu nehmen) , Mini IR Bewegungssensor PIR AM312. Das ganze läuft Problemlos.

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN