# data[].attributes.body
-  Python und MicroPython als Programmiersprachen sind beide ähnlich
- sie unterscheiden sich in ihrer Syntax
- MicroPython wird in eingeschränkteren Umgebungen mit geringerer Leistung verwendet, beispielsweise einem Mikrocontroller,
- während Python in größeren Umgebungen, beispielsweise dem Desktop, verwendet wird.

# data[].attributes.headline
b. Hier ist eine Erklärung des Codes von Einheit 1:

# data[].attributes.subject
b. Hier ist eine Erklärung des Codes von Einheit 1:

# data[].attributes.body
1. Zuerst werden die erforderlichen Bibliotheken `WiFi` und `ESPAsyncWebServer` importiert.

2. Es werden zwei Konstanten definiert: `trigPin` und `echoPin`. Diese dienen zur Steuerung des Ultraschallsensors.

3. Es wird eine Konstante `SOUND_SPEED` definiert, um die Schallgeschwindigkeit in Zentimetern pro Mikrosekunde festzulegen. Dies wird für die Berechnung der Entfernung verwendet.

4. Es werden zwei Variablen deklariert: `dauer` für die Dauer der Schallwellenübertragung und `distanceCm` für die berechnete Entfernung in Zentimetern.

5. Es werden die Netzwerkdaten für den Access Point definiert: `ssid` für den Netzwerknamen und `password` für das Passwort.

6. Es wird ein Objekt `server` vom Typ AsyncWebServer erstellt und auf Port 80 initialisiert.

7. Die Funktion `readDist()` wird definiert. Diese Funktion liest die Entfernung vom Ultraschallsensor und gibt sie als String zurück.

8. In der `setup()`-Funktion erfolgt die Initialisierung des Programms:

- Der serielle Port wird für die Debugging-Ausgabe initialisiert.

- Die Pin-Modi für `trigPin` und `echoPin` werden festgelegt.

- Der ESP wird als Access Point konfiguriert.

- Die IP-Adresse des Access Points wird über den seriellen Port ausgegeben.

- Ein Handler für den Pfad "/distance" wird erstellt. Wenn eine GET-Anfrage auf diesem Pfad eingeht, wird die Funktion `readDist()` aufgerufen und die berechnete Entfernung als Textantwort zurückgesendet.

- Der Server wird gestartet.

9. In der `loop()`-Funktion wird nichts gemacht, da der Code keine wiederkehrenden Aufgaben hat.

Zusammenfassend: Der Code richtet einen ESP32 als Access Point ein und ermöglicht es, die Entfernung mit einem Ultraschallsensor zu messen. Wenn eine GET-Anfrage auf "/distance" eingeht, wird die Entfernung als Textantwort zurückgesendet.

# data[].attributes.body
- Thonny ist eine integrierte Entwicklungsumgebung (IDE) für das Programmieren mit der Programmiersprache MicroPython.
- MicroPython ist eine Variante der Programmiersprache Python, die speziell für Mikrocontroller und eingebettete Systeme entwickelt wurde.

- Mit Thonny können Sie MicroPython-Code schreiben, bearbeiten, ausführen und debuggen.

- Thonny unterstützt eine Vielzahl von Mikrocontrollern, darunter populäre Boards wie den ESP32, ESP8266, Arduino UNO und viele andere. Es erleichtert das Erstellen von Programmen für diese Mikrocontrollerplattformen, da es spezielle Funktionen und Bibliotheken für die Hardwaresteuerung bietet, die in MicroPython verwendet werden können.
- Mit Thonny können Sie MicroPython-Code schreiben, der die Funktionen des Mikrocontrollers steuert, wie das Lesen von Sensordaten, das Steuern von Motoren oder das Kommunizieren mit anderen Geräten über verschiedene Schnittstellen wie I2C, SPI oder UART.
- Es ist wichtig zu beachten, dass Thonny nicht ausschließlich auf MicroPython beschränkt ist. Es unterstützt auch andere Programmiersprachen wie Python und kann für die allgemeine Python-Entwicklung verwendet werden. Für die Programmierung von Mikrocontrollern mit MicroPython ist Thonny jedoch eine beliebte IDE, die eine einfache und zugängliche Umgebung bietet.

# data[].attributes.attachment_caption
Beginners Guide to Arduino IDE and Arduino Programming

# data[].attributes.body
1. Alles, was Sie über Mikrocontroller wissen müssen | RS Components (rs-online.com)
2.ESP32 Wi-Fi & Bluetooth MCU I Espressif Systems
3. LCD am I<sup>2</sup>C-Bus beim Arduino (hm.edu)
4. wie funktioniert lcd display i2c - Google Suche
5. Leitfaden für Einsteiger in die Arduino-IDE und Arduino-Programmierung (circuitdigest.com)
6.Übersicht | CircuitPython-Bibliotheken auf jedem Computer mit Raspberry Pi Pico | Adafruit Lernsystem
7.nawi-werft.de/bausteine/i2c-display/
8.Leuchtdiode – Wikipedia
9.Thonny: Der anfängerfreundliche Python-Editor (codeflow.site)
10. https://www.educative.io/answers/what-is-the-difference-between-python-and-micropython
11. https://randomnerdtutorials.com/esp32-webserial-library/

# data[].attributes.attachment_link.readable_text
What is the Arduino IDE? As we know we need a text/code editor to write the code, a compiler to convert that code to machine code or binary files so that the microcontroller can understand, and also programming software to load these firmware files onto the microcontroller. When we combine all these with some additional features like debugging support, console support, etc, that's what we call an IDE (Integrated Development Environment) or in simple terms the Arduino Software. Arduino IDE, as the name states, is a development IDE for the Arduino boards. It consists of a feature-rich code editor, compiler, programmer, serial console, serial plotter, and many other features. It is simple and easy to use.

Arduino IDE is cross-platform, and it can run on operating systems from Microsoft, Linux, and Windows. Furthermore, you can program the boards using the Arduino IDE and Arduino Language, which is a derivative of C/C++.

How to Install Arduino IDE?

Installing Arduino IDE is pretty straightforward. Go to Arduino IDE to download the recent version of Arduino IDE. There are multiple versions available for different operating systems such as Windows, Mac, and Linux. Not only that, nowadays Arduino IDE comes in two variants Arduino IDE 1.x and Arduino IDE 2.x. For this tutorial, we will be talking about the Classic 1.X variant. Basically, both have almost same functionality with a different GUI plus some additional features such as auto code completion.

Download the installer for your operating system from the above-given link.

Once the download is done open the .exe file.

Agree to the licence agreement and select if the IDE should be installed to all users or not and click on "Next" to continue.

Select the location in which you want the IDE to install if you want to change the location or keep it default and click on "Install"

Wait for the installer to finish installation, and click on "Close".

Arduino Driver Installation

One common question that everyone gets when starting with Arduino Software is about the board driver installation. But the truth is that you don't have to worry about it. The installer will load all the necessary files to the computer and will install the drivers automatically as soon as you connect the board to the computer.

Connecting Arduino Board to the Computer

To connect the Arduino board to the computer, simply connect the appropriate cable to the Arduino board and connect the other end to the USB port of your PC. The power LED will glow indicating the board is powered. The system will automatically install the driver for the board.

Arduino IDE - Basics

After the Arduino IDE installation, you can launch the Arduino IDE by double-clicking the Arduino IDE shortcut on the Desktop or from the Start Menu. Now the Arduino IDE will be opened. The below image shows the Arduino IDE interface.

Selecting the right Board on Arduino

Now let's select the proper board. It is very important to select the proper board before compilation because the compiler will use this in the compile directives. To do that Click on the "Tools" -> "Board" -> "Arduino AVR Boards" and select your board from it.

Select the Arduino Serial Port

It's also important to select the proper serial port to which the Arduino board is connected. Otherwise, you won't be able to upload the code to the board. To do that click on "Tools" -> "Port" And select the correct COM port. If there are multiple COM ports and you are not sure which one to select, disconnect the Arduino board from the USB port and reopen the menu. The COM port entry that disappeared will be the correct COM port. Reconnect the Board to the same USB port and select that port.

Arduino Example Codes

To start with we will be using the LED Blink example that is already provided with the Arduino IDE. To open the Blink example, go to Files -> Examples -> Basics -> Blink.
Example Blink Program for Arduino
Let's open an example code to understand it further. For that click on File -> Examples -> Basics -> Blink.

A new window with the example blink code will be open. In the code area, you can see two functions, void setup() and void loop(). The void setup() function is the first function that will run when the Arduino is powered on. Normally we will add any initialization codes in this function. The void loop() will run in a loop, and we will add any code that needed to be repeated to this function.

As mentioned earlier, in the void setup() function there is an initialization code.

pinMode(LED_BUILTIN, OUTPUT);

In this line with pinMode(), we set the pin which is connected to the built-in LED as an output. pinMode() is used to set a specific pin as INPUT or OUTPUT. The syntax is pinMode (pin, mode). In which pin is the pin number, and the mode is INPUT or OUTPUT. In the example we are setting the built-in LED pin, i.e., is pin number 13, which is defined in the Arduino board definition file, to an output.

