Praxisbericht Arduino - Zusatzhardware und Sensoren - Vorstellung und Beispiele

BAXL

Moderator
Mitarbeiter
Nachdem ich nun schon ein wenig mit dem Arduino "herumgespielt" habe, sind immer mehr Zusatzelektroniken zum Einsatz gekommen. Ich weiß, dass hier einige Kollegen sich ein Starterset gekauft haben, aber irgendwie nicht so richtig wissen wie sie es anstellen sollen, also wäre hier genau der richtige Platz, um den Einstieg etwas zu erleichtern.

An den Arduino kann man eine Reihe elektronischer Komponenten (Transistor, Diode, Fotoelemente usw.) quasi direkt anschließen und ohne größere Zusatzbeschaltung in Betrieb nehmen (evtl. mal ein Widerstand bei einer LED oder einem Transistor). Es gibt aber auch komplette Module (Relaismodule, Echtzeituhren, SD-Kartenleser usew.), die bereits eine aufwändigere Zusatzbeschaltung enthalten, um diese ebenfalls sehr einfach an den Arduino anschließen zu können. Diese Zusatzmodule werden entweder über Steckbrücken angeschlossen, oder in Form von so genannten Shields direkt auf die Arduinoplatine aufgesteckt.

In diesem Thema kann/darf/soll jeder von Bauteilen, Zusatzmodulen und Shields kurz berichte. Was kann die Hardware? Wozu verwendet man sie und wo ist sie ggf. erhältlich? Umfangreichere Erklärungen (gerne auch mit Anschluß- und Programmbeispiel) sind besser in eigene Themen unterzubringen, weil dazu sicher noch Nachfragen kommen können. Ein erster Überblick kann aber hier aufgeschrieben werden.

Gerne mache ich den Start.

Edit: Die Sensoren können auch für ESP8266 und Raspberry Pi genommen werden.

Übersicht: (einfach anklicken, dann gehts direkt zum Post)
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Der Temperatursensor LM35

In vielen Anwendungen ist eine Temperatur zu messen. Diese kann man einfach nur anzeigen lassen, oder für eine Steuerungsaufgabe aktiv auswerten und z.B. ein Relais ein und wieder ausschalten. Es gibt viele Messensoren, die zum Teil unterschiedlich funktionieren.

Dabei ist mir in der Anwendung als einfachste Variante der LM35 untergekommen. Der LM35 ist schon eine richtige Zusatzelektronik in einem transistorartigen Gehäuse. Er hat drei Beine und misst die Temperatur. In Abhängigkeit von der Temperatur gibt er eine Spannung aus, die man über einen analogen Eingang des Arduinos direkt messen kann. Eine besondere Zusatzbeschaltung ist nicht erforderlich. Die drei Anschlußbeine werden einmal an Plus 5V, an Masse und an einen analogen Port angeschlossen. Das braucht nur drei Verbindungsleitungen.

Den LM35 kann man z.B. bei Reichelt für rund einen Euro kaufen. Der angegbene Meßbereich ist von 0 - 150°C. Die Angabe unterscheiden sich manchmal, je nachdem, welche Variante des LM35 man erwischt. Gelegntlich wird als Maximaltemperatur auch nur 100°C angegeben. Bei 0°C gibt der LM35 eine Spannung von 0V aus. Pro Grad Celsius steigt die ausgegbene Spannung um 10 mV, also 0,01V. Bei 25°C wären das dann 250mV.

Bei funduino.de findet man ein Beispielprogramm, dass direkt in den Arduino geladen werden kann.
 

BAXL

Moderator
Mitarbeiter
Der Dallas DS18B20 Temperatursensor

Ein weiterer Vertreter für die Temperaturmessung ist der DS18B20. Auch dieser Sensor beinhaltet eine Komplette Mess- und Auswerteelektronik. Wie schon beim TMP36 benötigt man nur drei Anschlussleitungen und einen einfachen Widerstand von 4,7 kilo Ohm. Im Unterschied zum TMP36 wird aber keine auswertbare Spannung ausgegeben, sondern direkt ein Messwert als Zahl. Möglich wird das über die Art, wie der DS18B20 das Ergebnis an den Arduino übermittelt. Die Übermittlung erfolgt über eine Art serieller Kommunikation.

Angeschlossen wird wieder plus 5V, Masse und eine Leitung an einen digitalen Arduinopin.
Damit die Übermittlung elektrisch funktioniert, wird die Datenleitung des DS18B20 über den erwähnten 4k7 Widerstand an plus 5V angeschlossen.

Die Messwertübermittlung selbst wird in Form von Datenpaketen an den digitalen Pin gesendet. Aber keine Angst, für das Auslesen der Werte gibt es vorgefertigte Programmbibliotheken, die man einfach in das eigene Programm einbindet. Man muß dann nur noch die entsprechenden Funktionen in einer Programmzeile aufrufen. Auch dafür gibt es genügend Beispiele, die man einfach in die Programmieroberfläche des Arduinos kopiert und startet.

Natürlich kann man die Beispielprogramme 1:1 übernehmen, doch soll die Temperaturmessung nur ein kleiner Teil des eigenen Programms sein. Dazu sind ein paar Sachen erklärungswürdig. Doch das sprengt den Rahmen dieses Posts und wird von mir in einem eigenen Thema ausführlicher beschrieben.

Den Dallas DS18B20 bekommt man in allen einschlägigen Shops für rund 2€ das Stück. Ich habe meine Exemplare, die zudem noch wasserdicht sind und ein Kabel haben, bei AZ-Delivery gekauft, die versenden auch über Amazon. Link direkt zum Shop, Link zum Amazon-Shop.


Und so sehen die Dinger aus. Einmal als wasserdichte Version mit Anschlußkabel und im einfachen TO-Gehäuse. (das obere Bild symbolisch, es ist eigentlich der TMP36)





Wenn man ab und zu einen neuen Schwung Sensoren kauft, egal, ob im To Gehäuse oder als Kabelversion, muß man die Adressen jedes Sensors herausfinden.

Dafür reicht eine einfache Schaltung. Für meine Aktionen tut es ein Arduino Nano, zwei Klemmsteinemit Steckpins, damit man das auf einem Breadboard befestigen kann, ein 470 Ohm Widerstand, drei Steckbrücken und ein paar Zeilen Code.

#include <OneWire.h>

OneWire ds(3); // Anschluss an PIN 3

void setup(void) {
Serial.begin(9600);
discoverOneWireDevices();
}

void discoverOneWireDevices(void) {
byte i;
byte present = 0;
byte data[12];
byte addr[8];

Serial.print("Nach 1 Leitung Sensor suchen\n\r");
while(ds.search(addr)) {
Serial.print("\n\rGefunden \'1-Wire\' fuehler mit der Adresse:\n\r");
for( i = 0; i < 8; i++) {
Serial.print("0x");
if (addr < 16) {
Serial.print('0');
}
Serial.print(addr, HEX);
if (i < 7) {
Serial.print(", ");
}
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return;
}
}
Serial.print("\n\r\n\rDas war es... mehr kommmt nicht:)\r\n");
ds.reset_search();
return;
}

void loop(void) {
// nothing to see here
}





 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
PT100 / PT1000 Widerstände

