Das fünfte Türchen

Hinter dem 5. Türchen dieses Adventskalenders versteckt sich der Nano V3 Mikrocontroller. Man kann ihn als kleinen Bruder des Uno Mikrocontrollers bezeichnen. Mit ihm lassen sich Projekte umsetzen, bei denen das kleinere Maß eine wichtige Anforderung ist. Er bietet im Grunde alles, was man für die Auswertung von Sensoren oder dem Steuern von Aktoren braucht. Wichtige Details finden Sie im Datenblatt und im Pinout, die auch im AZ-Shop verlinkt sind. Beides sollte man zur Hand haben, wenn man ein Projekt beginnt.

Die wichtigsten Infos sind die 13 digitalen Pins, die als Ein- und Ausgänge verwendet werden können. Außerdem stehen acht analoge Pins mit Analog-Digital-Wandler zur Verfügung, die ebenfalls als digitale Pins nutzbar sind. Die Kommunikation findet mit anderen Geräten oder Komponenten unter anderem über I²C- (A4 und A5), USART- (D0 und D1) oder SPI-Schnittstelle (D10, D11 und D12) statt. Die Pins D2 und D3 können für externe Unterbrechungssignale (Interrupts) verwendet werden.

Im Adventsbeitrag vom 03.12. wurde bereits gezeigt, wie man die Arduino IDE installiert und das Blink-Beispiel auf den Uno lädt. Für den Nano Microkontroller funktioniert das exakt genauso. Eventuell müssen Sie für den CH340 Chip, der sich auf dem Board befindet, einen Treiber installieren, damit der Nano V3 Microkontroller an einem virtuellen COM-Port erkannt wird (die verlinkte Seite ist in chinesischer Sprache. Drücken Sie auf den großen blauen Button. In der ZIP-Datei befindet sich der Treiber. Achten Sie dabei darauf, ob Sie ein 32- oder 64-Bit System nutzen).

Mikrocontroller anschließen

Wenn Sie dann den Nano anschließen, wählen Sie unter Werkzeuge->Board den Arduino Nano aus. Als Prozessor den ATmega328P (Old Bootloader). In den AZ-Blogs finden Sie einen Beitrag von Albert Vu, der beschreibt, wie man den Bootloader "flashen" kann, damit man nicht mehr den alten Bootloader wählen muss. Unter dem Menüpunkt "Port" sollte nun ein COM-Port erscheinen. Die Nummer dahinter variiert.


Laden Sie zum Testen das Blinkbeispiel auf den Mikrocontroller (Sketch -> Hochladen, oder STRG+U). Auf der Platine befindet sich eine Onboard-LED, die nach dem Erfolgreichen Upload blinken sollte (die LED liegt übrigens an Pin D13 an. Die Konstante LED_BUILTIN verweist auf diesen Pin).

Sensoren oder veränderbare Widerstände (Potentiometer, auch Poti) liefern eine Spannung, die an den analogen Eingängen gemessen werden können. Auf dem Nano Board sind Analog-Digital-Wandler integriert, die diese physikalischen Werte umwandeln.

Mit der Funktion analogRead(PINNUMMER) erhält man als Rückgabe einen Wert zwischen 0 und 1023. Will man diesen Bereich verändern, wenn man z.B. 0 bis 255 braucht, kann man die Funktion map(value, fromLow, fromHigh, toLow, toHigh) verwenden (weitere Infos finden Sie hier).

Parameter

Funktion

value

Eingangswert (z.B. aus analogRead())

fromLow

unterer Quellwertebereich (hier 0)

fromHigh

oberer Quellwertebereich (hier 1023)

toLow

unterer Zielwertebereich (hier 0)

toHigh

oberer Zielwertebereich (hier 255)


Analog Input 

Die Arduino IDE und die integrierten Bibliotheken bieten reichlich Beispielsketches. So auch für die analogen Pins. Öffnen Sie dafür im Menü Datei -> Beispiele -> 03.Analog den Sketch AnalogInput. Dieser ist ein geändertes Blink-Beispiel, in dem ein Potentiometer die Blinkgeschwindigkeit reguliert. Schließen Sie dafür alles wie im folgenden Fritzingplan an und laden Sie das Beispiel auf den Nano:


Die äußeren Anschlüsse des Potis werden mit 5V und GND verbunden, der mittlere Kontakt (Schleifer) mit A0. So ist es im Beispielsketch definiert. Der ledPin 13 ist (wie oben bereits erwähnt) der Kontakt zur Onboard-LED. Wenn Sie das Programm auf dem Nano ausführen, können Sie mit dem Poti die Pause für das Umschalten zwischen An und Aus regulieren und somit die Blinkpausen vergrößern oder verkleinern.