Void loop () {
digitalWrite (LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
delay(1000);                       //wait for a second
digitalWrite(LED_BUILTIN, LOW);   //turn the LED off by making the voltage Low
delay(1000);                     // wait for a second
}

If we look at the Loop function, we are calling two functions repeatedly digitalWrite() and delay().

The digitalWrite() function is used to change the state of a specific pin, i.e. we change the pin's state to high or low. The syntax is digitalWrite(pin, value) in which the pin is the corresponding pin number and the value is the state or value we want to set to the pin, i.e., HIGH or LOW.

The delay() function is a blocking function to pause a program from doing a task during the specified duration in milliseconds. For example delay(1000) will pause the program for 1000millisecods.

In the blink example, after the pin is set as an output, we set the pin as HIGH and wait for 1000ms. After the 1000ms, we change the pin state to LOW and again wait for 1000ms or 1 second. After the 1Second pause, the program will change the pin state back to HIGH and this loop will repeat continuously. As a result, we will get a square wave out from that pin. When we connect an LED to this pin, the LED will blink. The rate of blinking can be changed by changing the delay, by changing the values in the delay() function.

Uploading Code on Arduino

To upload the code to confirm that the Arduino is plugged in and the correct board and port are selected, either click the upload button in the quick action bar or click on Sketch -> Upload. Or you can also you the keyboard shortcut Ctrl+U.

If everything went correctly you will see a Done uploading message in the status bar and the LED will start to blink.

# data[].attributes.attachment_link.keywords[]
getting started with arduino programming

# data[].attributes.attachment_link.title
Beginners Guide to Arduino IDE and Arduino Programming

# data[].attributes.attachment_link.description
What is the Arduino IDE? As we know we need a text/code editor to write the code, a compiler to convert that code to machine code or binary files so that the microcontroller can understand, and also programming software to load these firmware files onto the microcontroller.

# data[].attributes.attachment_link.readable_text
LCD am I²C-Bus beim Arduino
Prof. Jürgen Plate

LCD am I²C-Bus beim Arduino

Allgemeines

Die gängigen Dot-Matrix-LCDs mit einer Zeichenmatrix von 5x8 Pixeln haben zwei oder vier Zeilen mit je 16 oder 20 Zeichen. Die Kontakte sind meist einreihig mit 16 Polen, es gibt aber auch Displays mit seitlich zwei Reihen. Die Kontakte sind üblicherweise von links nach rechts mit 1 bis 16 nummeriert. Zumindest ist der Pin 1 markiert. An den Kontakten 15 und 16 ist normalerweise die Hintergrundbeleuchtung (LED) angeschlossen. Die Zuordnung von Anode und Kathode ist oft nicht immer eindeutig. Hier hilft nur ausprobieren. Ganz frühe LCDs hatten nur einen 14-poligen Anschluss, die Hinterleuchtung wurde an separaten Pins mit Energie versorgt. Es gibt in seltenen Fällen auch eine 15-polige Anschllussleiste, bei der die Kathode der LED mit dem GND-Anschluss des Controllers verbunden ist und Pin 15 an die Anode der LED angeschlossen ist. Hintergrundinfos zu LCD finden Sie im Skript zu Displays.

Ob die Hintergrundbeleuchtung eventuell einen Vorwiderstand benötigt, ist von Modell zu Modell verschieden. Im Zweifelsfall muss man auch hier ausprobieren, indem ein Widerstand von 470 Ω zwischen 5 V und LED geschaltet wird. Durch Messen des Stroms kann man dann auf einen internen Widerstand schließen.

Die folgende Tabelle zeigt die gängigste Pin-Belegung eines üblichen Text-LCDs. Leider gibt es auch Anzeigen, bei denen die Stromversorgungsanschlüsse (Pins 1 und 2) vertauscht sind. Also auf jeden Fall einen Blick ins Datenblatt werfen.

Pin Display

Funktion

Beschreibung

Pin Arduino

Bemerkung

Bemerkungen:

Pin 3 dient der Kontrastregelung. Hierzu dient ein 10kΩ-Potenziometer. An den mittleren Anschluss kommt Pin 3, die beiden äußeren Anschlüsse des Potenziometers werden an +5 V und GND angeschlossen.

Der Pin 5 (Read/Write) wird meist fest mit GND verbunden, da fast alle Programmbibliotheken und schreiben und kein Busy-Signal vom LCD auslesen. Deshalb werden an den notwendigen Stellen in der Bibliothek delay()-Aufrufe eingebaut.

Die Pins 7, 8, 9 und 10 werden meist nicht genutzt und das Display im 4-Bit-Modus angesteuert. Anstelle von einmal 8-Bit schickt der Arduino also zweimal vier Bits zum Display. So werden vier Datenleitungen eingespart.

Die Pin 15 und 16 dienen der LED-Hintergrundbeleuchtung. Je nach Modell sind diese unterschiedlich belegt.

Bei den LCDs mit zweireihigem 14-poligen Anschluss sind die Pinnummern meist der Bedruckung auf der Oberseite zu entnehmen. Die Pin 15 und 16 für die Versorgung der LED-Hintergrundbeleuchtung sind meist auf der gegenüber liegenden Seite zu finden. Die Pinbelegung entsprichtim Übrigen der Tabelle oben.

Achtung: Beim Anschluss-Schema von Displays mit zweireihigem Steckverbinder sind bei einigen Displays die Anschlüsse Vdd und Vs vertauscht! Das müssen Sie beachten, wenn Sie beispielsweise das Controllerboard getrennt vom Display beschaffen und das Display selbst anlöten. Lesen Sie vor dem Anschließen auf jeden Fall das Datenblatt.

Die üblichen LCD-Anzeigen sind in der Regel mit einem Hitachi HD44780 Controller (oder einem oder kompatiblen Typ) und dem Displaytreiber HD44100 asgerüstet. Sie erlauben maximal 80 Stellen, was bedeutet, dass das größte Display der Typ mit 4x20 Zeichen (alternativ 2x40 Zeichen) ist. Displays mit mehr Stellen werden über mehrere Controller angesteuert.

Das "klassische" LCD am Arduino

Wie oben schon angedeutet, kann solch ein LCD kann im 4-Bit- oder 8-Bit-Modus angesprochen werden, dementsprechend werden vier oder acht Datenleitungen benötigt, die an die digitalen Pins des Arduino angeschlossen werden. Um Leitungen zu sparen, wird meist der 4-Bit-Modus verwendet. neben der Stromversorgung und der Kontrastregelung werden sechs digitale Leitungen benötigt, da die R/W-Leitung des Displays fest mit GND verbunden ist. Eine übliche Belegung ist:

RS des LCD an Digital-Pin 12

E des LCD an Digital-Pin 11

D4 des LCD an Digital-Pin 5

D5 des LCD an Digital-Pin 4

D6 des LCD an Digital-Pin 3

D7 des LCD an Digital-Pin 2

Die Library für das LCD ist in der Arduino-IDE enthalten. Es muss also nichts installiert werden. Beim Programmieren ist nur die Pinbelegung zu achten, die davon abhängt, wie das LCD angeschlossen wurde. Diese Belegung wird beim Erzeugen eines LCD-Objekts mitgegeben:

#include <LiquidCrystal.h<  // Bibliothek LiquidCrystal einbinden
// Pin-Zuordnung: RS  E   D4 D5 D6 D7
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Objekt erzeugen

Im Setup wird die Displaykonfiguration übergeben. Die beiden Parameter stehen für die Zeichen pro Zeile und die Zeilenanzahl. In diesem Beispiel 20 Zeichen und 2 Zeilen:

lcd.begin(20, 2);

Die LCD-Bibliothek ist in der über die Hilfe-Funktion der Arduno-IDE erreichbare Referenz gut dokumentiert. Unter Datei → Beispiele → LiquidCrystal finden Sie etliche Beispiele, die ebenfalls in der Referenz beschrieben sind. Deshalb folgt hier nur ein einfaches "Hello World"-Programm:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
  {
  lcd.begin(20,4);  // setze LCD auf 20 Zeichen und 4 Zeilen
  lcd.clear();
  lcd.setCursor(0, 0);      // Cursor auf Position 1, Zeile 1 (0, 0)
  lcd.print("Hello World"); // Ausgabe Text an LCD
  }

void loop()
  {
  lcd.setCursor(0, 1);      // Cursor auf Position 1, Zeile 2 (0, 1)
  lcd.print(millis()/1000); // Anzahl der Sekunden seit dem Start
  delay(1000);              // Warten
  }

Neben den Beispielen der Arduino-IDE gibt es genügend Infos im Web zu finden, so dass hier das obige Beispiel genügen soll.
LCD per I²C am Arduino

Wesentlich Leitungsökonomischer ist der Anschluss eines Dot-Matrix-LCDs über den I ²C-Bus. Hier werden nur vier Leitungen benötigt: +5 V, GND, SDA und SCL. Natürlich bedarf dazu das LCD einer Erweiterung der Hardware. Mit Hilfe des I ²C-I/O-Portexpanderbausteins PCF8574 läßt sich das LCD ansteuern. Dieser Baustein bietet acht bidirektionale Portleitungen, die man einzeln über den I ² C-Bus gesetzt und abgefragt werden können.

Belegung des PCF8574

A0 – A2: Auswahl der I2C Bus Adresse

P0 – P7: Digitale I/O Ports

SDA: Datenleitung – Verbindung zum I2C Bus

SCL: Taktleitung – Verbindung zum I2C Bus

INT: Interrupt Ausgang

VDD: +5 V

VSS: GND

Die Erweiterung muss man auch nicht selbst bauen, sondern es gibt sie als fertiges Modul zum Aufstecken oder auch bereits komplett mit Display. Die winzige Platine besitzt vier Anschlüsse auf der rechten Seite (GND, VCC; SDA, SCL) und einen Jumper auf der Linken Seite, mit dem die Hintergrundbeleuchtung abgeschaltet werden kann. Auch das Potenziometer für die Kontrastregelung ist mit auf der Patine. Die I ² C-Displays werden von verschiedenen Unternehmen angeboten, einfach mal bei Ebay oder Amazon nachsehen.

Über drei Lötbrücken kann die I ² C-Adresse des Moduls eingestellt werden. Per Default sind alle Verbindungen offen, wodurch das Modul über die Adresse 0x27 angesprochen werden kann. Über Jumper oder Lötbrücken können sieben weitere Adressen eingestellt werden.

Aber auch der Nachbau wäre nicht schwierig. Die Schaltung besteht praktisch nur aus dem Portexpander PCF8574 und dem Potenziometer für den Kontrast (was im folgenden Bild weggelassen wurde).

Je nachdem, welchen Arduino-Typ Sie verwenden, müssen die Leitungen SDA und SCL des LCD an unterschiedliche Ports des Arduino angeschlossen werden:

Bei der Verdrahtung (siehe Schaltbild oben) hält man sich am besten au das Schema der kommerziell angebotenen Boards.

Für die Programmierung des I ²C-Moduls benötigt man eine Library, die nicht in der Arduino-IDE vorinstalliert ist. Diese kann unter https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library als ZIP-Datei heruntergeladen werden. Danach fügt man die Library in der Arduino-IDE zu den vorhandenen Bibliotheken hinzu. Dies wird unter dem Menüpunkt Sketch → Bibliothek einbinden → .ZIP Bibliothek hinzufügen erledigt. Danach kann die Bibliothek im Code verwendet werden. Nach Aufruf der Arduino-IDE findet man in den Beispielen zu LiquidCrystal_I2C drei Beispiele. Hier soll als erstes Beispiel eine übliche "Hello-World"-Variante dienen:

#include <Wire.h>  // binde Bibliothek Wire fuer I2C ein
#include <LiquidCrystal_I2C.h> // binde Bibliothek LiquidCrystal_I2C ein

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 4 Zeilen

void setup()
  {
  lcd.begin();                // initalisiere LCD
  lcd.backlight();           // Hintergrundbeleuchtung an
  lcd.clear();
  lcd.setCursor(0, 0);      // Cursor auf Position 1, Zeile 1 (0, 0)
  lcd.print("Hello World"); // senden Nachricht an LCD
  }

void loop()
  {
  lcd.setCursor(0, 1);      // Cursor auf Position 1, Zeile 2 (0, 1)
  lcd.print(millis()/1000); // zeige Anzahl Sekunden seit Start
  delay(500);
  // Display aus, Info bleibt erhalten
  lcd.noDisplay();
  delay(500);
  // Display an, Info wird angezeigt
  lcd.display();
  }

Die ersten drei Zeilen brauchen Sie bei jedem Programm, das mit dem I ²C-Modul arbeitet. Die Bibliotheksfunktionen sind jenen der Standard-LCD-Libraryp nachempfunden, so dass die Programme beider Schaltungsvarianten laufen, sofern man die richtigen Bibliotheken einbindet und die Funktion init() entsprechend anpasst. Als kleines Extra wird gezeigt, wie man das Display ein- und ausschalten kann, ohne die angezeigte Info zu verlieren.

Programmierung

In diesem Abschnitt werden einige Beispielprogramme gezeigt, die demonstrieren sollen, das man auch mit einem so einfachen Display einige interessante Dinge anstellen kann. Das erste Programm soll Sie einstimmen und es soll als Schema für Ihre eigenen ersten Versuche dienen.

Früher oder später werden Sie bemerken, dass die deutschen Umlaute nicht mit dem Zeichensatz Ihres PC übereinstimmen. Es gibt zwar eine Variante des LCD-Controllers mit dem "passenden" Zeichensatz (ROM Code A02), aber im Handel gibt es meist nur die Standardvariante (ROM Code A00), deren Zeichensatz die folgende Tabelle zeigt:

Wie Sie sehen, werden alle Zeichen in einer 5x8 Pixel großen Matrix dargestellt. Die Spalte 1 der Zeichentabelle oben (RAM Character Generator) erlaubt die Definition eigener Zeichen-Bitmuster. Dieses Feature wird in den folgenden Beispielen mehrfach genutzt. Die erste Anwendung des programmierbaren Zeichengenerators ist die Definition der groß geschriebenen Umlaute.

Umlaute darstellen

Die Umlaute ä, ö, ü, ß und das Grad-Zeichen sind im Zeichensatz des LCD-Controllers enthalten, sie stehen nur leider an einer anderen Stelle. Im Programmcode kann man das mit einigen Zeilen abfangen und die Zeichencodes konvertieren. Eine Funktion für die klein geschreibenen Umlaute sieht beispielsweise so aus:

char Umlaut(byte ascii)
  {
  switch (ascii)
    {
    case 228: return  225; break; // ä
    case 246: return  239; break; // ö
    case 252: return  245; break; // ü
    case 223: return  226; break; // ß
    case 176: return  223; break; // grad
    default:  return  ascii; break;
    }
  }

Für Ä, Ö und Ü müssen eigene Zeichen für das LCD definiert werden. Die Methode in der Library heisst lcd.createChar(num, bitarray), wobei num der Zeichencode zwischen 0 und 7 ist.bitarray ist ein Array, das die Bitdefinition beinhaltet. Diese Definition stellt ein Zeichen als Muster von 5x8 Pixeln als Gruppe von 8 Zeilen zu je 5 Bits dar. Das folgende Bild zeigt den Aufbau am Beispiel des Buchstabens 'R':
Das Array für dieses Zeichen würde definert als:

byte Auml[8] =  { B11110, B10001, B10001, B11110, B10100, B10010, B10001, B00000 };

Das folgende Programm definiert die Zeichenmuster für die Umlaute Ä, Ö und Ü als Arrays. Diese Zeichendefinition wird dann mittels lcd.createChar() in der Funktionsetup() ins LCD geladen. In der Hauptschleife werden für den Test ASCII-Zeichen von der seriellen Schnittstelle eingelesen und auf das Display ausgegeben. Der Aufruf der Umcodierungfuntion wird in die Ausgaberoutine eingebettet, der Aufruf autet dann:lcd.write(Umlaut(Serial.read())).

#include <Wire.h>  // binde Bibliothek Wire ein
#include <LiquidCrystal_I2C.h> // binde Bibliothek LiquidCrystal_I2C ein

// Bitmuster fuer grosse Umlaute
byte Auml[8] =  { B01010, B00000, B01110, B10001, B10001, B11111, B10001, B10001 };
byte Uuml[8] =  { B01010, B00000, B10001, B10001, B10001, B10001, B10001, B01110 };
byte Ouml[8] =  { B01010, B00000, B01110, B10001, B10001, B10001, B10001, B01110 };

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 4 Zeilen

char Umlaut(byte ascii)
  {
  switch (ascii)
    {
      case 228: return  225; break; // ä
      case 246: return  239; break; // ö
      case 252: return  245; break; // ü
      case 223: return  226; break; // ß
      case 196: return  0; break;   // Ä
      case 214: return  2; break;   // Ö
      case 220: return  1; break;   // Ü
      case 176: return  223; break; // grad
      default:  return  ascii; break;
    }
  }

void setup()
  {
  Serial.begin(9600);
  lcd.begin();                // initalisiere LCD
  lcd.backlight();           // Hintergrundbeleuchtung an
  lcd.createChar(0, Auml);   // Umlaute definieren
  lcd.createChar(1, Uuml);
  lcd.createChar(2, Ouml);
  lcd.clear();
  }

void loop()
  {
  if (Serial.available())
    {
    // bisserl warten
    delay(100);
    // clear the screen
    lcd.clear();
    // zeichenweise ausgeben
    while (Serial.available() > 0)
      {
      lcd.write(Umlaut(Serial.read()));
      }
    }
  }

Balkengrafik

Waagrechte Balkengrafik geht recht einfach, indem man das Leerzeichen nimmt und das Zeichen mit dem Code 255, ein "Klötzchen", das eine Displayposition voll ausfüllt. So kann man waagrechte Balken mit 16 oder 20 Stellen darstellen. Bei vertikalen Balken wird es etwas komplizierter. Dafür werden acht neue Zeichen definiert. Das erste Zeichen hat eine gefüllte Zeile ganz unten, das zweite dann schon zwei Zeilen von unten usw. Das letzte definierte Zeichen ist dann komplett gefüllt. Das kann man aus der Arraydefinition im Listing unten schön erkennen. Um die Programmierung kompakter zu machen, werden nicht wie bei den Umlauten einzelne Arrays definiert, sondern ein zweidimensionales 8x8-Array. Die Methode lcd.createChar() kann dan in einer Schleife aufgerufen werden.

Um den Balken mit n Linien auszugeben, genügt der Befehl lcd.write(i), wie es im Beispielprogramm gezeigt wird. Da acht Werte aber nur eine recht grobe Auflösung haben, gibt es die Funktion Balken(), die eine Auflösung von 16 Linien hat und in zwei aufeinanderfolgenden Zeilen ausgegeben wird. Neben dem auszugebenden Wert kann der Funktion noch Zeile und Spalte des Displays übergeben werden (beginnend bei 0). Die Ausgabe erfolgt dann in der angegebenen Zeile und der Zeile darunter.

#include <Wire.h>  // binde Bibliothek Wire ein
#include <LiquidCrystal_I2C.h> // binde Bibliothek LiquidCrystal_I2C ein

// Balkengrafik-Muster
byte bar[8][8] = {
  { B00000,B00000,B00000,B00000,B00000,B00000,B00000,B11111 },  // 0
  { B00000,B00000,B00000,B00000,B00000,B00000,B11111,B11111 },  // 1
  { B00000,B00000,B00000,B00000,B00000,B11111,B11111,B11111 },  // 2
  { B00000,B00000,B00000,B00000,B11111,B11111,B11111,B11111 },  // 3
  { B00000,B00000,B00000,B11111,B11111,B11111,B11111,B11111 },  // 4
  { B00000,B00000,B11111,B11111,B11111,B11111,B11111,B11111 },  // 5
  { B00000,B11111,B11111,B11111,B11111,B11111,B11111,B11111 },  // 6
  { B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111 }}; // 7

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 4 Zeilen

void Balken(int value, int zeile, int spalte)
  {
  // 16-Schritte-Balkengrafik ausgeben
  // zeile gibt die Displazeile an, wobei die Ausgabe in
  // der angegebenen Zeile und der darunterliegenden erfolgt
  // spalte gibt die displayspalte des Balkens an
  char upper, lower;

  if(value < 8)
    { upper = ' '; lower = value; }
  else
    { upper = value - 8; lower = 7; }
  lcd.setCursor(spalte, zeile); // Obere Haelfte ausgeben
  lcd.write(upper);
  lcd.setCursor(spalte, zeile + 1); // Untere Haelfe ausgeben
  lcd.write(lower);
  }

void setup()
  {
  int i;

  Serial.begin(9600);
  lcd.begin();             // initalisiere LCD
  lcd.backlight();        // Hintergrundbeleuchtung an
  for(i = 0; i < 8; i++)  // Balken definieren
    lcd.createChar(i, bar[i]);
  lcd.clear();

  lcd.print("Hello ");
  for(i = 0; i < 8; i++)
    {
    lcd.write(i);  // Alle einzeiligen Balken darstellen
    delay(200);
    }
  for(i = 15; i >= 0; i--)
    {
    Balken(i, 2, i); // Alle zweizeiligen Balken darstellen
    delay(200);
    }
  }

void loop()
  {
  // Nix
  }

Das folgende Programmstück gibt beispielsweise einen Wert als Balken aus, der über den analogen Eingang 0 eingelesen wurde:

int wert = analogRead(0);
byte code = map(wert, 0, 1023,0,16); // proportionalen Wert zwischen 0 und 15 ermitteln
Balken(code, 0, 0); ;

Große Ziffern

Durch die geschickte Definition und Kombination von Grafiksymbolen lassen sich größere Symbole darstellen. Dazu werden fünf Grafiksymbole definiert, die so kombiniert werden können, dass sich mit ihnen große Ziffern darstellen lassen. Die Symbole haben folgende Muster und sind im Array pattern abgelegt, wobei das letzte Muster nicht zum Darstellen von Ziffern dient, sondern den "großen" Dezimalpunkt definiert.

byte pattern[5][8] = {
  { B11111,B11111,B00000,B00000,B00000,B00000,B00000,B00000 }, // 0
  { B00000,B00000,B00000,B00000,B00000,B00000,B11111,B11111 }, // 1
  { B11111,B11111,B00000,B00000,B00000,B00000,B11111,B11111 }, // 2
  { B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111 }, // 3
  { B00000,B00000,B00000,B00000,B00000,B01110,B01110,B01110 }};// 4

Jede große Ziffer belegt zwei Zeilen und setzt sich aus sechs der Grafiksymbole zusammen, drei für die obere und drei für die untere Hälfte. Die Arrays DigitsTop und DigitsBot definieren, aus welchen Grafiksymbolen die oberen und unteren Zeilen auf dem LCD zusammengesetzt sind. Auf dem LCD sehen die Zahlen dann so aus:
Bei der Definition kommen nur die Symbole 0 bis 3 vor. Wo alle Pixel dunkel sein sollen, steht ein Leerzeichen, das unten mit seiner ASCII-Codierung 32 auftaucht:

const char DigitsTop[10][digitWidth]={
   {3,0,3}, {0,3,32}, {2,2,3}, {0,2,3}, {3,1,3},
   {3,2,2}, {3,2,2},  {0,0,3}, {3,2,3}, {3,2,3}};
const char DigitsBot[10][digitWidth]={
   {3,1,3}, {1,3,1}, {3,1,1},   {1,1,3}, {32,32,3},
   {1,1,3}, {3,1,3}, {32,32,3}, {3,1,3}, {1,1,3}};

Im folgenden Beispielprogramm sind die beiden Arrays in der Funktion showDigit() definiert. Diese Funktion stellt eine große Ziffer (Parameterdigit) an der durchzeile und spalte vorgegebenen Position dar, wobei diese Werte bereits in den Dimensionen der großen Ziffern rechnen. So würde beispielsweisezeile = 0 die Displayzeilen 0 und 1 belegen zeile = 1 dementsprechen die Displayzeilen 2 und 3. Analog würde der Wertspalte = 3 die Displayspalten 10 bis 13 belegen.
Das Programm zeigt zuerst alle darstellbaren Ziffern und realisiert dann eine Digitaluhr für Minuten und Sekunden.

#include <Wire.h>  // binde Bibliothek Wire ein
#include <LiquidCrystal_I2C.h> // binde Bibliothek LiquidCrystal_I2C ein

// Breite der grossen Ziffern (Anzahl Stellen)
#define digitWidth 3
// Hoehe der grossen Ziffern
#define digitHeight 2

// Muster, aus denen die grossen Ziffern zusammengesetzt werden
byte pattern[5][8] = {
  { B11111,B11111,B00000,B00000,B00000,B00000,B00000,B00000 },  // 0
  { B00000,B00000,B00000,B00000,B00000,B00000,B11111,B11111 },  // 1
  { B11111,B11111,B00000,B00000,B00000,B00000,B11111,B11111 },  // 2
  { B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111 } , // 3
  { B00000,B00000,B00000,B00000,B00000,B01110,B01110,B01110 }}; // 4

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 4 Zeilen

void showDigit(int digit, int zeile, int spalte)
  {
  // Stellt eine grosse Ziffer dar. Die Position wird
  // durch zeile und spalte festgelegt, wobei diese
  // Werte bereits in den Dimensionen der Ziffern rechnen
  // zeile=0 belegt z. B. die Displayzeilen 0 und 1, zeile=1
  // entsprechen die  Displayzeilen 2 und 3.
  // Ebenso wuerde der Wert spalte=3 die Displayspalten
  // 10 bis 13 belegen.

  byte i;
  // Arrays zur Indexierung der selbstdefinierten Zeichen,
  // aus denen die großen Ziffern bestehen
  const char DigitsTop[10][digitWidth]={
     {3,0,3}, {0,3,32}, {2,2,3}, {0,2,3}, {3,1,3},
     {3,2,2}, {3,2,2},  {0,0,3}, {3,2,3}, {3,2,3}};
  const char DigitsBot[10][digitWidth]={
     {3,1,3}, {1,3,1}, {3,1,1},   {1,1,3}, {32,32,3},
     {1,1,3}, {3,1,3}, {32,32,3}, {3,1,3}, {1,1,3}};

  lcd.setCursor(spalte*(digitWidth + 1), zeile*digitHeight);
  for(i = 0; i < digitWidth; i++)
    lcd.write(DigitsTop[digit][i]);
  lcd.setCursor(spalte*(digitWidth + 1), zeile*digitHeight + 1);
  for(i = 0; i < digitWidth; i++)
    lcd.write(DigitsBot[digit][i]);
  }


void setup()
  {
  int i;

  Serial.begin(9600);
  lcd.begin();                 // initalisiere LCD
  lcd.backlight();            // Hintergrundbeleuchtung an
  for(i = 0; i < 5; i++)      // Sonderzeichen definieren
    lcd.createChar(i, pattern[i]);
  lcd.clear();

  for(i = 4; i >= 0; i--)
    {
    showDigit(i, 0, i);
    delay(500);
    }
  for(i = 9; i >= 5; i--)
    {
    showDigit(i, 1, i-5);
    delay(500);
    }
  lcd.clear();
  }

void loop()
  {
  byte j, k;

  j = 0; k = 0;

  for (;;)
    {
    showDigit(j/10, 0, 0);
    showDigit(j%10, 0, 1);
    lcd.setCursor(digitWidth*2 + 1, 0);
    lcd.write(4);
    lcd.setCursor(digitWidth*2 + 1, 1);
    lcd.write(4);
    showDigit(k/10, 0, 2);
    showDigit(k%10, 0, 3);
    delay(1000);
    k++;
    if (k == 60)
      { j++; k = 0; }
    if (j == 60)
      j = 0;
    }
  }

Ein letztes Beispiel, das hier nicht aufgelistet ist, zeigt die Anwendung diverser anderer Displayfunktionen (siehe Links).
Links

Copyright © Hochschule München, FK 04, Prof. Jürgen Plate
Letzte Aktualisierung:

# data[].attributes.attachment_link.keywords[]
hardware basteln löten programmierung arduino lcd liquidcrystal i2c

# data[].attributes.attachment_link.description
Prof. Jürgen Plate Die gängigen Dot-Matrix-LCDs mit einer Zeichenmatrix von 5x8 Pixeln haben zwei oder vier Zeilen mit je 16 oder 20 Zeichen. Die Kontakte sind meist einreihig mit 16 Polen, es gibt aber auch Displays mit seitlich zwei Reihen. Die Kontakte sind üblicherweise von links nach rechts mit 1 bis 16 nummeriert.

# data[].attributes.attachment_link.title
wie funktioniert lcd display i2c - Google Suche

# data[].attributes.headline
C. Intelligenter Behälter mit Kontrollstation 

# data[].attributes.subject
C. Intelligenter Behälter mit Kontrollstation 

# data[].attributes.body
1. Mikrocontroller ESP32
2. Ultraschallsensor HC-SR04
3. Powerbank 5V Output

# data[].attributes.body
1. Microcontroller ESP8266
2. Raspberry Pico Pi
3. LCD-Display I2C
4. Bewegungsmelder
5. LED (rot, gelb, grün)
6. Powerbank 5 V

# data[].attributes.body
- Die Server-Client-Architektur ist ein gängiges Kommunikationsmodell in der Informatik. Es besteht aus zwei Hauptkomponenten: dem Server und dem Client. Der Server bietet einen Dienst an, während der Client den Dienst nutzt.

- Der Server ist ein Computer oder ein Programm, das auf einem Computer läuft und bestimmte Ressourcen oder Dienste bereitstellt. Er hört auf eingehende Anfragen von Clients und reagiert entsprechend. Der Server ist normalerweise immer eingeschaltet und wartet auf Anfragen von Clients.

- Der Client ist ebenfalls ein Computer oder ein Programm, das auf einem Computer läuft und eine Verbindung zum Server herstellt, um bestimmte Dienste oder Ressourcen zu nutzen. Der Client sendet Anfragen an den Server und erwartet eine Antwort. Der Client kann auf verschiedenen Geräten ausgeführt werden, wie z.B. einem Computer, einem Smartphone oder einem Mikrocontroller.

Bei der Auswahl von Server- und Client-Komponenten gibt es einige wichtige Faktoren zu beachten:

1. Anforderungen: Klären Sie die Anforderungen an Ihre Anwendung. Welche Art von Dienstleistungen oder Ressourcen werden benötigt? Muss der Server eine große Anzahl von gleichzeitigen Verbindungen unterstützen? Muss die Kommunikation sicher sein? Basierend auf Ihren Anforderungen können Sie die geeigneten Server- und Client-Technologien auswählen.

2. Kommunikationsprotokoll: Wählen Sie das geeignete Kommunikationsprotokoll für Ihre Anwendung. Es gibt verschiedene Protokolle wie HTTP, MQTT, TCP/IP usw. Stellen Sie sicher, dass sowohl der Server als auch der Client das ausgewählte Protokoll unterstützen.

3. Plattformkompatibilität: Überprüfen Sie, ob die gewählten Server- und Client-Technologien auf den Plattformen lauffähig sind, auf denen Ihre Anwendung ausgeführt wird. Stellen Sie sicher, dass es für Ihre Plattform entsprechende Bibliotheken oder APIs gibt.

4. Skalierbarkeit: Wenn Sie erwarten, dass Ihre Anwendung in Zukunft wächst und mehr Benutzer oder Clients unterstützen muss, wählen Sie eine Server- und Client-Architektur, die skalierbar ist. Stellen Sie sicher, dass der Server skalierbar ist, um mit der steigenden Anzahl von Clients umzugehen.

5. Sicherheit: Wenn Sicherheit ein wichtiger Aspekt Ihrer Anwendung ist, stellen Sie sicher, dass der gewählte Server- und Client-Mechanismus Sicherheitsfunktionen wie Verschlüsselung, Authentifizierung und Autorisierung unterstützt.

6. Bei der Auswahl von Server- und Client-Komponenten ist es wichtig, Ihre spezifischen Anforderungen und die Art Ihrer Anwendung zu berücksichtigen. Überlegen Sie, welche Funktionen, Skalierbarkeit und Sicherheit erforderlich sind, um die besten Entscheidungen zu treffen.

# data[].attributes.body
JPG Schaltplan

# data[].attributes.body
JPG Steckplan

# data[].attributes.body
Schaltplan ESP und Pico Pi + Zusatz - Datei

# data[].attributes.body
Bei der Verwendung der Arduino IDE gibt es einige wichtige Dinge zu beachten:

1. Boardauswahl: Stellen Sie sicher, dass Sie das richtige Arduino-Board in der IDE auswählen. Wählen Sie das Board aus, das Sie tatsächlich verwenden, da verschiedene Boards unterschiedliche Spezifikationen und Pins haben.

2. Portauswahl: Überprüfen Sie, ob der richtige serielle Port für Ihr Arduino-Board ausgewählt ist. Der Port ermöglicht die Kommunikation zwischen dem Computer und dem Board. Stellen Sie sicher, dass das Board ordnungsgemäß mit dem Computer verbunden ist und der richtige Port ausgewählt ist.

3. Hochladen des Sketches: Bevor Sie Ihren Sketch auf das Arduino-Board hochladen, vergewissern Sie sich, dass der Sketch korrekt kompiliert wurde und keine Fehler oder Warnungen auftreten. Überprüfen Sie den Kompiliervorgang in der Ausgabe der IDE, um sicherzustellen, dass alles reibungslos verläuft.

4. Serielle Überwachung: Die Arduino IDE bietet eine serielle Überwachungsfunktion, mit der Sie Nachrichten und Daten von Ihrem Arduino-Board über den seriellen Port empfangen können. Überprüfen Sie die serielle Ausgabe, um sicherzustellen, dass Ihr Code wie erwartet funktioniert und die richtigen Informationen sendet.

5. Bibliotheken: Die Arduino IDE unterstützt eine Vielzahl von Bibliotheken, die zusätzliche Funktionen und Möglichkeiten bieten. Wenn Sie eine Bibliothek verwenden möchten, stellen Sie sicher, dass Sie sie korrekt installiert und in Ihrem Sketch eingebunden haben. Überprüfen Sie auch die Dokumentation der Bibliothek, um deren Verwendung und Funktionen zu verstehen.

6. Versionskontrolle: Wenn Sie Ihre Arduino-Sketches verwalten und überwachen möchten, können Sie Versionskontrollsysteme wie Git verwenden. Dadurch können Sie Änderungen nachverfolgen, verschiedene Versionen verwalten und bei Bedarf auf frühere Versionen zurückkehren.

7. Fehlerbehebung: Wenn Ihr Sketch nicht wie erwartet funktioniert oder Fehler auftreten, überprüfen Sie Ihren Code sorgfältig auf Tippfehler, fehlende Semikolons, ungültige Zuweisungen oder andere Syntaxfehler. Verwenden Sie auch die serielle Überwachung und Debugging-Techniken, um den Fehler zu isolieren und zu beheben.

Es ist wichtig, dass Sie sich mit den Funktionen und Tools der Arduino IDE vertraut machen, um effektiv damit arbeiten zu können. Die IDE bietet viele Funktionen und Optionen, um Ihre Arduino-Projekte zu entwickeln und zu testen. Nehmen Sie sich Zeit, um die Dokumentation zu lesen und die verfügbaren Ressourcen zu nutzen, um das Beste aus Ihrer Arbeit mit der Arduino IDE herauszuholen.

# data[].attributes.body
Arduino-Sketch-Sprache:
Die Arduino-Sketch-Sprache ist eine vereinfachte Programmiersprache, die speziell für die Arduino-Plattform entwickelt wurde. Sie basiert auf der Programmiersprache C/C++, wurde jedoch um einige Funktionen und Bibliotheken erweitert, um die Programmierung von Arduino-Projekten zu erleichtern.

Ein Sketch ist der Begriff für ein Arduino-Programm. Ein Sketch besteht aus einer oder mehreren Funktionen, die von der Arduino-IDE erkannt und in der richtigen Reihenfolge ausgeführt werden. Der Sketch wird in der Arduino-IDE geschrieben, kompiliert und dann auf das Arduino-Board hochgeladen.

Der Sketch besteht aus zwei grundlegenden Funktionen:

1. setup(): Diese Funktion wird einmal beim Start des Programms aufgerufen und wird verwendet, um die anfängliche Konfiguration des Boards und der verwendeten Komponenten einzurichten.

2. loop(): Diese Funktion wird immer wieder in einer Endlosschleife aufgerufen, nachdem die setup()-Funktion abgeschlossen ist. Hier wird der Hauptcode für Ihr Arduino-Projekt geschrieben. Der Code in der loop()-Funktion wird immer wieder ausgeführt, bis das Programm beendet oder das Board ausgeschaltet wird.

In der Arduino-Sketch-Sprache können Sie auf eine Vielzahl von Arduino-Bibliotheken und Funktionen zugreifen, die spezielle Aufgaben erleichtern, wie z. B. das Steuern von Pins, das Kommunizieren mit Sensoren und Aktoren, das Verarbeiten von Daten und vieles mehr.

Das Arduino-Board kann über die USB-Schnittstelle mit einem Computer verbunden werden, um den Sketch hochzuladen und die Serielle Kommunikation für Debugging und Ausgabe von Daten zu ermöglichen.

# data[].attributes.attachment_link.readable_text
Displays dienen zur Anzeige von Informationen. Dazu muss das Display eingeschaltet sein. Sinnvoll ist das aber nur, wenn sich gerade jemand vor dem Display befindet. Wenn nicht ist das ein unnötiger Stromverbrauch. Deshalb gibt es die Idee, eine Person vor dem Display zu erkennen und das Display zu aktivieren. Wird nach einiger Zeit keine Person vor dem Display erkannt, wird das Display abgeschaltet. Das wäre praktisch eine lokale Anwesenheitserkennung für das Display.

In der folgenden Lösung wollen wir einen PIR Motion Detector vom Typ HC-SR501 für die Anwesenheitserkennung verwenden und ein HD44780-kompatibles LCD mit I2C-Modul steuern.

Wenn das Deine ersten Versuche mit einem PIR Motion Detector und einem HD44780-kompatiblen LCD mit I2C-Modul sind, dann solltest Du Dich zuerst über die Besonderheiten dieser Bauteile informieren. Außerdem empfiehlt es sich zuerst mit den einzelnen Bauteilen Erfahrungen zu sammeln.

Aufbau und Bauteile

Raspberry Pi Pico

HC-SR501

Raspberry Pi Pico

LCD (I2C)

Programmcode

Dreh- und Angelpunkt der softwareseitigen Ansteuerung des 1602-Displays mit der I2C-Schnittstelle sind zwei Python-Bibliotheken. Eine für den I2C und das andere für das Display selber. Die beiden folgenden Dateien müssen heruntergeladen und auf dem Pico gespeichert werden:

Damit hast Du die softwareseitigen Voraussetzungen zur Ansteuerungen des Displays erfüllt.

Im Programmcode wird der GPIO-Pin für den PIR Motion Detector, der I2C-Bus und das Display initialisiert. Anschließend wird ein Text auf dem Display beispielhaft ausgegeben.
Im weiteren Programmcode werden zwei Funktionen definiert. Eine, um das Display einzuschalten und die andere, um das Display auszuschalten. Wobei hier nicht das Display selber ein- und ausgeschaltet wird, sondern nur die Hintergrundbeleuchtung.
Die Einschaltfunktion wird über einen Interrupt aufgerufen, wenn eine Bewegung durch den PIR-Sensor registriert wird.
Die Ausschaltfunktion wird über eine Timersteuerung aufgerufen. In der Ausschaltfunktion wird das Display aber nur dann tatsächlich ausgeschaltet, wenn der PIR-Sensor in Ruhe ist. Also keine Bewegung erkannt wird.

# Bibliotheken laden
from time import sleep
from machine import I2C, Pin, Timer
from machine_i2c_lcd import I2cLcd

# Initialisierung des PIR-Moduls
pir = Pin(22, Pin.IN, Pin.PULL_DOWN)

# Initialisierung I2C
i2c = I2C(0, sda=Pin(20), scl=Pin(21), freq=100000)

# Initialisierung LCD über I2C
lcd = I2cLcd(i2c, 0x27, 2, 16)

# Display-Zeilen ausgeben
lcd.putstr('Hello World')

# Funktion: Display einschalten
def display_on(pin):
    lcd.backlight_on()

# Funktion: Display ausschalten
def display_off(timer):
    pir_value = pir.value()
    print(pir_value)
    if pir_value == 0:
        lcd.backlight_off()

# Initialisierung Interrupt für die Bewegungserkennung
pir.irq(trigger=Pin.IRQ_RISING, handler=display_on)

# Timer für die Display-Abschaltung nach Zeit
tim = Timer(freq=0.05, mode=Timer.PERIODIC, callback=display_off)

Funktionen prüfen

1. Display-Abschaltung: Beim Starten des Programms sollte das Display angehen und auch anbleiben. Die Frage ist, ob sich das Display nach einiger Zeit abschaltet. Die Abschaltung erfolgt natürlich nur, wenn keine Bewegung vom PIR Motion Sensor erkannt wird. Dazu ist es erforderlich den Sensor in eine Richtung zeigen zu lassen, in der er definitiv keine Bewegung registrieren kann. Nach einiger Zeit sollte das Display ausgehen und auch ausbleiben.

2. Display bleibt an: Wenn die Display-Abschaltung funktioniert ist zu prüfen, ob das Display auch anbleibt, wenn jemand sich vor dem Display befindet. Dazu drehst Du den PIR Motion Sensor zu Dir hin. Das Display sollte die ganze Zeit anbleiben, auch wenn Du Dich nicht viel und nicht oft bewegst.

Wenn das alles ohne Probleme funktioniert hat, dann hast Du vermutlich nicht lange genug geprüft oder einfach wahnsinnig viel Glück gehabt. Dazu ein paar Beobachtungen, Erklärungen und hilfreiche Lösungsvorschläge.

Beobachtungen und Erklärungen

Die Frequenz des Timers im Programmcode ist vermutlich zu groß. Die gewählte Frequenz ist zum Testen und Experimentieren gedacht. Du willst schließlich wissen, ob das Display zeitnah ausgeht. Wenn das Display länger anbleiben soll, dann muss die Zeit verlängert werden. Das bedeutet, der Wert der Frequenz muss kleiner werden.

Die Anwesenheitserkennung mit einem PIR Motion Detector lebt davon, dass sich jemand bewegt. Wenn sich jemand vor dem Display befindet, der Sensor aber keine Bewegung registriert, weil die Person bewegungslos ist, dann geht das Display trotzdem aus. Bei einer Bewegung geht das Display zwar gleich wieder an, aber die irrtümliche Abschaltung kann trotzdem nervig sein.

Es gibt zwei Möglichkeiten das zu lösen. Man verlängert die Zeit bzw. verkleinert den Parameter „freq" des Timers, der die Abschaltung auslöst. Alternativ bestünde die Möglichkeit die Dauer der Zustandshaltung der Bewegungserkennung am linken Potentiometer (Kuppel zeigt nach oben) zu verlängern.

Darf es ein bisschen mehr sein?

Genau genommen ist eine Anwesenheitserkennung mit einem PIR-Sensor eher untauglich. Weil eine Anwesenheit nicht zwangsläufig bedeutet, dass eine Bewegung stattfinden muss. Aber ein PIR-Sensor braucht eine Bewegung um eine Anwesenheit feststellen zu können.
Eine Alternative zur Anwesenheitserkennung mit PIR-Sensor ist eine Abstandsmessung. Zum Beispiel mit einem Ultraschallsensor.

Weitere verwandte Themen:

Hardware-nahes Programmieren mit dem Raspberry Pi Pico und MicroPython

Das Elektronik-Set Pico Edition ist ein Bauteile-Sortiment mit Anleitung zum Experimentieren und Programmieren mit MicroPython.

LED: Einschalten, ausschalten, blinken und Helligkeit steuern

Taster: Entprellen und Zustände anzeigen

LED mit Taster einschalten und ausschalten

Ampel- und Lauflicht-Steuerung

Elektronischer Würfel

Eigene Steuerungen programmieren

Elektronik-Set jetzt bestellen Online-Workshop buchen

Online-Workshop

Hardware-nahes Programmieren mit dem Raspberry Pi Pico

Gemeinsam mit anderen und unter Anleitung experimentieren? Wir bieten unterschiedliche Online-Workshops zum Raspberry Pi Pico und MicroPython an. Einführung in die Programmierung, Sensoren programmieren und kalibrieren, sowie Internet of Things und Smart Home über WLAN und MQTT.
Online-Workshop buchen
Für Ihre Fragen zu unseren Online-Workshops mit dem Raspberry Pi Pico besuchen Sie unseren PicoTalk (Online-Meeting). (Headset empfohlen)
Zum PicoTalk

# data[].attributes.attachment_link.title
Raspberry Pi Pico: Anwesenheitserkennung für ein Display mit PIR Motion Detector (HC-SR501)

# data[].attributes.attachment_link.description
Displays dienen zur Anzeige von Informationen. Dazu muss das Display eingeschaltet sein. Sinnvoll ist das aber nur, wenn sich gerade jemand vor dem Display befindet. Wenn nicht ist das ein unnötiger Stromverbrauch. Deshalb gibt es die Idee, eine Person vor dem Display zu erkennen und das Display zu aktivieren.

# data[].attributes.attachment_link.readable_text
Raspberry-Pi-Projekte: PIR Bewegungsmelder HC-SR501
Prof. Jürgen Plate

Raspberry Pi: PIR Bewegungsmelder HC-SR501

Allgemeines

Mittlerweile gibt es passive Bewegungsmelder für einige Euro bei Ebay, Amazon und anderen Händlern. Solche Bewegungsmelder laufen unter der Bezeichnung "PIR-Sensor", wobei "PIR" für "Passive Infra Red" (passiver Infrarot-Sensor) steht. Solche Infarot-Bewegungsmelder (meist nur "Bewegungsmelder" genannt) dienen oft zum automatischen Einschalten von Beleuchtung etc. Sie erkennen eine bestimmte Menge an Infarotstrahlen/Wärme) und werten diese Information aus. Schlicht gesagt, reagieren Sie auf die Wärme des menschlichen Körpers (oder auch von Hund, Katze usw.). Damit aber nicht staische Wärmequellen (besonntes Fenster, Heizkörper etc.) den Senso triggern, regieren solche Sensoren auf bewegliche Wärmequellen. Damit das funktioniert, ist eine Fesnel-Linse vor dem Sensor augeordnet. Das folgende Bild zeigt den PIR-Sensor auf der Platine und daneben die abgenommene Fresnel-Linse.