Mit am einfachsten sind temperaturabhängige Widerstände. Das sind passive elektronische Bauteile, die bei Temperaturänderung auch ihren Widerstand verändern. Um damit messen zu können, benötigt man idR. einen weiteren Festwiderstand, der zusammen mit dem Messwiderstand einen Spannungsteiler bildet. Man misst dann den Spannungsfall am Messwiderstand. Weit verbreitet sind PT100 und PT1000 Messwiderstände, die aus Platin bestehen und ein relativ lineares Widerstandsverhalten bei Temperaturänderung haben.
Der Name PT100 und PT1000 kommt von dem Widerstandswert, den diese Widerstände bei 0°C haben. Der PT100 eben 100 Ohm und der PT1000 1000 Ohm bzw 1kOhm.
Die Widerstandsveränderung bzw. der Widerstand für eine bestimmte Temperatur, errechnet sich aus einer Formel, die man je nach Sensortyp leicht im Internet findet.
Für die Messung mit dem Arduino fließt dann noch die verwendete Spannung für den Spannungsteiler ein. Diese Sensoren sind je nach Ausführung günstig zu erhalten (PT100), können aber auch recht teuer werden (PT1000). Unterm Strich steht man sich preislich und beim messtechnischen Aufwand bei dem LM35 oder dem DS18B20 besser. Darum weite ich diese Sensoren hier nicht weiter aus. Wer aber Lust hat kann sich gerne damit auseinandersetzen und hier berichten :).
 

BAXL

Moderator
Mitarbeiter
Anzeigedisplay 2x16

Interessant wird es erst, wenn man gemessene Werte auch ohne die Hilfe des PCs anzeigen lassen kann. Das hat bei mir z.B. den Durchbruch bei der Motivation des Weitermachens gebracht. Ich dachte zuerst das sei sehr kompliziert, aber...

In einem zweiten Arduinoset, dass ich mir zwischenzeitlich gekauft hatte, war ein LCD-Display dabei, das 16 Zeichen in 2 Reihen darstellen kann. Und zwar so eins hier:



Man sieht schon einen Messwert angezeigt, den ich mit einem DS18B20 gemessen habe.

Die Krux ist die Ansteuerung. Man kann das umständlich machen, also mehrere Datenleitungen an das Display anschließen, oder man nimmt ein kleines Zusatzmodul (I2C-Converter), das nur Plus, Masse und zwei Datenpins benötigt. Dieser I2C-Converter erhält seine Steuersignal als serielles Datenpaket und leitet das dann umgewandelt an die Signalpinns des Displays weiter - vollautomatisch :) :



Auch hier ist die Ansteuerung sehr einfach. Man benötigt wieder eine kleine Programmbibliothek, die einem Funktionen für das Beschreiben des Displays zur Verfügung stellt. Es geht zwar auch "zufuß", allerdings bindet das einige Digitalausgänge des Arduinos mehr. Sowohl das Display, als auch die messensoren arbeiten über eine Art Bussystem, das es elaubt mehrere dieser Geräte parallel anzuschließen, ohne weitere Signalpins des Arduinos zu opfern.

So ein Display gibt es in unterschiedlicher Ausführung. Mal grün, mal blau, mal mit 2x16 Zeichen oder 4x20 Zeichen. Die Kosten halten sich im niedrigen Eurobereich. So ein 2x16 LCD-Display mit i2C-Converter kostet z.B. bei AZ-Delivery 2,99€. Ein 4x20 Display inkl. I2C-Converter kostet über Amazon 9€. Die Preise schwanken nur geringfügig, je nach Anbieter. AZ-Delivery nenne ich nur deshalb meistens, weil ich da die Sachen überwiegen kaufe und zu jedem Bauteil oder Modul eine ausführliche deutsche Beschreibung inkl. Beispielprogramm dazubekomme.

Hier zum Vergleich noch mal das 4x20 LCD-Display im Vergleich zum 2x16 Display.

 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
SD-Kartenleser und Echtzeituhr Shield

Wenn man es soweit geschafft hat Messwerte zu erfassen und auf einem Display anzuzeigen, kann man sich die ansehen und daran freuen. Möchte man diese Werte aber nutzen, wäre es nützlich diese zu konservieren und mit einem Zeitstempel zu versehen. Der Arduino bieten von Hause aus keine derartige Funktionalität. Doch dafür gibt es Zusatzmodule, natürlich mit entsprechenden Hilfsbibliotheken. Weil es mir einfach erschien, habe ich mir gleich ein komplettes Shield bestellt. Darauf ist ein Einschub für eine normalgroße SD-Karte, eine Echtzeituhr und ein kleines Lochrasterfeld, um ggf. eigene kleine Schaltungen darauf unterzubringen. Das Shield heißt DatenLogger Modul und kostet bei diversen Anbietern so zwischen 7 - 8 €. Diese Module (SD-Kartenleser, Echtzeituhr) gibt es auch getrennt. Das kann praktisch bei einem Einbau in ein Gehäuse sein. Würde man alle Zusatzmodule in Form eines Shields bestellen, hätte man irgendwann einen riesigen Stapel Platinen übereinandergesteckt :).

Das Shield sieht so aus:



Die Echtzeituhr läuft mit Datum und Uhrzeit, die SD-Karten sollten in FAT32 formatiert sein, damit diese erkannt, gelesen und beschrieben werden können.
Es gibt so ein paar Kleinigkeiten, die ich nur am Rande erwähnen möchte. Dateinamen können mit der verfügbaren Programmbiliothek (Library) nur Dateinamen im alten DOS-Format 8.3 bedienen. D.h., der Name kann nur 8 Zeichen und die Dateierweiterung nur 3 Zeichen lang sein. Es sollte auf Umlaute und Sonderzeichen (bis auf - und _) verzichtet werden.

Die Echteituhr liefert schon das Datum und die Uhrzeit zurück, aus irgendeinem Grund, den ich noch nicht herausgefunden habe, ist es schwierig bei einstelligen Monats-, Tages-, Sekunden-, Minuten- und Stundenzahlen, diese mit einer führenden Null auszugeben. Dafür ist ein gewisse Programmieraufwand nötig. Auf dem nachfolgenden Foto ist das an der Sekundenanzeige zu sehen. Es macht übrigens keinen Unterschied welches Ausgabemedium verwendet wird, die führenden Nullen sind nur mit Programmieraufwand möglich.



Schreibt man diese Angaben aber in eine Datei, dann kommt z.B. Excel damit trotzdem klar und ordnet das richtig zu. Natürlich muß die Uhr erst einmal gestellt werden. dazu gibt es Miniprogramme für den Arduino, in denen man die Zahlenwerte von Hand einträgt und hochlädt, oder aber, wenn die Uhr des PCs richtig stimmt, diese Daten übernimmt und an die Uhr übergibt. Ich habe letzteres verwendet.
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Anzeigedisplay 2004 / 4 Zeilen, 20 Zeichen



Im oberen Bild ist das 2004 Display bereits zu sehen. Für die Inbetriebnahme, habe ich einen meiner Arduino Nano Nachbauten genommen. Der erste Versuch, das Display einfach am Uno, an die Anschlüsse des 1602 zu stecken, hat leider nicht funktioniert. Scheinbar sind die verwendeten Bibliotheken nicht kompatibel. Beim 1602 brauchte ich nur die Displaygröße (16,2) in der Initialisierung angeben, beim 2004 musste dem I2C-Modul ebenfalls eine Pinreihenfolge übergeben werden. Wie sich die ergibt und was genau damit gemeint ist habe ich noch nicht herausgefunden. Gut dass ich eine Anleitung und einen Demosketch dafür hatte.

Man achte auch darauf, dass beim Befehl lcd.setcursor(s,z); der erste Wert die Spaltenposition ist und der zweite Wert die Zeile und dass dort bei 0 angefangen wird zu zählen. (0,0) ist dann (Spalte 1, Zeile 1)

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);

void setup() {

lcd.begin(20, 4);
lcd.clear();

lcd.setCursor(0,0);
lcd.print("Testtext Zeile 1");
lcd.setCursor(0,1);
lcd.print("Testtext Zeile 2");
lcd.setCursor(0,2);
lcd.print("Testtext Zeile 3");
lcd.setCursor(0,3);
lcd.print("Testtext Zeile 4");

}