Die Eingangswerte 0 bis 1023 werden hier direkt als Pause weitergegeben. Die Angabe in der delay()-Funktion ist in Millisekunden angegeben. Also erreichen wir Pausen zwischen 0 und 1023 ms. Möchten wir nun aber Pausen z.B. zwischen 1 und 5 Sekunden (1000 und 5000 ms) einstellen, dann kommt hier die oben genannte map()-Funktion ins Spiel.

Fügen Sie nach der Zeile für das Einlesen folgende weitere Zeile ein:

// read the value from the sensor:
sensorValue = analogRead(sensorPin);
//neu eingefügt:
sensorValue = map(sensorValue, 0, 1023, 1000, 5000);

Damit überschreiben wir den vorher eingelesenen Wert, der nun auf den neuen Wertebereich umgerechnet (skaliert) wird. Die Pausen sollten damit deutlich länger sein.

Hinweis: Die Funktion delay() sorgt für echte Pausen im Programmablauf. Daher wird die Änderung am Poti auch erst wirksam, wenn die Pause vorbei ist. Um das zu ändern, würde sich ein nicht blockierendes Programm besser eignen. Schauen Sie dafür in den Beispielsketch unter 02.Digital -> BlinkWithoutDelay. Dort wird gezeigt, wie mit Zeitmessungen das Umschalten der LED realisiert wird. Mit dem Poti müssten Sie dann das Intervall ändern.

Der Trick mit den gedimmten LEDs

Die Helligkeit einer LED kann in der Regel nicht über die Spannung geändert werden, wie es bei Glühlampen der Fall ist. Man bedient sich eines Tricks, der dafür sorgt, dass die LED nur sehr kurz ein- und wieder ausgeschaltet wird. Das geschieht so schnell, dass es für unser Auge so aussieht, als wäre die LED dunkler, je kürzer die Ein- und Ausschaltzeit ist. Wir können den vorherigen Sketch etwas ändern, um den Effekt zu sehen. Statt delay() nutzen wir delayMicroseconds() für die Pausen und wir ändern den Zielwertebereich von 1000 und 5000 in 0 und 10. Damit kann man durch Drehen des Potis die Helligkeit der Onboard-LED ändern.

Möchte man das jedoch richtig machen, greift man zur sogenannten Pulsweitenmodulation (PWM). Dem Datenblatt kann man entnehmen, welche Pins dazu in der Lage sind. Oft ist auf das Board neben den Pinnummern auch ein Tilde aufgedruckt (ein liegendes S), um die PWM-Pins zu identifizieren. Schließen Sie eine LED (Vorwiderstand nicht vergessen) an Pin 9 an und laden das Beispiel "Fading" unter Datei->Beispiele->3.Analog auf den Nano. Die LED sollte nun pulsieren.

 

Um die externe LED mit dem Poti zu regeln, fügen wir beide Sketches zusammen:

int ledPin = 9;    // LED connected to digital pin 9
int sensorPin = A0;    // select the input pin for the potentiometer
int fadeValue = 0;  // variable to store the value coming from the sensor

void setup() {}

void loop() {
  fadeValue = analogRead(sensorPin);
  fadeValue = map(fadeValue, 0, 1023, 0, 255);
  analogWrite(ledPin, fadeValue);
}

Legt man Wert auf minimierten Code, dann sieht das gekürzt so aus:

void setup() {}

void loop() {
  analogWrite(9, map(analogRead(A0), 0, 1023, 0, 255));
}

Die Funktionalität bleibt die gleiche.

Digital Input

Oft benötigen wir Taster als Eingabemöglichkeit. Sei es zum Starten oder Stoppen eines Prozesses, oder anderer Funktionen. Hier können relativ einfach die digitalen Pins verwendet werden. Allerdings ist darauf zu achten, dass in diesem Fall die Taster nicht einfach nur Stromkreise schließen. Aus diesem Grund müssen Pullup- oder Pulldown-Widerstände verwendet werden, mit denen die Zustände an den Pins klar definiert werden. Auf dem Nano sind an jedem digitalen Pin Pullup-Widerstände integriert. Diese werden im setup() aktiviert, wenn der jeweilige Pin als Eingang initialisiert wird:

pinMode(buttonPin, INPUT_PULLUP);