Die im Handel erhältliche Sensorplatine HC-SR501 hat eine Reichweite von etwa 7 Metern und einen Erfassungswinkel von ca. 120 Grad. Die Platine trägt die Auswerte-Elekronik mit dem IC BISS0001 und einen 3,3-V-Spannungsregler, was den Vorteil hat, dass sich das Ausgsangssignal direkt in den Raspberry Pi einspeisen lässt. Auf der Platine befinden sich neben den Anschlusspins noch zwei Potenziometer und ein Jumper. Die folgenden Bilder zeigen die Vorder- und Rückseite der Platine. Das Bild darunter einen Schaltplan, der aber nicht ganz der HC-SR501 entspricht. Hier ist noch ein Fotowiderstand (Cos2) enhalten, der die Ausgabe deaktiviert, wenn es hell genug ist - die Schaltung ist speziell für Beleuchtungszwecke gedacht.

Anschluss und Einstellung

Der Anschluss ist denkbar einfach. Es gibt nur drei Anschlusspins, +5 V, GND und Ausgang. Der Ausgang liefert 0 V, wenn keine Bewegung erkannt wird und +3,3 V, wenn sich vor dem Sensor eine Wärmequelle bewegt. Zm Verdrahten mit dem RasPi nimmt man am Besten drei Jumperkabel mit jeweils einer Buchse am Ende. Die Pins auf der Platine des Moduls sind mit "GND", "OUT" und "+5V" bezeichnet.