void loop() {

lcd.setBacklight(HIGH);
delay(1000);
lcd.setBacklight(LOW);
delay(1000);
}

Hier geht es zu einem ausführlichern Bericht:
Arduino - 2004 LCD-Display mit I2C Modul
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
RTC DS3231 AT24C32 Real Time Clock

Gestern trudelte wieder ein kleines Tütchen aus dem Osten ein. Eine Echtzeituhr basierend auf dem DS3231 Chip. Das besondere an diesem Modul ist die Ganggenauigkeit. Durch eine Temperaturmessung und eines Korrekturprogramms soll die Abweichung nur wenige Sekunden im Jahr sein. Es gibt Berichte,wo die Abweichung faktisch Null sein soll. Wenige Sekunden reichen mir aber schon. :)

Das Platinchen habe ich bei Amazon bestellt und hat mich 84 Ct zuzüglich 1,05€ Versandkosten gekostet. Lieferzeit war ca. 2 Wochen.

Und so sieht die Platine, bereits mit einem Arduino verbunden, aus.



Ganz wichtig ist der Anschluß. Zuerst die Betriebsspannung (das Teil läuft von 3,3 - 5 V), also +5V und GND. Der Anschluß SLC der Uhr kommt beim Arduino an A5 und SDA an A4.

Zum Stellen der Uhr habe ich ein Sketch von Matthias Busse verwendet. Link zu seiner Seite:

Man muß allerdings hier die Uhrzeit von Hand im Sketch eintragen und mit einem Vorlauf von ca. 4s zur eingetragenen Zeit hochladen.

Edit: Und sie läuft. Zusammen mit dem 2004 Display und dem Nano.

Edit: Die Uhr läuft nun schon seit 13 Tagen und ich konnte keine Abweichung der Uhrzeit feststellen. Ich vergleiche immer mit meiner Funkuhr.



----------------------------------------------------------------------------------------------------------------
ACHTUNG!

Folgender Sketch setzt bei jedem Neustart des Arduinos die Uhrzeit so, wie es im Programmquellcode steht. Damit die Uhr also nicht jedes mal wieder verstellt wird, muss man das Uhrenmodul vor dem nächsten Reset oder Power on, vom Arduino trennen.

Möglichkeit zwei wäre es, im Quellcode die Zeile "einstellenDS3231zeit(00, 48, 11, 7, 4, 5, 19);" , durch zwei // auszukommentieren und den Sketch erneut compilieren und übertragen.
-----------------------------------------------------------------------------------------------------------------

Der Sketch:

// Einstellen der Uhrzeit vom RTC3231
// Die aktuelle Zeit wird in Setup() eingestellt und beim Start übertragen
// Dazu wird das Programm ca. 4 Sekunden vor der eingestellten Zeit übersetzt
// und übertragen, dann ist es rechtzeitig fertig
// SLC an A5, SDA an Pin A4
// Matthias Busse 7.11.2016 Version 1.0

#include "Wire.h"
#define DS3231_ADDRESSE 0x68

void setup() {
Wire.begin();
Serial.begin(9600);
// aktuelle Zeit sek min std wt tag mon jahr
einstellenDS3231zeit(00, 48, 11, 7, 4, 5, 19);
}

void loop() {
zeigeZeit(); // Zeit ausgeben
delay(5000); // jede Sekunde
}

void einstellenDS3231zeit(byte sekunde, byte minute, byte stunde, byte wochentag, byte tag, byte monat, byte jahr) {
// Datum und Uhrzeit einstellen
Wire.beginTransmission(DS3231_ADDRESSE);
Wire.write(0);
Wire.write(decToBcd(sekunde)); // Sekunden einstellen
Wire.write(decToBcd(minute)); // Minuten einstellen
Wire.write(decToBcd(stunde));
Wire.write(decToBcd(wochentag)); // 1=Sonntag ... 7=Samstag
Wire.write(decToBcd(tag));
Wire.write(decToBcd(monat));
Wire.write(decToBcd(jahr)); // 0...99
Wire.endTransmission();
}


void leseDS3231zeit(byte *sekunde, byte *minute,byte *stunde, byte *wochentag, byte *tag, byte *monat, byte *jahr) {
Wire.beginTransmission(DS3231_ADDRESSE);
Wire.write(0); // DS3231 Register zu 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESSE, 7); // 7 Byte Daten vom DS3231 holen
*sekunde = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*stunde = bcdToDec(Wire.read() & 0x3f);
*wochentag = bcdToDec(Wire.read());
*tag = bcdToDec(Wire.read());
*monat = bcdToDec(Wire.read());
*jahr = bcdToDec(Wire.read());
}

void zeigeZeit(){
byte sekunde, minute, stunde, wochentag, tag, monat, jahr;
leseDS3231zeit(&sekunde, &minute, &stunde, &wochentag, &tag, &monat, &jahr); // Daten vom DS3231 holen
if (tag < 10) { Serial.print("0");}
Serial.print(tag); // ausgeben T.M.J H:M:S
Serial.print(":");
if (monat < 10) { Serial.print("0");}
Serial.print(monat);
Serial.print(":20");
Serial.print(jahr);
Serial.print(" ");
if (stunde < 10) { Serial.print("0");}
Serial.print(stunde, DEC); // byte in Dezimal zur Ausgabe
Serial.print(":");
if (minute < 10) { Serial.print("0");}
Serial.print(minute, DEC);
Serial.print(":");
if (sekunde < 10) { Serial.print("0"); }
Serial.println(sekunde, DEC);
}

byte decToBcd(byte val) {
// Dezimal Zahl zu binary coded decimal (BCD) umwandeln
return((val/10*16) + (val%10));
}

byte bcdToDec(byte val) {
// BCD (binary coded decimal) in Dezimal Zahl umwandeln
return((val/16*10) + (val%16));
}
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Demarkt SPI Leser Micro Speicher SD TF Karte Speicherkarte

Mein letzter Neuzugang waren 5 SD-Kartenleser für Micro SD-Karten. Bei einem Angebot von 2,91€ zuzügl. 1,10€ Versand für 5 Stück bei Amazon, konnte ich nicht widerstehen.





Die Module sehen recht ordentlich aus. Angeschlossen ist schon eins, habe es aber noch nicht ausprobiert.
Sobald es läuft ergänze ich hier.
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Mega 2560 R3 Board mit ATmega2560

Ein Arduino Mega Nachbau hat auch den Weg zu mir gefunden. Für knapp 15€ von AZ-Delivery über Amazon. Nötig wurde das, weil ich mit dem Uno an die Speichergrenzen gestoßen bin, obgleich das Programm nicht sonderlich groß war und auch nicht übermäßig viele Variablen benutzt wurden. Mir wurde beim Compilieren nur immer gemeldet, dass der Speicher knapp würde und es zu Programmlauffehlern kommen könne. Weil das Projekt aber für eine Solarsteuerung gedacht ist, kann ich mir unvorhergesehene Abstürze nicht leisten.

Mit 256 KB Flashspeicher (inkl. 8 KB für Bootloader), 8 KB SRAM und 4 KB EEPROM-Speicher sollte ich auf der sicheren Seite sein. Als angenehmen Nebeneffekt stehen mir jetzt noch mehr Ein- und Ausgänge zur Verfügung. 55 digitale I/O-Pins, davon 15 mit 8-bit-PWM, 16 analoge Inputs mit 10 bit Auflösung, 6 externe Interrupt-Pins, 2 Hardware-Serial-Verbindungen, je 1x SPI & I²C

 

BAXL

Moderator
Mitarbeiter
433 MHz Datenübertragung

