1. Diese Seite verwendet Cookies. Wenn Sie sich weiterhin auf dieser Seite aufhalten, akzeptieren Sie unseren Einsatz von Cookies. Weitere Informationen
  2. Kandidat werden bei Die Modellbauer
    Information ausblenden

Praxisbericht Arduino - Zusatzhardware und Sensoren - Vorstellung und Beispiele

Dieses Thema im Forum "Arduino, RaspberryPi und Co." wurde erstellt von BAXL, 26. April 2019.

  1. BAXL

    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.
     
    BlackbirdXL1 gefällt das.
  2. BAXL

    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.
     
    BlackbirdXL1 gefällt das.
  3. BAXL

    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)

    [​IMG]

    [​IMG]


    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
    }



    [​IMG]

    [​IMG]
     
    Zuletzt bearbeitet: 19. September 2019
    BlackbirdXL1 gefällt das.
  4. BAXL

    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 :).
     
    BlackbirdXL1 gefällt das.
  5. BAXL

    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:

    [​IMG]

    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 :) :

    [​IMG]

    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.

    [​IMG]
     
    Zuletzt bearbeitet: 26. April 2019
    Crazy virus 4.0 und BlackbirdXL1 gefällt das.
  6. BAXL

    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:

    [​IMG]

    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.

    [​IMG]

    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: 19. August 2019
  7. BAXL

    BAXL Moderator Mitarbeiter

    Anzeigedisplay 2004 / 4 Zeilen, 20 Zeichen

    [​IMG]

    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);
    }
     
    Zuletzt bearbeitet: 19. August 2019
  8. DFENCE

    DFENCE Mitglied

    Ich könnte berichtet über alles was ich habe, aber dazu bräuchte ich Monate weil ich seit nem Jahr AZ Delivery und co wöchtenlich abgesucht hab und viel sehr sehr viel gekauft hab. Ich kann aber über bestimmte Bauteilgruppen berichten wenn jemand was bestimmtes sucht.
    Einfach nachfragen :)
     
  9. BAXL

    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.

    [​IMG]

    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.

    [​IMG]

    ----------------------------------------------------------------------------------------------------------------
    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: 19. August 2019
  10. BAXL

    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.

    [​IMG]

    [​IMG]

    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: 17. Mai 2019
  11. BAXL

    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

    [​IMG]
     
  12. BAXL

    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);
    }



    [​IMG]

    [​IMG]
     
    Zuletzt bearbeitet: 1. September 2019
  13. BAXL

    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:

    [​IMG]

    [​IMG]

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

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

    [​IMG]

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

    [​IMG]

    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.

    [​IMG]
     
    Zuletzt bearbeitet: 6. September 2019
    Crazy virus 4.0 gefällt das.
  14. BAXL

    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.

    [​IMG]

    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.

    [​IMG]

    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);
    }
     
  15. BAXL

    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.



    [​IMG]

    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 walze ich dieses Display etwas weiter aus, weil es mir einige Schwirigkeiten 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: 10. November 2019
    Crazy virus 4.0 gefällt das.

Diese Seite empfehlen