Die Einstellung des PIR-Moduls erfolgt über zwei Potenziometer und einen Jumper (siehe Bild unten). Mit dem linken Potenziometer ("Time") wird die Haltezeit des Moduls nach dem Erkennen einer Wärmequelle eingestellt. Mit dem rechten Potenziometer ("Sensitive" stellt man die Empfindlichkeit und damit auch die Reichweite des Sensors ein. Der Jumper dient der Einstellung der Arbeitsweise: In der unteren Stellung wird bei jeder erkannten Bewegung ein Impuls erzeugt. Wenn also jemand beisielsweise am Sensor vorbei geht, gibt es im Sekundenabstand Impulse, solange sich die Person innerhalb der Reichweite des Sensors befindet. In der oberen Stellung des Jumpers liefert der Sensor nur einen Impuls, abhängig von der Dauer der Haltezeit. Dies ist auch meist der Dfault-Wert.

Programmierung

Für die folgenden Programme wird das PIR-Modul auf "ein Impuls pro Erkennung" (Default) eingestellt. Die Haltezeit stellen Sie auf den minimalen Wert (Potenziometer auf Linksanschlag). Denken Sie auch daran, dass wegen des Zugriffs auf den GPIO-Pin eventuell Root-Rechte nötig sind.

Das erste Programm demonstriert die Bearbeitung der Impulse von PIR-Modul. Dazu muss eine kleine State Machine mit zwei Zuständen programmiert werden, da die Einschaltzeit relativ lang ist. Würde man nur den Zustand des GPIO-Pins abfragen, bekäme man im Ruhezustand immer eine "0" und bei aktivem PIR für längere Zeit dauernd eine "1". Es gilt also:

1. Nach dem Start warten, bis der PIR-Sensor in Ruhe ist (warten auf "0"). Die Zustandsvariable wird auf "0" gesetzt.

2. Ist die Zustandsvariable == 0 warten, bis der Sensor eine "1" liefert und dann die Zustandsvariable auf "1" setzen.

3. Ist die Zustandsvariable == 1 warten, bis der Sensor eine "0" liefert und dann die Zustandsvariable auf "0" setzen.

Das Ganze läuft in einer Endlosschleife ab, wobei bei jedem Schleifendurchlauf eine Pause (mittels time.sllep()) eingelegt wird, damit das Programm nicht zu viel Rechenzeit aufnimmt. Das Python-Programm liefert beim Erkennen der Bewegung nur die Meldung "Bewegung erkannt!". Hier kann man natürlich noch weitere Aktionen programmieren, etwa ein BIld mit der Kamera aufnehmen, das Licht einschalten etc.

#!/usr/bin/python
import RPi.GPIO as GPIO
import time

# BCM GPIO-Referenen verwenden (anstelle der Pin-Nummern)
# und GPIO-Eingang definieren
GPIO.setmode(GPIO.BCM)
GPIO_PIR = 4

print "PIR-Modul gestartet (CTRL-C to exit)"

# Set pin as input
GPIO.setup(GPIO_PIR,GPIO.IN)

# Initialisierung
Read  = 0
State = 0

try:
  print "Warten, bis PIR im Ruhezustand ist ..."

  # Schleife, bis PIR == 0 ist
  while GPIO.input(GPIO_PIR) != 0:
    time.sleep(0.1)
  print "Bereit..."

  # Endlosschleife, Ende mit STRG-C
  while True:
    # PIR-Status lesen
    Read = GPIO.input(GPIO_PIR)

    if Read == 1 and State == 0:
      # PIR wurde getriggert
      print "Bewegung erkannt!"
      # Zustand merken
      State = 1
    elif Read == 0 and State == 1:
      # PIR wieder im Ruhezustand
      print "Bereit..."
      # Zustand merken
      State = 0

    # kleine Pause
    time.sleep(0.1)

except KeyboardInterrupt:
  # Programm beenden
  print "Ende..."
  GPIO.cleanup()

Statt des Wartens in einer Schleife besteht die Möglichkeit, den Daten-Pin so zu initialisieren, dass eine Veränderung, genauer ein Wechsel von "0" auf "1", an das Skript übergeben wird. Dazu wird dann eine Callback-Funktion Motion() zum Auslesen des Pinzutands definiert, die beim Auftreten einer positiven Flanke automatisch aufgerufen wird. Der Vorteil dabei ist, das der Code nicht ständig den Pin-Status überprüft, sondern schläft, bis etwas passiert.

#!/usr/bin/python

import RPi.GPIO as GPIO
import time
import datetime

# BCM GPIO-Referenen verwenden (anstelle der Pin-Nummern)
# und GPIO-Eingang definieren
GPIO.setmode(GPIO.BCM)
GPIO_PIR = 4

print "PIR-Modul gestartet (CTRL-C to exit)"

# Set pin as input
GPIO.setup(GPIO_PIR,GPIO.IN)

# Initialisierung
Read  = 0
State = 0

print "Warten, bis PIR im Ruhezustand ist ..."

# Schleife, bis PIR == 0 ist
while GPIO.input(GPIO_PIR) != 0:
  time.sleep(0.1)
print "Bereit..."

# Callback-Funktion
def MOTION(PIR_GPIO):
  print "%s - Bewegung erkannt!" % datetime.datetime.now()

print "%s - Warten auf Bewegung" % datetime.datetime.now()

try:
  # Ereignis definieren: steigende Flanke
  GPIO.add_event_detect(GPIO_PIR, GPIO.RISING, callback=MOTION)
  # laenger schlafen - Callback wird durch die Flanke aktiviert
  while True:
    time.sleep(60)

except KeyboardInterrupt:
  # Programm beenden
  print "Ende..."
  GPIO.cleanup()

Das Programm ist zudem kürzer als das erste.
Das dritte Programm ist eine C-Implementierung des ersten. Als Bibliothek wird hier wiringPi verwendet. Si könnten aber genausogut die auf der Seite über die GPIO-Programmierung in C vorgestellte Bibliothek oder die die bcm2835-Library verwenden.

/*
 * Program for PIR-Sensor.
 * Connect on board pin number 07 to Sensor
 *
 * gcc -Wall -o pir -l wiringPi pir.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <wiringPi.h>

/* Sensor auf GPIO 4, Pin 7, WiringPi 7 */
#define SENSOR 7

unsigned int state = 0;
unsigned int data  = 0;
struct sigaction sig_struct;

/* Signalhandler fuer STRG-C */
void  finish(int sig)
  {
  printf("Signal %d empfangen. Programm wird beendet.\n", sig);
  exit(0);
  }

int main(int argc, char **argv)
  {
  /* Initialisierung der Bibliothek */
  if (wiringPiSetup() == -1)
    {
    printf("Please run this as root\n");
    return EXIT_FAILURE;
    }

  /* Signalhandler fuer STRG-C einrichten */
  sig_struct.sa_handler = finish;
  sigemptyset(&sig_struct.sa_mask);
  sig_struct.sa_flags = 0;
  sigaction(SIGINT,&sig_struct,NULL);

  /* Sensor als Input definieren */
  pinMode(SENSOR, INPUT);

  while((data = digitalRead(SENSOR)) != 0)
    {
    /* Pause 0,1 Sekunde */
    usleep(100000);
    }

  printf("Bereit...\n");
  while (1)
    {
    data = digitalRead(SENSOR);
    if(data == 1 && state == 0)
      {
      printf("Bewegung erkannt - %d\n",(int)time(NULL));
      state = 1;
      }
    else if (data == 0 && state == 1)
      {
      printf("Bereit...\n");
      state = 0;
      }
    /* Pause 0,1 Sekunde */
    usleep(100000);
    }
  return EXIT_SUCCESS;
  }

Auch bei C kann man mit Flankenerkennung arbeiten, siehe oben genannte Webseite.
Links

Copyright © Hochschule München, FK 04, Prof. Jürgen Plate und die Autoren
Letzte Aktualisierung:

# data[].attributes.attachment_link.keywords[]
linux programmierung raspberry pi pir bewegungsmelder hc-sr501

# data[].attributes.attachment_link.description
Prof. Jürgen Plate Mittlerweile gibt es passive Bewegungsmelder für einige Euro bei Ebay, Amazon und anderen Händlern. Solche Bewegungsmelder laufen unter der Bezeichnung "PIR-Sensor", wobei "PIR" für "Passive Infra Red" (passiver Infrarot-Sensor) steht. Solche Infarot-Bewegungsmelder (meist nur "Bewegungsmelder" genannt) dienen oft zum automatischen Einschalten von Beleuchtung etc.

# data[].attributes.body
#Importiert Bibliotheken
import machine
import utime
from machine import UART
from time import sleep
from machine import Pin
from machine import I2C, Pin, Timer
from machine_i2c_lcd import I2cLcd

#Steuern die LEDs, Gpio 11-13)
ledRed = Pin(13, Pin.OUT)
ledYellow = Pin(12, Pin.OUT)
ledGreen = Pin(11, Pin.OUT)#

# Initialisierung des PIR-Moduls
pir = Pin(22, Pin.IN, Pin.PULL_DOWN)

# Initialisierung I2C
i2c = I2C(0, sda=Pin(20), scl=Pin(21), freq=100000)

# Initialisierung LCD über I2C
lcd = I2cLcd(i2c, 0x27, 2, 16)

#Zukunft Zimmer nummer mit senden
#zimmerNummer = -1

# Funktion: Display einschalten
def display_on(pin):
lcd.backlight_on()
#print("ON")

# Funktion: Display ausschalten
def display_off(timer):
#print("OFF")
lcd.backlight_off()

#len=Länge String oben
def writeToLCD(oben, unten = ""):
lcd.clear()
#whilschleife verlängert den String auf 16 Zeichen = benötigt um 2 Zeilen auf zu teilen
while len(oben) < 16:
oben += " "

lcd.putstr(oben + unten)
#display_on(0)

def setupUART():
writeToLCD("Init UART...")
sleep(1)
uart0 = UART(0, baudrate=9600, tx=machine.Pin(0), rx=machine.Pin(1), bits=8, parity=None, stop=1)#tx-Sendepin, rx-empfangspin,
#setCursor(1, 0)
if uart0:
writeToLCD("UART ready.")
else:
writeToLCD("UART ERROR!")
sleep(2)
return uart0

def printStatus(distance):
textUnten = ""
try:
distance = float(distance)
except ValueError:
return

prozent = (27.0- distance)/27.0
prozent = int(prozent * 100)
if prozent < 25:
textUnten = "Bitte auffuellen!"
ledRed.on()
ledYellow.off()
ledGreen.off()
elif prozent <75 and prozent >=25:
ledYellow.on()
ledRed.off()
ledGreen.off()
textUnten = "Kanuele: %d%%" % prozent
else:
textUnten = "Kanuele: %d%%" % prozent
ledRed.off()
ledYellow.off()
ledGreen.on()
zimmerNummer = 42
textOben = "Zimmer %d" % zimmerNummer
writeToLCD(textOben, textUnten)

def dataLoop(uart):
writeToLCD("Waiting for", "Input...")
sleep(1)
display_off(0)
while True:
rxData = uart.readline()
if rxData:
#dataString = rxData.lstrip().rstrip()
try:
dataString = rxData.decode("utf-8")
#lstrip links zeilenumbrüche entfernen, rechts genauso
dataString = dataString.lstrip().rstrip()
except UnicodeError:
print("Not a utf-8 string")
continue

print("Got data: '%s'" % dataString)
if dataString.startswith("Connected, IP address"):
ip = dataString.split(": ")[1]
writeToLCD("WiFi IP:", "%s" % ip)
#elif dataString.lower().startswith("zimmer "):
#    zimmerNummer = dataString.split(' ')[1]
#    writeToLCD("Neues Zimmer:", "Nummer: %s" % zimmerNummer)
#elif dataString.lower().startswith("prozent "):
#    prozent = int(dataString.split(' ')[1])
#    printStatus(prozent)
elif dataString.lower().startswith("no connection"):
writeToLCD("Keine", "Verbindung!")
elif dataString.lower().startswith("http error"):
writeToLCD("HTTP", "Fehler!")
elif dataString.lower().startswith("--"):
writeToLCD("Ungültiger", "Fuellstand!")
elif dataString.lower().startswith("dist:"):
try:
dataString= dataString.split(": ")[1]
printStatus(dataString)
except IndexError:
continue

sleep(1)

def setTimers():
# Initialisierung Interrupt für die Bewegungserkennung
pir.irq(trigger=Pin.IRQ_RISING, handler=display_on)

# Timer für die Display-Abschaltung nach Zeit
tim = Timer(freq=0.05, mode=Timer.PERIODIC, callback=display_off)

def _main():
ledRed.off()
ledYellow.off()
ledGreen.off()
#Display-Zeilen ausgeben
uart0 = setupUART()
setTimers()
dataLoop(uart0)

_main()

# data[].attributes.body
#include <ESP8266WiFi.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

const char* serverNameDist = "http://192.168.4.1/distance";

int INTERVAL = 5000;

void connectToWifi(){

WiFi.begin("ESP32-Access-Point", "123456789");

Serial.print("Connecting");

while (WiFi.status() != WL_CONNECTED)

{

delay(500);

Serial.print(".");

}

Serial.println();

Serial.print("Connected, IP address: ");

Serial.println(WiFi.localIP());

}

void setup()

{

Serial.begin(9600);

Serial.println();

Serial.println("Starting up...");

connectToWifi();

//pinMode(BLUE, OUTPUT);

//pinMode(LED_BUILTIN, OUTPUT);

//digitalWrite(LED_BUILTIN, HIGH);

//Serial.println("Device ready");

}

void loop() {

if(WiFi.status()== WL_CONNECTED ){

String distance = httpGETRequest(serverNameDist);

if(distance.equals("error")){

delay(5000);

return;

}

Serial.print("dist: ");

Serial.println(distance);

}

else {

Serial.println("No connection!");

connectToWifi();

}

delay(INTERVAL);

}

String httpGETRequest(const char* serverName) {

WiFiClient client;

HTTPClient http;

http.begin(client, serverName);

// Send HTTP POST request

int httpResponseCode = http.GET();

String payload = "--";

if (httpResponseCode>0) {

//Serial.print("HTTP Response code: ");

//Serial.println(httpResponseCode);

payload = http.getString();

}

else {

Serial.println("HTTP Error!");

// Serial.println(httpResponseCode);

return ("error");

}

http.end();

return payload;

}

# data[].attributes.body
- Ein Mikrocontroller ist ein Halbleiterchip, der einen Prozessor und zugleich auch Peripheriefunktionen enthält. Er ist ein vollständig in sich geschlossenes System und wird in vielen Fällen in elektrischen Geräten eingesetzt. Der Unterschied zwischen einem Mikrocontroller und einem Mikroprozessor besteht darin, dass ein Mikrocontroller über zusätzliche Peripheriefunktionen verfügt.

- Er kann externe Signale über eine Vielzahl von Kommunikationsprotokollen erkennen und darauf reagieren.
- Einige der Funktionen eines  Mikrocontrollers sind: Timer zur Messung der Zeit, USART zur Übertragung von Daten, I/O-Ports für die Ein- und Ausgabe von Daten.

-Der ESP32 ist ein leistungsstarker Mikrocontroller, der sowohl Wi-Fi als auch Bluetooth-Konnektivität bietet. Mit seinem Dual-Core-Prozessor bietet er hohe Rechenleistung. Er verfügt über digitale und analoge Ein- und Ausgänge sowie verschiedene Schnittstellen für die Kommunikation mit anderen Geräten.
- Der ESP32 ermöglicht drahtlose Kommunikation und ist in der Lage, mit anderen Geräten zu interagieren.

# data[].attributes.headline
E.  Verkabelung ESP32  Ultraschallsensor HC-SR04 

# data[].attributes.subject
E.  Verkabelung ESP32  Ultraschallsensor HC-SR04 

# data[].attributes.body
- Keliane und Hanifes klein Projekt mit Display und Pulssensor erfolgreich beendet. Code funktioniert!
- Code Austausch/ Briefing
- Neu Idde: Behälter mit Display geliehen + Bewegung Sensor wird von Janine aufgebaut+ Bargraph zu Behälter eingebaut
- Bis nächste mal: LED in neue Behälter erneuern, Prototyp für Behälter+server-client umstellung+bargraph einbau

# data[].attributes.body
-wifi Verbindung mit 2 ESPs hergestellt
- Janine hat micro Pi +displey+esp+LED Verbindung hergestellt
- LED Ampelfunktion eingebaut
- Ausgabe in % - neue Idee!
- Briefing stattgefunden
-

# data[].attributes.body
- Deep sleep an ESP eingebaut hat funktioniert, Anpassung fehlt
-  Batterie die ESP versorgen soll muss noch organisiert werden, wir brauchen mind 5V Versorgung  min 3 Batterien verkabeln oder powerbank
- Fragerunde und Austausch infos Stattgefunden. Briefing
- Fathema und Keliane arbeiten dazu noch in einem kleinem Projekt Displey+Pulssensor + Pi

# data[].attributes.body
- Microkont. und Ultraschall Verbindung durch Arduino Programm hergestellt (richtige Bibliotheken heruntergeladen) - - passende Code geschrieben
-Janine hat Prototyp für Behälter gebaut
- Wir haben festgelegt welche Batterie zu Behälter einheit gehört
-

# data[].attributes.body
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
const int trigPin = 5;
const int echoPin = 18;
//define sound speed in cm/uS
#define SCHALL_SPEED 0.03432
long dauer;
float distanzCm;
// Set your access point network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
String readDist() {

// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds
dauer = pulseIn(echoPin, HIGH);

// Calculate the distance
distanzCm = (dauer/2) * SCHALL_SPEED;
return String(distanzCm);
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input

Serial.println();

// Setting the ESP as an access point
Serial.print("Setting AP (Access Point)…");
// Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/distance", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDist().c_str());
});