Es gibt die Möglichkeit, Daten zwischen Arduinos per Funk zu übertragen. Die mir scheinbare einfachste Variante sind die kleinen 433 MHz Module, die man für kleines Geld kaufen kann. Gesagt, getan. Ein 5er Pack bestellt. Mein Erster Versuch mit den nackten Modulen verlief alles andere als erfolgreich. Für das Experiment mussten zwei Nanos herhalten. Es gibt diverse Seiten mit Beispielprogrammen. Da habe ich gemops und dachte, es sei alles gut. Programme in die IDE und auf die Nanos geschubst. Weil es nicht klappte bin ich auf Fehlersuche gegangen. Und, Augen auf. Das erste Beispielprogramm für den Sender hatte in den Remarks den Digitalpin 9 angegeben, sowie auch bei der Grafik für den Anschluß, im Programm stand in der Befehlszeile der Port 10:eek:. Ha, Fehler gefunden - dachte ich. Dann kam mir die Idee, dass es an den fehlenden Antennen läge. Also eben zwei 17 cm Drähte klar gemacht und angelötet. Leider wieder ohne Erfolg. Als nächstes in die Programme serielle Ausgaben zum Monitoring eingefügt. Die Programme liefen. Nächster Schritt, die Module mal austauschen, ich habe ja von jedem 5 Stück. Auch da klappte es erst nicht. Plötzlich fällt mir bei der 198sten Überprüfung der Anschlüsse etwas ins Auge. Platine 1, für den Sender, hatte GND direkt auf der Seite der 5V angesteckt, beim Empfänger an GND auf gegenüberliegenden Seite von 5V. Beide Module an GND direkt neben den 5V angesteckt und - surprise, endlich klappte es. Um die Reichweite zu testen wurde der Sender ins Schlafzimmer verbracht (ca. 10m Luftlinie mit ein paar kleineren Störfaktoren) Es kamen tatsächlich Datenpakete an, aber nicht regelmäßig. Die Antennen hatte ich ursprünglich zu Spulen aufgewickelt. Nachdem ich die Spulen fast gerade gezogen hatte, kamen auch jetzt regelmäßig Datenpakete an.

Zweites Experiment: Sender ins Erdgeschoß Empfänger im 1. OG. Auch hier ist Empfang, allerdings kommen die Datenpakete wieder etwas zögerlicher an. Zwischen beiden Baugruppen liegt eine Betondecke mit viel Eisen. Wenn ich die Empfängerantenne um 90° zum Boden drehe, kommen ein paar Pakete mehr an. Bei einer Signalauswertung muß man also mit Verzögerungen rechnen. Die Antenne weiter zu strecken, bis sie fast gerade ist, bringt ebenfalls wieder eine kleine Verbesserung. Da kann man also mit etwas Experimentieren optimalere Bedingungen schaffen.


Der Sender ist mit der roten Antenne, der Empfänger mit der gelben Antenne.

Fazit, wenn was nicht klappt, liegt der Teufel, wie so oft, im Detail. Bisher werden ganz simpel nur die Ziffern 9876 übertragen. Im nächsten Schritt versuche ich etwas anderes. Vielleicht bekommt der Empfänger eine LED und der Sender einen Taster, oder ich übermittle eine gemessene Temperatur und lasse die auf einem Display anzeigen.

Hier, bei Amazon, gibt es 4 Sender-Empfängerpärchen bereits mit angelöteter Antenne für rund 7,60€. Bei funduino.de gibt es weitere Beispielprogramme.

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
mySwitch.enableReceive(0); // Empfänger ist an Interrupt-Pin "0" - Das ist am UNO der Pin2
}

void loop() {
// Serial.println("Schleife läuft");
// put your main code here, to run repeatedly:
if (mySwitch.available()) // Wenn ein Code Empfangen wird...

{
int value = mySwitch.getReceivedValue(); // Empfangene Daten werden unter der Variable "value" gespeichert.

if (value == 0) // Wenn die Empfangenen Daten "0" sind, wird "Unbekannter Code" angezeigt.
{
Serial.println("Unbekannter Code");
}

else // Wenn der Empfangene Code brauchbar ist, wird er hier an den Serial Monitor gesendet.
{
Serial.print("Empfangen: ");
Serial.println( mySwitch.getReceivedValue() );
}

mySwitch.resetAvailable(); // Hier wird der Empfänger "resettet"
}
}

#include <RCSwitch.h>
RCSwitch rcSwitch = RCSwitch();

void setup() {
Serial.begin(9600);
// put your setup code here, to run once:
// Sendemodul an dem digitalen PIN 10 angeschlossen.
rcSwitch.enableTransmit(10);
}

void loop() {
// put your main code here, to run repeatedly:
// Senden der Zeichenkette "Hallo Welt!"
rcSwitch.send(9876,24);
Serial.println("Sende!");
delay(1000);
}







Weitere Anwendungsbeschreibung
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
PIR HC-SR501 Bewegungssensor

Norbert hat wieder gespielt.
Diesmal mit einem Bewegungssensor, dem PIR HC-SR501. Den bekommt man einzeln ab ca. 2,50€ zuzügl Versand, im Duzend ist er billiger. :)
Da muß man mal bei den Anbietern genau hinsehen. Manchmal versendet derselbe Anbieter vom eigenen Shop und gleichzeitig bei Amazon.
Der 5er-Pack war als Amazon Primekunde dann einen Euro günstiger ;).

Der genannte Sensor ist ein passiver Sensor, der bereits fix und anschlußfertig geliefert wird. Drei Anschlußbeinchen, von dem einer +VCC ist (4,5-20V), Masse und der Signalpin, der zwischen 0 und 3,5V wechseln kann.

Der Anschluß gestaltet sich also recht einfach. VCC und Masse ist klar, die steckt man jeweils an GND und +5V vom Arduino. Für meine Experimente habe ich den Signalpin des Bewegungsmelders mit dem Digitalpin 7 an meinem Nano verbunden. Damit es nicht so langweilig wird, habe ich die 433MHz Platinen aus meinem Vorpost verwendet und die Hardware und Programme etwas modifiziert. Die Senderschaltung bekommt den Bewegungssensor und die Empfängerplatine eine LED, die ich über einen Vorwiderstand an den Digitalpin 4 des Nanos angeschlossen habe.

Beim ersten Funktionstest habe ich mir die Signale über den seriellen Monitor am PC angesehen, um zu testen wie die Signale kommen und welche Auswirkung das Drehen an den Potis für Empfindlichkeit und die Signalhaltezeit hat. Das habe ich erst nicht so richtig verstanden. Hinzu kommen noch zwei unterschiedliche Betriebsarten, die man über einen Jumper auswählen kann. Zu den Betriebsarten schreibe ich später mehr, da muß man mehrmals lesen, um die systematik der Funktion zu verstehen.

Bei den Potis bin ich auch bezüglich der Drehrichtung fündig geworden. Bei beiden Potis gilt, nach Rechts drehen (im Uhrzeigersinn) erhöht die Empfindlichkeit, bzw. die Einschaltdauer, nach Links drehen (entgegen dem Uhrzeigersinn) verringert die Empfindlichkeit bzw. die Einschaltdauer.

Für den Test brauchte ich dann nur noch die Programme für das entsprechende Eingangs- und Ausgangssignal anpassen.

Hier erstmal Bilder von dem Sensor:





Die Schaltungen sehen narürlich fast so wie beim Vorpost aus:

Auf dem folgenden Bild sieht man die Senderplatine mit dem PIR-Sensor:



Die Empfängerplatine hat eben die LED mit dem Widerstand bekommen.



Der Code für den Sender:

#include <RCSwitch.h>
RCSwitch rcSwitch = RCSwitch();

// Bewegungsmelder
int Bewegungsmelder=7;
byte Bewegungsstatus=0;