Damit ist dann der Eingang allerdings active low. Das bedeutet, dass nun der LOW-Zustand des Pins aktiv, also AN bedeutet. Dagegen ist HIGH der AUS-Zustand. Der Beispielsketch "DigitalInputPullup" unter Datei->Beispiele->2.Digital zeigt nochmal, wie es funktioniert. Der Taster wird zwischen Pin D2 und GND angeschlossen.

Man kann das auch mit externen Widerständen aufbauen. Dann benötigt man den internen Widerstand nicht. Im Beispielsketch "Button" ist in den Informationen der Schaltkreis für einen Pull-Down-Widerstand beschrieben und es wird erklärt, wie digitale Eingänge genutzt werden. Der Schaltplan sieht dann so aus:


Ein Problem mit Tastern ist, dass sie "prellen". Sollten Sie sich nämlich wundern, dass es manchmal so aussieht, als würde man den Taster mehrmals gedrückt haben, liegt das an diesem physikalischen Effekt. Man kann das mit Kondensatoren oder in Software lösen.

Der Sketch "Debounce" ist ein Beispiel für eine solche Lösung. Im Grunde geht es darum, dass man einen Tastendruck detektiert und danach für eine kurze Zeit den Taster ignoriert. Ein anderer Ansatz wäre, dass man mehrmals prüft, ob der Taster noch gedrückt ist. Dann ist man sicher, dass es kein zufälliges Signal war und gibt es an das Programm weiter.

Statt eines Tasters zu benutzen, kann man übrigens auch einfach nur die Enden von zwei Steckbrücken bzw. Kabeln aneinander halten. Wenn Sie z.B. eine Alarmanlage an Fenster oder Türen bauen möchten, nutzen Sie dafür einfach flache Metallkontakte, die mit den Pins verbunden sind. Das geht auch.

Externe Spannungsquellen

Oft möchte man sein Projekt unabhängig von einem Computer benutzen. Der ist auch nur zum Hochladen des Sketches auf den Mikrocontroller notwendig. Möchten Sie eine Batterie bzw. Akku, oder ein Netzteil verwenden, dann brauchen Sie den PC nicht. Der Nano kann über drei Anschlüsse mit Spannung versorgt werden. Zum Beispiel wie am PC, über den Mini-USB-Anschluss. Dort könnten Sie ein USB-Stecker-Netzteil oder eine Powerbank anschließen.

Außerdem verfügt der Nano über einen VIN-Anschluss (Voltage Input). Dort können Sie eine Spannung zwischen 7V und 12V anlegen. Entweder mit einem Labornetzteil, einem 9V-Block, einem Batteriepack mit mehreren AA-Batterien, oder einem LiPo-Akku mit Spannungsregler (LiPo-Akkus liefern meistens weniger als 5V, deswegen muss die Spannung transformiert werden).

Im ersten Türchen des AZ-Adventskalenders gab es das Breadboard Kit, das ein Netzteil-Modul enthält. Das liefert eine Spannung von 3,3V oder 5V. Die 5V können direkt an den 5V-Pin (der sonst als Spannungsquelle für andere Komponenten verwendet wird) angeschlossen und der Nano damit versorgt werden.

5V an den VIN-Pin anzulegen, ist keine gute Idee, da dort wie gesagt mindestens 7V anliegen müssen. Mehr als 5V an den 5V-Pin anzulegen, sollten Sie ebenso vermeiden, um den Nano nicht zu zerstören.

Bildschirmaus- und eingabe

Zum Schluss sei noch die Möglichkeit erwähnt, Ausgaben auf dem Monitor auszugeben. Das wird manchmal für das "Debuggen", also Fehlersuche, benötigt. Dafür nutzt man die serielle Kommunikation zwischen Nano Mikrocontroller und PC. Im setup() wird es folgendermaßen Initialisiert:

Serial.begin(9600);

Der Wert in der Klammer ist die Baudrate (also die Übertragungsgeschwindigkeit). In der Arduino IDE im Menü Werkzeuge können Sie entweder den Seriellen Monitor oder den Seriellen Plotter öffnen. Der Plotter ist für Sensordaten ganz gut geeignet, um Tendenzen zu erkennen. Der Serielle Monitor gibt Werte oder Texte aus. Wichtig ist, dass die Baudrate, die rechts unten in dem Monitor eingestellt ist, mit dem Wert in der Initialisierung im setup() übereinstimmt.

Nun können Sie in Ihrem Quelltext an beliebigen Stellen Bildschirmausgaben einfügen mit:

Serial.println(WERT);         // Variablenwert wird ausgegeben mit Zeilenumbruch
Serial.print(WERT);                 // Variablenwert wird ausgegeben ohne Zeilenumbruch
Serial.println(WERT, HEX);    // Variablenwert wird hexadezimal ausgegeben
Serial.println(WERT, BIN);    // Variablenwert wird binaer ausgegeben
Serial.println("Froehliche Weihnachten!");      // Textausgabe

Mehrere Variablen gleichzeitig mit einem Aufruf auszugeben ist damit nicht möglich. Entweder man nutzt mehrere Aufrufe von Serial.print(), oder man setzt vorher den Text in einer Stringvariable zusammen, die man anschließend ausgibt.

Hinweis: Sprintf unterstützt in der Arduino IDE keine Gleitkommazahlen (mit %f) auf einem AVR Board

double kommaZahl_A = 12.345678;
double kommaZahl_B = 98.765432;
 
char kommaZahl_A_str[10];
char kommaZahl_B_str[10];
char ergebnisPuffer[10];
char ausgabePuffer[25];
 
void setup() {
  // initialisieren:
  Serial.begin(115200);
    
  // ***** einzelne Ausgabe *****
  Serial.print(kommaZahl_A, 2); // zwei Kommastellen
  Serial.print(" + ");
  Serial.print(kommaZahl_B, 2); // zwei Kommastellen
  Serial.print(" = ");
  // mit Ausgabe der Berechnung mit vier Kommastellen:
  Serial.println(kommaZahl_A + kommaZahl_B, 4);
 
  //***** Als String zusammensetzen und dann ausgeben *****
  String ausgabeString = String(kommaZahl_A, 2) + " + " + String(kommaZahl_B, 2) + " = " + String(kommaZahl_A + kommaZahl_B, 4);
  Serial.println(ausgabeString);
 
  //***** mit sprintf zusammensetzen und dann ausgeben *****
  dtostrf(kommaZahl_A, 5, 2, kommaZahl_A_str);
  dtostrf(kommaZahl_B, 5, 2, kommaZahl_B_str);
  dtostrf(kommaZahl_A + kommaZahl_B, 8, 4, ergebnisPuffer);
  sprintf(ausgabePuffer, "%s + %s = %s", kommaZahl_A_str, kommaZahl_B_str, ergebnisPuffer);
  Serial.println(ausgabePuffer);
}
 
void loop() {}

Ausgabe:

12.35 + 98.77 = 111.1111
12.35 + 98.77 = 111.1111
12.35 + 98.77 = 111.1111

Eine Tastatureingabe ist über den Seriellen Monitor auch möglich. Dafür nutzt man die Abfrage auf Serial.available() und die Funktion Serial.read() zum Auslesen der einzelnen Bytes, die über die serielle Verbindung eingetroffen sind. Schreibt man das Byte in eine char-Variable, werden statt Zahlenwerte Buchstaben aus der ASCII-Tabelle ausgegeben:

char temp;
 
void setup() {
  Serial.begin(115200);
  Serial.println("Warte auf Texteingabe...");
}
 
void loop() {
  while(Serial.available()) {
    temp = Serial.read();
    Serial.print(temp);    
  }
}

Ausgabe:

Weitere Tipps

Das Öffnen des Seriellen Monitors startet den angeschlossenen Mikrocontroller neu.

Variablen sollten nicht in der setup()-Funktion deklariert werden. Vorzugsweise außerhalb der Funktionen als globale Variablen. Werden sie in der loop()-Funktion deklariert, wird mit jedem Schleifendurchlauf neuer Speicher für die gleiche Variable reserviert, was auf Mikrocontrollern mit wenig Arbeitsspeicher irgendwann zu Problemen führen kann.

Werfen Sie einen Blick in die Deutsche Arduino Referenz für eine umfangreiche Beschreibung der Funktionen, die man in der Arduino IDE verwenden kann. Testen Sie auch die Beispiele. Da gibt es viel zu entdecken. Außerdem gibt es eine mehrteilige Reihe mit dem Thema Arduino IDE - Programmieren für Einsteiger im AZ-Blog-Bereich. Dort finden Sie weitere Tricks wie z.B. die Portmanipulation, um mehrere digitale Pins gleichzeitig zu initialisieren und zu schalten.


Wir wünschen eine frohe Adventszeit.

Andreas Wolter

für AZ-Delivery Blog

Specials

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Aanbevolen blog berichten

  1. Installeer ESP32 nu van de raad van bestuur
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmeren via Wi-Fi