// Start server
server.begin();
}

void loop(){

}

# data[].attributes.headline
Projekt Idee/Was können wir alternativ machen?

# data[].attributes.subject
Projekt Idee/Was können wir alternativ machen?

# data[].attributes.body
- Mikrokontroller+ PC Verbindung hergestellt
- Arduino+Microkontroller Verbindung hergestellt
- Deep sleep funktion kennengelernt und nachgeforscht
- Janine hat sich Aufgabe gemacht, Prototyp Behälter zu basteln
- Behälter soll erst mit Makaroni oder Bohnen gefüllt werden( wenn jem andere Idee hat, bitte hier ändern und in Komment erwähnen)

# data[].attributes.body
- HC-sr04,  Ultsensor, 2Mikrokontroller (ESP32+ESP8266) bekommen
-Pi mit hc-sr04 verkabelt und in Python Programm geschrieben um zu Funktionalität zu prüfen
- Mikrokontroller versucht mit PC zu verbinden -gescheitert!

# data[].attributes.body
- Team festgelegt
- Microkontroller Funktionen geforscht
- Adulino Programm kennengelernt
-

# data[].attributes.body
- Idee festgelegt/Skizze
- Mit Herr Bossle besprochen
- Messesensoren geforscht
- Andere Teile festgelegt