void setup() {
Serial.begin(9600);
// Sendemodul an dem digitalen PIN 10 angeschlossen.
rcSwitch.enableTransmit(10);
pinMode(Bewegungsmelder, INPUT);

}

void loop() {
Bewegungsstatus=digitalRead(Bewegungsmelder);
Serial.println(Bewegungsstatus);
if (Bewegungsstatus == HIGH){
rcSwitch.send(9876,24);
Serial.println("Sende!");
}
delay(100);
}

Empfängerprogramm:

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
byte Bewegung=0;
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(0); // Empfänger ist an Interrupt-Pin "0" - Das ist am UNO der Pin2
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
}

void loop() {
// Serial.println("Schleife läuft");
// put your main code here, to run repeatedly:
if (mySwitch.available()) // Wenn ein Code Empfangen wird...

{
int value = mySwitch.getReceivedValue(); // Empfangene Daten werden unter der Variable "value" gespeichert.

if (value == 0) // Wenn die Empfangenen Daten "0" sind, wird "Unbekannter Code" angezeigt.
{
Serial.println("Unbekannter Code");
}

else // Wenn der Empfangene Code brauchbar ist, wird er hier an den Serial Monitor gesendet.
{
Serial.print("Bewegung erkannt");
Serial.println( mySwitch.getReceivedValue() );
digitalWrite(4, HIGH);
delay(500);
}

mySwitch.resetAvailable(); // Hier wird der Empfänger "resettet"
}
if (Bewegung == 1){

}


Serial.println("keine Bewegung erkannt");
digitalWrite(4, LOW);

}

Nun zu den Betriebsarten. "Ab Werk" ist der Jumper (gut auf dem ersten Bild zu sehen) so gesetzt, dass der Sensor bei Bewegung ein Signal erkennt und für eine gewisse Zeit ein High-Signal liefert. Ich nenne das mal Betriebsart 1. Die Signaldauer kann über das entsprechende Poti eingestellt werden. Da sollte man aber nur ganz wenig das Poti drehen, um die Zeit zu verstellen. Bei Bewegung wird also der Ausgang high und hält das für die eingestellte Zeit. Danach schaltet der Ausgang wieder auf Low. Für ca. 3s ist der Sensor danach quasi "blind" und reagiert nicht mehr. Erst nach 3s kann eine erneute Bewegungung gemeldet werden.

Für die zweite Betriebsart muß man den Jumper umsetzen. Da wird dann der innere Pin mit dem mittleren Pin verbunden. Man kann das auf dem dritten Bild sehen. Nun wird die Erklärung etwas umständlich. Also im Zweifel öfters lesen! :).

Wenn eine Bewegung erkannt wird, schaltet der Ausgangspin des PIR wieder auf High. Ist nur eine kurze Bewegung gewesen (also einmal kurz mit der Hand davor winken), ist das Verhalten quasi wie in Betriebsart 1. Das Ausgangssignal schaltet nach der, am Poti voreingestellten Zeit, wieder auf Low. Besteht die Bewegung aber länger, dann wird solange das Ausganssignal gesetzt gehalten, bis die keine Bewegung mehr vorhanden ist. Die "Nachlaufzeit" ist dann wieder so, wie voreingestellt. Ist die Nachlaufzeit dann abgelaufen, fällt der Ausgang auf low und der Sensor ist wieder für ca. 3s blind, bis er erneut eine Bewegung erkennen kann.

Beispiel:
Ich gehe in ein Zimmer, in dem meine Schaltung aufgestellt ist. Der PIR erkennt meine Bewegung und schaltet ein. Bleibe ich dann ruhig stehen, geht der Ausgang, sagen wir mal nach 4s wieder aus. Es dauert nun 3s, bis der PIR wieder eine Bewegung erkennen kann.

Gehe ich in das Zimmer und laufe darin meinetwegen 3 Minuten herum und gehe wieder raus, dann bleibt der Ausgang solange an zuzüglich der voreingestellten Nachlaufzeit, also insgesamt 3 Minuten und 5 s.

Ich probiere das gerade im Wohnzimmer aus. Eine Bewegung wird tatsächlich erkannt und per 433MHz Verbindung ins Arbeitszimmer gemeldet.

Beim folgenden Bild habe ich meine Holde gebeten, vor dem Sensor herumzulaufen. Man kann sehen, dass die Kontroll-LED leuchtet.

 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Thermosensor MAX6675

Die Bezeichnung dieses Sensors ist leicht irreführend, weil es den Eindruck erweckt, der MAX6675 sei selbst das Messelement für Temperaturen. Der Thermsosensor als Ganzes besteht eigentlich aus einem k - Typ Messfühler und einer Auswerteplatine, die im wesentlichen aus einem IC besteht, eben dem MAX6675 Baustein. Dieses MAX6675 IC wertet die eingehenden Messwerte des k - Typ Messfühlers aus und liefert den Messwert über eine digitale Kommunikation an einen angeschlossenen Mikrorechner ab.



Das k - Typ Element besteht aus zwei unterschiedlichen Metalldrähten, die an einem Ende miteinander verbunden werden. Durch diese Kombination zweier Metalle, wird temperaturabhängig elektrische Energie von nur wenigen Mikrovolt erzeugt. Die Metallkombination ist NiCr - Ni (Nickelchrom - Nickel). Man findet dieses k- Typ Thermoelement auch häufig bei Multimetern. Man kann also im Prinzip jedes k - Typ Thermoelement am MAX6675 anschließen, man muß nur auf die Polung achten. Der Messbereich liegt zwischen 0°C und ca. 1300°C. Die Auswerteplatinen haben dabei eine Messwertauflösung (nicht Genauigkeit!!) von 0,25V.



Zur Verwendung bei einem Arduino oder auch Raspberry Pi, muß man die Auswerteplatine über 5 Leitungen anschließen (siehe Bild oben), von denen zwei Leitungen Plus und Masse sind. Die übrigen drei Leitungen sind SCK (Serial Clock), CS (Chip Select) und SO (Serial Output), die jeweils an einem digitalen Port des Arduinos oder RasPi angeschlossen werden müssen.

Zum Ansteuern gibt es bereits fertige Programmbibliotheken, von denen man dann nur noch die vordefinierten Funktionen aufrufen braucht. Selbstverständlich findet man auch gleich Beispielprogramme, mit denen man die Messwerte aus dem MAX6675 ausließt und am PC über den seriellen Monitor der Arduino IDE anzeigen lassen kann.

#include "max6675.h" //Die MAX6675 Bibliothek
int max6675SO = 8; // Serial Output am PIN 8
int max6675CS = 9; // Chip Select am PIN 9
int max6675CLK = 10; // Serial Clock am PIN 10
// Initialisierung der MAX6675 Bibliothek mit
// den Werten der PINs
MAX6675 ktc(max6675CLK, max6675CS, max6675SO);
void setup() {
Serial.begin(9600); // Begin der Seriellen Kommunikation mit 9600 Baud
delay(500); // eine kleine Pause damit der Sensor sich kalibriert
}
void loop() {
// Lesen des Temperaturwertes in Grad Celsius
Serial.print(ktc.readCelsius());
Serial.println("C");
// Lesen des Temperaturwertes in Grad Fahrenheit
Serial.print(ktc.readFahrenheit());
Serial.println("F");
// 500ms Pause bis zum nächsten Durchlauf
delay(500);
}
 

BAXL

Moderator
Mitarbeiter
OLED Display 128x64 1,3" mit I2C Ansteuerung

Meine neueste Errungenschaft ist ein OLED Display mit einer Größe von 1,3" und einer Auflösung von 128x64 Bildpunkten.

Das Display ist monochrome (weiß) und kann Text und Grafiken anzeigen. Mein Einsatzzweck ist die Darstellung von Text, weil mein 2004 LCD Display mit 4 Zeilen zuwenig Platz für die Darstellung von Messdaten bietet. D.h. also, dass ich keine Grafik, sondern nur Text und Zahlen anzeigen möchte. Mein Display ist von AZ-Delivery, das schreibe ich deshalb jetzt ausdrücklich hier herein, weil ich bemerkt habe, dass die Displays unterschiedlicher Anbieter und Ausführungen, nicht alle mit den gleichen Librarys angesteuert werden können.

WICHTIG!
Bei meinem ersten Versuch wurde auf dem Bildschirm nur eine Vielzahl weißer Pixel ausgegeben, Ursache für die fehlerhafte Anzeige ist, dass dieses Display nicht mit dem SSD1306, sondern mit dem SH1106 Controller-Chip ausgestattet ist.

Angeschlossen wird VDO -> +5V, GND -> GND, SCK -> A5, SDA -> A4 am Arduino.

Die Suche nach einer funktionierenden Lib, die rein Text darstellen kann, nahm sich etwas aufwändig aus. Der Anbieter gibt auf seiner Internetseite lediglich eine Lib an, die speziell Grafiken anzeigen kann, das ist die weit verbreitete U8g2 Bibliothek von Oliver Kraus. Text wird dort auch nur in Form einer Grafik ausgegeben. Leider hat diese Lib den üblen Nachteil, dass sie enorm viele globale Variablen deklariert, sodass es vom Arduino Compiler bereits eine Fehlermeldung gibt, dass der Speicherbereich so voll ist, dass es zu Funktionsstörungen kommen kann. Selbst wenn man aus dem Beispielprogramm alle überflüssigen Teile entfernt und quasi nur noch ein nacktes Programm übrig bleibt, ist der Speicher fast voll.

Nach einigem Suchen und Probieren habe ich die U8x8lib.h gefunden. Und siehe da, der Speicherbedarf für Variablen ist auf ca. 25% runter gegangen. Diese Lib findet man auch unter dem o.g. Link. Das zugehörige Testprogramm ist nach dem Einbinden der Library unter "Bibliotheken => U8g2 => u8x8 => HelloWorld" zu finden.

Damit das hier vorgestellte Display angesteuert werden kann, muß im Deklarationsteil
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
auskommentiert werden.

Leider sind die Beispielprogramme oft sehr spartanisch. Das HelloWorld Beispiel taugt gerade dazu, in die entsprechende Funktion einen Text in " " zu übergeben und anzuzeigen.
Sehr positiv aufgefallen ist mir, dass die Positioniereung des Textes genauso wie beim 2004 LCD Display funktioniert. Angabe von Zeile und Spalte und die anzuzeigende Information.

u8x8.drawString(0,0,"Hello World!"); // (Spalte, Zeile, String)

Der erste Wert in der Klammer gibt die Spalte an, wobei von 0 an durchnummeriert wird und das 1.Zeichen auf Position Null ist.
Der zweite Wert in der Klammer gibt die Zeile an, auch hier beginnt man bei Null zu zählen. Es können maximal 16 Zeichen in 8 Zeilen ausgegeben werden.





Funktionierendes Beispielprogramm, dass ich zum Testen verwendet habe:

Code:
//  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)

#include <Arduino.h>
#include <U8x8lib.h>

// Please UNCOMMENT one of the contructor lines below
// U8x8 Contructor List
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
// Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

byte zeile = 0;
char z[4];
char TestText[9] = "Testtext";
int IntZahl;
char ZahlCharArray[16];
String ZahlString;

void setup(void)

{

  u8x8.begin();
  u8x8.setPowerSave(0);

}

void loop(void)
{
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.drawString(0,0,"Hello World!");
  u8x8.drawString(0,1,"Hallo Welt!");
  u8x8.drawString(0,2,"ABCDEFGHIJKLMNOP");
  u8x8.drawString(0,3,"Zeile 4");
  u8x8.drawString(0,4,"Zeile 5");
  u8x8.drawString(0,5,"Zeile 6");
  u8x8.drawString(0,6,"Zeile 7");
  u8x8.drawString(0,7,"Zeile 8");
  delay(2000);
  u8x8.clear();

for (byte ii=0; ii<7; ii++){
   u8x8.drawString(0,ii,"Ich wandere");
   u8x8.clearLine(ii-1);
   delay(200);
}
u8x8.clear();

for (byte ii=0; ii<8; ii++){

    ZahlString = (ii+1)*100;
    ZahlString.toCharArray(ZahlCharArray,16);
    u8x8.drawString(0,ii,ZahlCharArray);

   delay(800);
}
u8x8.clear();

}
In einem Extrathema (128 x 64 Pixel 1,3 Zoll OLED I2C Display für Arduino ) walze ich dieses Display etwas weiter aus, weil es mir einige Schwierigkeiten bereitet hat nicht nur platt einen Text in " " auszugeben, sondern auch die Anforderung bestand, Messwerte, die bekanntlich nicht als String vorliegen, umzuwandeln und der Ausgabefunktion zu servieren. Dazu musste ich einige Hürden überwinden.
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Adapter für NRF24l01 Module

Wie schon in meinen Berichten ( NRF24L01 2,4 GHz Sende und Empfangsmodul für Arduino ) zu lesen ist, benötigen die NRF24l01 Module eine recht stabile 3,3V Spannungsversorgung, weil die gezogenen Ströme bis über 100mA im Sendebetrieb erreichen können. Die 3,3V Versorgung der Arduinos ist zu schwach und kann diesen Strom nicht liefern. Darum muß man in dem Fall mindestens einen 10µF Elko parallel zur Spannungsversorgung anschließen, um beim Senden einen kleinen Strompuffer zu haben. Eine andere Möglichkeit ist es, einen speziellen Adapter zu verwenden, der einen Spannungsregler besitzt und den man an die 5V versorgung des Arduinos anschließen kann. Ich habe mir einige dieser Adapter bestellt und in Betrieb genommen. Auch ohne Elko kabe ich nun eine zuverlässige Verbindung. Je nach Anbieter und Bestellmenge liegen die Preise bei ca. 1,30€ bis 2,50€ (Amazon).



 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Lichtsensor mit Photowiderstand LDR und digitalem Ausgang (Komparator)

Um Helligkeiten zu messen bedient man sich eines Photowiderstandes, man nennt sie auch lichtabhängigen Widerstand, oder LDR. Die bekommt man einzeln, muß dann aber noch eine Zusatzbeschaltung erstellen.



Es gibt bereits fertige Module, die sowohl einen analogen Ausgang, als auch eine Komparatorschaltung besitzen, die man mit einem verstellbaren Widerstand einstellen kann. Damit ist es möglich, bei bestimmten Lichtwerten einen Digitalausgang ein- bzw. auszuschalten. Der analoge Ausgang liefert Spannungswerte von 0 bis 5V, die man mit einem analogen Eingang eines Arduinos in 8 Bit Auflösung messen kann (0 bis 1023). Derartige Fertigmodule habe ich bei Amazon im 10er Pack für 7,99€ bezogen.

Der Anschluß gestaltet sich sehr einfach. +5V an VCC, Masse an GND, A0 an einen Analogeingang und D0 an einen Digitaleingang. Achtung 5V Pegel, falls man einen ESP8266, WEMOS 1D Mini o.ä. verwendet.

Die Programmierung bedarf keiner weiteren Erläuterung, weil man lediglich den Analog- oder den Digitaleingang abfragt. (Basiswissen ;))

So sieht das gute Stück aus:



 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
220V / 230V Wechselspannungssensor