# data[].attributes.body
1. Projekt und Plan erstellung  bis 26.04

2. WhatsApp+Team+Aufgabenverteilung 3.05
3. Mikrocontroller+HC-sr40+ESP Verbindung  bis 10.05
4. Sleep Deep +Microkontroller ESP +Battery+1Fragerunde bis 17.05
5. Display+Led+Mikrocontroller ESP +2Fragerunde bis 24.05
6. Prototypen feststellen+im Lauf bringen 30.05
7. Dokumentation+Presentation+3Fragerunde bis 5.06

# data[].attributes.attachment_link.readable_text
In diesem Beitrag stelle ich dir vor wie du deinen Microcontroller mit ESP8266 Chip in den „Deep Sleep" versetzt und somit deine externe Stromversorgung schonst.

Einen Microcontroller mit ESP8266 Chip habe ich unter anderem bereits in den Beiträgen:

vorgestellt.

Jedoch möchte ich hier den Wemos D1 mini verwenden, dieser kleine Microcontroller hat den Vorteil das Sensoren auf diesen gesteckt werden können ohne das man diese recht umständlich verkabeln muss.

Was ist der „deep sleep"?

Von einem „deep sleep" redet man wenn der Microcontroller in einen Schlafmodus versetzt wird. In diesem Modus verbraucht dieser nur sehr wenig Strom und kann somit mit einer Batterie deutlich länger betrieben werden. In diesem Modus kann der Microcontroller jedoch nur gewisse Befehle und Aktionen ausführen. Zumeist sind die Befehle nur um einen Timer zu aktualisieren um nach einer Zeit x wieder in den Normalen Betrieb über zugehen.