Manchmal möchte man irgendwo nachprüfen können, ob ein 230V Verbraucher eingeschaltet wurde, d.h., man will eigentlich nur wissen, ob ein Schalter, Relais usw., Spannung an einen Verbraucher gelegt hat. Es soll weder genau die Spannung und auch nicht der fließende Strom gemessen werden. Ganz simpel, liegen 230V an? Ja oder nein?

Diese Information sollte dann von einem Arduino direkt an einem Digitalport eingelesen werden können. Das Problem, 230V Wechselspannung kann man ganz schlecht gefahrlos am Arduino anschließen. Es gibt viele Lösungen dafür, die mehr oder weniger gefahrlos oder einfach umzusetzen sind. Beim Funduino.de gibt es eine Platine, die auf der Hochspannungsseite an die Phase und Nulleiter eines 230V Anschlusses angeklemmt werden kann. Mit einer speziellen Schaltung und einem zwischengeschalteten Optokoppler, kann man galvanisch getrennt, an der anderen Seite der Platine, das Signal direkt an den Arduino ausgeben.

Aber Vorsicht, diese Platine ist an den 230V Seite komplett offen und gegen Berührung ungeschützt. Man kann also leitende, unter Spannung stehende Teile, anfassen und einen Stromschlag bekommen. Darum sollte man die Platine, bevor man 230V Spannung anlegt, in ein Schutzgehäuse packen. Am besten man nimmt eine Aufputzabzweigdose und steckt das Teil da hinein. Natürlich nicht vergessen, den Deckel der Abzweigdose zuzumachen ;).

Und so sehen die Platinen aus:



Ausführlicher Bericht zur Erkennung von 220V /230V Wechselspannung:
230V 220V Wechselspannung AC Pegel mit einem Arduino erkennen
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
2,8" TFT LCD-Bildschirm in Farbe mit SPI Schnittstelle

Ich habe mir ein 2,8" LCD Farbbildschirm gegönnt. Das Modul ist von Dolla Tek hat eine Auflösung von 240x320 Pixel und wird über die SPI Schnittstelle angeschlossen. Zur Ansteuerung des Displays kommt ein ILI9341 Controllerchip zum Einsatz, das ist wichtig, um die richtige Library einzubinden. Das Display muß mit 3,3V versorgt werden und darf an den Porteingängen auch nur 3,3V bedient werden. Verwendet man einen Arduino, muß man für sämtliche Anschlüße einen Spannungsteiler aus Widerständen bauen, oder ein Pegelwandlermodul zwischenschalten. Die bekommt man je nach Anbieter oder Bestellmenge für zwischen 1,50€ bis 4,50€. Am billigsten ist AZ-Delivery am teuersten Miss Birdler. Dazwischen tummeln sich auch noch Anbieter. Die Anschlußbezeichnungen geben einem manchmal Rätsel auf, weil es für ein und denselben Port viele verschiedene Kürzel gibt.
Das Dolla Tek hat die Anschlüsse GND, VCC, CLK,MOSI, RES, DC, BLK und MISO. Für die vielen verschiedenen Bezeichnungen und Anschlußmöglichkeiten spendiere ich noch ein eigenes Thema.

Will man das Display an ein ESP8266 Modul anschließen, benötigt man keine Pegelwandlung, weil diese Module bereits komplett auf 3,3V laufen. Allerdings gestaltet es sich schwierig, die richtigen Anschlüsse zu finden, weil man viel, ich würde sagen zuviel, im Internet findet. Das altebekanne Problem eben. Alle schreiben was, aber entweder wird nur an der Oberfläche gekrazt, oder so tief eingestigen, dass man regelrechte akademische Dokumentationen mit Osziloskopbildern findet. Alkso beides nicht richtig zielführend.

Bislang konnte ich das Display noch nicht zum Leben erwecken. Entweder sucht der Compiler irgendwelche weiteren Libs, die nicht da sind, oder bricht auch so mit obskuren Fehlermeldungen ab. Das wird also noch eine abendfüllende Aktion. Der Sonntag ist bereits ohne brauchbares Ergebnis draufgegangen.


 

BAXL

Moderator
Mitarbeiter
Lichtsensor BH1750 / Luxmeter - Messung der Beleuchtungsstärke

Zur Lichmessung gibt es Sensormodule für den Arduino und Co, die als Sensorchip den BH1750 verwenden. Als kleine Randnotiz, der BH1750 werkelt üblicherweise auch in Smartphone, um das Umgebungslicht zur Nachjustierung der Displayhelligkeit zu messen.

Der BH1750 ist bei fertigen Sensorplatinen bereits auf einer Platine aufgelötet die man, zum einfacheren Anschluß an den Arduino, mit Pfostenpins bestücken kann. Zur Kommunikation dient der I2C-Bus mit seinen Anschlüssen SCL, SDA und natürlich VCC und GND. Die Platine kann mit 5V betrieben werden, obgleich der BH1750 3,3V als Betriebsspannung benötigt. Die Beschaltung auf der Sensorplatine erledigt das Problem aber für uns.



Der Sensor liefert als Messergebnis bereits eine digitale Information, nämlich die Beleuchtungsstärke in Lux, also banal gesagt, wie hell es am Sensor ist. Der Messbereich geht von 0 bis 65.535lx. Damit ist auch klar, dass wir als Datentyp für den Messwert einen Integer (int) haben. Dieser Umstand resultiert aus einem AD-Wandler mit 16 Bit Auflösung.

Die von mir verwendete Library findet man auf: https://github.com/claws/BH1750/
Der Sensor belegt auf dem I2C-Bus die Adresse 0x23 und sollte für die Beispiele aus der Lib mit SCL an A5 des Arduinos und SDA an A4 des Arduinos angeschlossen werden. Die Adresse kann umgestellt werden. Ist der ADDR-Pin auf Masse, oder offen, besitzt die Schaltung die o.g. Adresse 0x23, legt man den ADDR-Pin auf +VCC, dann reagiert die Messchaltung auf Adresse 0x5c. Um genau zu sein wird bei einer anliegenden Spannung von kleiner als 0,7V die 0x23 gesetzt, bei größer 0,7V ist 0x5c gültig. Womit dann die Funktion des ADDR-Pins erklärt wäre.



Vorsicht Falle:
Im Susa habe ich den Sensor angeschlossen und mich gewundert warum es nicht klappt. Als Fehler kam dauernd "[BH1750] Device is not configured!". Erst auf den zweiten Blick ist mir aufgefallen, dass ich Dösel statt A4, A5, die Ports D4 und D5 angeschlossen hatte:confused:. Also aufpassen!

Für den ersten Versuch habe ich das bei der Lib mitgelieferte Testprogramm BH1750test geladen. Nach dem ich den o.g. Fehler gefunden und behoben hatte, lief alles ganz unspektakulär und auf dem seriellen Monitor trudelten die Messwerte in Lux ein.




Es gibt bei dem Sensor noch die Möglichkeit die Messempfindlichkeit per Software einzustellen. Das hängt davon ab, wie stark das einfallende Licht ist. Je mehr Licht gemessen wird, umso "unempfindlicher" kann man die Messung machen. Die Messempfindlichkeit hat dann auch noch einen Einfluß auf die Dauer, bis ein Messwert abgeliefert wird. Bei niedriger Empfindlichkeit dauert es ca. 16ms, bis ein Wert bereit steht, bei normaler, oder hoher Messempfindlichkeit, benötigt der Sensor ca. 120ms bis der Messwert gesendet wird. Doch das zeige ich nicht an dieser Stelle, dafür spendiere ich noch ein eigenes ausführlicheres Thema mit einer praktischen Anwendung als Luxmeter mit Display.