Neben dem depp sleep welchen ich in diesem Beitrag vorstellen möchte, gibt es noch zwei weitere „Modem-sleep" und „Light-sleep". Im nachfolgenden zeige ich dir eine kleine Tabelle mit den groben Unterschieden der 3 verschiedenen Sleep Modi.

* Anhängig von der Implementierung

In diesem Beitrag zeige ich dir nun wie du einen Microcontroller mit einem ESP Chip in den Deep Sleep Modus versetzt und nach einer Zeit x wieder aufwecken kannst.

benötigte Resourcen

Um das nächste Beispiel nachprogrammieren zu können benötigst du einen Microcontroller mit einem ESP Chip und ein Breadboardkabel.

Aufbau der Schaltung für einen „Deep Sleep"

Der Microcontroller wird mit einem Befehl im Programm zum schlafen gebracht und durch einen weiteren Befehl wieder zum aufgeweckt. Was sich so einfach anhört ist es auch denn man muss nur den digitalen Pin D0 bzw. GPIO16 mit dem Reset Pin des ESP verbinden.

GPIO16 mit RST verbunden für den Deep Sleep am ESP8266

Diese Verbindung muss jedoch NACH dem Upload des Sketches auf dem Microcontroller hergestellt werden!

Hinweis

Ein Problem beim Deep Sleep ist, das die Daten nicht einfach auf Wunsch bereit stehen sondern nur in einem zuvor definierten Intervall abgerufen werden können.