Code:
/*

  Example of BH1750 library usage.

  This example initialises the BH1750 object using the default high resolution
  continuous mode and then makes a light level reading every second.

  Connection:

    VCC -> 3V3 or 5V
    GND -> GND
    SCL -> SCL (A5 on Arduino Uno, Leonardo, etc or 21 on Mega and Due, on esp8266 free selectable)
    SDA -> SDA (A4 on Arduino Uno, Leonardo, etc or 20 on Mega and Due, on esp8266 free selectable)
    ADD -> (not connected) or GND

  ADD pin is used to set sensor I2C address. If it has voltage greater or equal to
  0.7VCC voltage (e.g. you've connected it to VCC) the sensor address will be
  0x5C. In other case (if ADD voltage less than 0.7 * VCC) the sensor address will
  be 0x23 (by default).

*/


#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter;


void setup(){

  Serial.begin(9600);

  // Initialize the I2C bus (BH1750 library doesn't do this automatically)
  Wire.begin();
  // On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3);

  lightMeter.begin();

  Serial.println(F("BH1750 Test begin"));

}


void loop() {

  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");
  delay(1000);

}
Die Preise für das Modul schwanken sehr stark, so bekommt man das schon ab 1,70€, darf je nach Anbieter aber auch bis zu 6,50€ berappen. Für das gleiche Modul versteht sich.

Meine Exemplare habe ich von hier, die haben 1,74€ gekostet und einiges an Wartezeit. Bestellt am 2. November, erhalten am 6. Dezember.

Typische Lichtstärken:

Sonne, klarer Himmel - 100'000 lx
Sonne, bedeckter Himmel - 20'000 lx
Sommer im Schatten - 10'000 lx
Beleuchtung Fernsehstudio - 1'000 lx
Bürobeleuchtung - 500 lx
Flurbeleuchtung - 100 lx
Straßenbeleuchtung - 10 lx
Kerze in 1 m Entfernung - 1 lx
Vollmond bei klarem Himmel - 0,25 lx
sternenklarer Nachthimmel - 0,001 lx
bewölkter Nachthimmel - 0,0001 lx
 
Zuletzt bearbeitet:

BAXL

Moderator
Mitarbeiter
Ultraschallsensor HC-SR04

Für Anwendungen mir dem Arduino gibt es ein kostengünstiges Ultraschallmodul, das HC-SR04. Das Modul kostet, ja nach Bezugsquelle und Bestellmenge zwischen rund 1,30€ und 4,00€.



Die Hauptanwendung ist die Entfernungsmessung. Dabei wird sich der Umstand zunutze gemacht, dass Schallwellen eine Ausbreitungsgeschwindigkeit haben, die bei ca. 340 m/s liegt. Zu dem Zweck wird ein Ton im Ultraschallbereich ausgesendet. Trifft der Ton auf ein Hinderniss, wird er reflektiert. Mit einem Mikrofon fängt man den reflektierten Tonimpuls wieder auf. Anhand der Laufzeit und der Geschwindigkeit des Schalls lässt sich nun die Strecke berechnen, die der Ton zurückgelegt hat. Der Abstand zu einem Hinderniss lässt sich folgendermaßen berechnen:

gemessene Laufzeit x Schallgeschwindigkeit / 2

Das HC-SR04 wird mit vier Leitungen an einen Arduino (o.ä.) angeschlossen. VCC an +5V, GND an GND und die Pins Trig und Echo an digitale Ports des Arduinos.
Für den Trig -Anschluß wird ein Arduino-Port als Ausgang und für den Echo-Pin als Eingang konfiguriert.

Über den Trig-Pin löst man das Aussenden eine Ultraschallimpuls aus und über Echo wird ein Signal ausgegeben, wenn der reflektierte Schall auf das Mikrofon trifft.

In einem Programm wird das derart umgesetzt, dass man Trig für eine kurze Zeit ein und wieder ausschaltet. Danach "horcht" man am Echo Pin, bis der reflektierte Schall wieder zurückkommt. Die Zeitdauer des High-Impulses am Echo-Pin wird dann zur Berechnung der Entfernung verwendet. Wichtig ist, dass man die Zeit durch Zwei teilt, weil der Schall ja die Entfernung zweimal zurückgelegt hat und dafür natürlich die doppelte Zeit benötigte.

Für die Zeitmessung gibt es beim Arduino eine Funktion, die sich pulseIn() nennt. Diese Funktion lauscht auf dem vorher definierten Eingangspin, an dem Echo angeschlossen ist, und liefert die Zeit im Microsekunden zurück, die der High-Impuls angelegen hat. Der Fallstrick bei der ganzen Programmierung ist eigentlich das richtige Berechnen mit den Maßeinheiten.

Wir haben einerseits die Schallgeschwindigkeit, die in Meter pro Sekunde angegeben ist und die Laufzeit, die über pulseIn() in Microsekunden zurückgeliefert wird. Wichtig ist auch, in welcher Maßeinheit man die errechnete Entfernung ausgeben möchte, ob in Meter, oder Zentimeter.

Eine Sekunde hat 1000000 (eine Million) Microsekunden oder auch 1000 (Tausend) Millisekunden.
Bei einer Schallgeschwindigkeit von 343 m/s würde der Schall in einer Mikrosekunde einen Weg von 0,0343 cm, oder 0,000343 m zurücklegt. Dabei gehen wir davon aus, dass die Lufttemperatur 20°C beträgt.

Zur Vereinfachung des Programmcodes dividiert man nicht durch 0,0343 sondern multipliziert mit dessem Kehrwert, was ungefähr 29,4 beträgt. Nicht zu vergessen die Division durch 2, weil der Weg ja zweimal zurückgelegt wurde.

Also ergibt sich als Berechnung: gemessenen Zeit in Mikrosekunden / 2 x 29,4 = Entfernung in Zentimeter

Auf unterschiedlichen Internetseiten findet man eine Vielzahl von Berechnungsformeln, bei denen die 29,2 mal durch 28, 25 oder 29,1 ersetzt wurde. Ich nehme an, dass bei Versuchen die per Ultraschall gemessene Entfernung von der Entfernung abweicht, die man mit dem Lineal nachgemessen hat. Ich habe zudem festgestellt, dass die Messung unterschiedlich genau ist, je nachdem, wie weit das Hindernis vom Sensor entfernt ist. Im Nahbereich bis ca. 5cm erhält man sehr ungenaue Messungen, ab ca. 6 bis 8 cm werden die Ergebnisse genauer, haben aber immernoch eine Abweichung von wenigen Millimeter.

Auf einer Internetseite fand ich noch den Hinweis, dass die Messung von der Temperatur abhängig ist, weil sich bei Temperaturschwankungen die Dichte der Luft verändert und somit auch die Laufzeit des Schalls. Die entsprechende Formel wurde so angegeben:

Schallgeschwindigkeit bei 20°C+(0,6 x tatsächliche Temperatur) oder auch 343,2 m/s + (0,6 x tatsächliche Temperatur)

Zum Testen habe ich mit einem DS18B20 die Raumtemperatur gemessen und entsprechende verrechnet, die Formel sah so aus:

entfernung = dauer*((343.2+(0.6*temperatur())))/20000;

Die Messergebnisse waren trotzdem nicht sonderlich befriedigend und teilweise noch schlechter, als vorher mit festen Werten der Schallgeschwindigkeit. Nebenbei habe ich noch herausgefunden, dass die Ultraschallfrequenz einen zusätzlichen Einfluß hat.

Es stellt sich deshalb die Frage, zu welchem Zweck das Modul am Ende taugt. Für eine exakte Längenmessung scheidet eine solche Schaltung aus, denkbar sind aber Anwendungen, bei denen es nicht auf ein paar Millimeter ankommt, wie bei einem einfachen Näherungssensor, oder eine Füllstandanzeige von Flüssigkeitsbehältern. In einem eigenen Thema stelle ich meine Testschaltung samt Programmcode vor.
 
Zuletzt bearbeitet:
Top Bottom