Zum Beispiel könnte man einen DHT11 Sensor an den Microcontroller anschließen jedoch nicht beliebig die Daten abrufen, in diesem Fall würde man entweder die Daten auf eine SD Karte schreiben oder aber an einen Intranet / Internet Dienst zur späteren Auswertung senden. Eines dieser Internetdienste wäre ThingSpeak.com, wie du Daten an diesen Dienst sendest habe ich dir im Beitrag Iot Service ThingSpeak, einrichten und betreiben ausführlich erläutert.

Als erstes wollen wir in einem definierten Abstand einen Text auf der seriellen Schnittstelle ausgeben.

Sicherlich könnten wir dieses auch mit dem Befehl „delay" machen ABER dazu müsste der Microcontroller im betrieb bleiben und würde somit deutlich mehr Strom verbrauchen.

void setup() {
  //beginn der seriellen Kommunikation mit 74880 baud
  //Es könnte auch jeder andere gültige Wert gewählt werden,
  //jedoch wird über diesen Wert auch die Debugausgaben angezeigt
  Serial.begin(74880);
  //Timeout für die serielle Verbindung
  Serial.setTimeout(2000);
  //solange die serielle Schnittstelle nicht bereit ist, mache... (nix)
  while(!Serial) { }

  //Ausgabe des Textes inkl. der Millisekunden seit dem der Microcontroller gestartet ist.
  Serial.print("Hallo, ich bin wach. Der Microcontroller läuft seit ");
  Serial.print(millis());
  Serial.println(" Millisekunden.");
  Serial.println("Ich gehe gleich für 10 sek. in den Deep Sleep.");
  //den Microcontroller in den Deep Sleep für 10 Sekunden versetzen.
  ESP.deepSleep(10e6);
}

void loop() {
  //bleibt leer
}

Video

# data[].attributes.attachment_link.description
In diesem Beitrag stelle ich dir vor wie du deinen Microcontroller mit ESP8266 Chip in den „Deep Sleep" versetzt und somit deine externe Stromversorgung schonst. Einen Microcontroller mit ESP8266 Chip habe ich unter anderem bereits in den Beiträgen: vorgestellt.

# data[].attributes.attachment_link.description
Ultrasonic Sensor HC-SR04 is a distance measuring sensor. The sensor has one receiver and one transmitter. The transmitter sends a generated soundwave and re...

# data[].attributes.attachment_caption
BitBastelei #327 - Abstandsmessung per Ultraschall: HC-SR04 mit Arduino

# data[].attributes.headline
a. Abstandmessung per Ultraschallsensor 

# data[].attributes.subject
a. Abstandmessung per Ultraschallsensor 

# data[].attributes.attachment_link.title
BitBastelei #327 - Abstandsmessung per Ultraschall: HC-SR04 mit Arduino

# data[].attributes.body
- zu jedem Sensor Infos erstellen. Janine/Mura/Keliane

- Berichtführung Mura
- Aufgabenverteilung Alle
- Mailsteine anlegen Janine/Mura
- Deadline erstellen Mura
- Deadline Überwachung Fatema/Janine
- Prototyp erstellen Janine
- Code für Sensor Ult+ESP Mura
- Deep Sleep Funktion/Code einbauen Mura
- Code für Display+LED+ESP+Bewegungssensor+Pico Janine
- Code WLAN-Verbindung ESPs Mura/Janine
- Batterie (Akku) Versorgung Planung Janine
- Fragerunden/Fragen erstellen & bearbeiten Fatema/Keliane
- Handouts erstellen Mura/Keliane
- Literatur einfügen Keliane/Fatema
- Padlet pflegen Alle

# data[].attributes.body
1. Fatema Najafi
2. Keliane Bristine Mentsa
3. Janine Göhler
4. Mura Sherbekova

# data[].attributes.body
Der HC-SR04 Sensor misst mittels Ultraschall die Entfernung zu Objekten, somit ein Abstandmesssensor.  Er kann bis auf 3 mm genau messen und kann für eine Distanz von 2 cm bis zu 4 Meter eingesetzt werden. Er wird sehr gerne in der Robotertechnik eingesetzt, um damit berührungslos die Entfernung zu messen oder um den Füllstand von einem Behälter zu ermitteln.

- Ultraschallsensoren: Diese Sensoren verwenden Schallwellen. Der Sensor verfügt über einen Empfänger und einen Sender. Der Sender sendet eine erzeugte Schallwelle und der Empfänger empfängt reflektierten Ultraschall. Der Ultraschall wird mit 40 kHz ausgesendet und breitet sich durch die Luft aus. Anhand der Laufzeit und der Schallgeschwindigkeit kann die Entfernung bestimmt werden.
- Der Sensor besteht aus 4 Pins: VCC, TRIG, ECHO und GND.

- Der HC-SR04 hingegen benötigt typischerweise eine Betriebsspannung von 5 V und hat einen Stromverbrauch von etwa 15 mA während der Messung. Es ist wichtig, die Spezifikationen des HC-SR04-Sensors zu überprüfen, da es auch einige Varianten geben kann, die mit 3,3 V arbeiten.

# data[].attributes.body
1. Projekt- Worum es geht?

2. Team - Wer Was Macht?

3. Material -Microcontroller-UltSensor-WLAn verbindung- Displey-LED

4. Doku - Tagebuch-WhatsappGruppe-ZoomTermine- Präsentation-Deadlines Meilensteine festlegen