Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
1
Arduino Tutorials Robotik-AG Weil der Stadt Autor: Thomas Jörg | Stand: 31. Oktober 2017 | Version 1.48
#include <Wire.h>
void setup()
Wire.begin();
Serial.begin(9600);
Serial.println("\nI2C Scanner");
void loop()
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++ )
Wire.beginTransmission(address); error = Wire.endTransmission();
if (error == 0)
Serial.print("I2C device found at 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
else if (error == 4)
Serial.print("Unknow error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000);
2
Inhalt Arduino Tutorials Robotik-AG Weil der Stadt .......................................................... 1
Arduino Pinouts. ...................................................................................................... 3
Erläuterung: ..................................................................................................... 4
„Blink“: Interne LED: ................................................................................................ 5
Schritt 2: Externe LED ....................................................................................... 5
Potentiometer, LDR, Taster: einfache Sensoren ...................................................... 6
Weitere analoge/lineare Sensoren: ................................................................ 7
Kombination von Sensoren und Aktoren ................................................................. 8
Helligkeit einer LED über Potentiometer/Sensor steuern ............................... 8
Die PWM (Pulsweitenmodulation) .......................................................................... 9
Die H-Brücke .......................................................................................................... 10
Beschaltung des L298n: ......................................................................................... 11
Schaltlogik für EnA: ........................................................................................ 12
Ultraschallsensor HC-SR04 ..................................................................................... 13
Adafruit DVR8833 H-Brücke ................................................................................... 14
DRV8833: Schaltlogik laut Datenblatt ............................................................ 15
Erläuterung zu den Tabellen: ............................................................................. 15
DRV8833: PWM-Betrieb laut Datenblatt ....................................................... 15
Pololu DRV8835 H-Brücke ...................................................................................... 16
WS2812B „Neopixels“ ............................................................................................ 17
Der I2C-Bus (sprich: „I-Quadrat-C“) ........................................................................ 18
Beispiele einiger I2C Sensoren/Aktoren für die Robotik: ...................................... 19
OLED128x32 I2C mit SSD1306-Controller ............................................................... 20
Der MPU 6050 IMU-Sensor .................................................................................... 21
Schritt 1: Die Bibliotheken von Jeff Rowberg ................................................ 21
Schritt 2: Verkabelung ................................................................................... 21
Schritt 3: Kalibrierung des MPU 6050 ............................................................ 22
Schritt 4: Test des MPU 6050 ......................................................................... 22
Ersatz für den Ultraschall: VL53L0X-TOF-I2C-Sensor .............................................. 24
Funktionsüberprüfung ................................................................................... 26
Verwendete Bibliotheken .............................................................................. 26
Interrupt-Modus des VL53L0X ........................................................................... 26
Erläuterung der Sensorbefehle im Quelltext: ................................................ 26
„Blink“-Sketch neu: Timersteuerung...................................................................... 27
Skript-Variante 1: Timer-Prinzip ..................................................................... 27
Skript-Variante 2: Zeitmessung eines Loops .................................................. 27
3
Arduino Pinouts. Quellen-Grundlage: https://makezine.com/wp-content/uploads/2013/02/arduino_uno_pinout_web.png
4
Erläuterung: Der Arduino Uno besitzt insgesamt (von links oben nach rechts unten gezählt) 7 + 6 + 10 + 8 = 31 Pins. Die wichtigsten Pinouts sind:
5V: Entweder: Eingangsspannung von 5V für die Spannungsversorgung des Arduinos aus einer externen Quelle
oder: Ausgangsspannung von 5V für die permanente Versorgung von LEDs oder Sensoren.
Achtung! Wird der 5V-Pin als Spannungs-Eingang verwendet, wird die Spannung NICHT reguliert!
3V3: Ausgangsspannung von 3,3V für die permanente Versorgung von LEDs oder Sensoren.
Vin: Hierüber kann der Arduino mit einer externen Spannung zwischen 7 und 12 Volt versorgt werden. Ein Spannungswandler sorgt für
konstante Spannungsversorgung des Arduinos von 5V
GND (3 mal): „Ground“, „Minuspol“
A0 … A5: „ADC“ Analog-Digital-Wandler. Hier können analoge Sensorwerte eingelesen werden. C-Befehl: analogRead(A1);
SCL / SDA: I2C-Bus, „Serial-Clock“ / „Serial Data“, Fortgeschrittenes Feature
SCK /MISO /MOSI / SS: SPI-Bus, „Serial Clock“ / „Master In Slave Out“ / „Master Out Slave In“ / „Slave Select“, Fortgeschrittenes Feature
PWM (5 mal): „Puls-Weiten-Modulation“, Ausgabe von Analog-ähnlichen Werten in Form von Rechteckpulsen
TX / RX: Serielle Kommunikationsschnittstelle, TX -> „Transmit“, senden / RX -> „Receive“, empfangen
Es können die Pins 1 bis 13 und A0 bis A5 ebenfalls als digitale Pins genutzt werden! Das heißt: Sie können programmiert werden.
NICHT programmierbar sind die Pins Reserved / Reset / IOREF / GND / 5V / 3V3 / Vin / Aref. Das sind 10 Stück (GND gibt es 3 mal)
5
„Blink“: Interne LED: Die interne LED an Pin 13 zum Blinken bringen:
void setup() // Setup-Funktion Anfang
pinMode(13, OUTPUT); // Pin Nummer 13 wird als Output, also Ausgang geschaltet.
// Setup-Funktion Anfang
void loop() // Endlosschleife Anfang
digitalWrite(13, HIGH); // LED anschalten
delay(1000); // 1000 Millsekunden warten
digitalWrite(13, LOW); // LED ausschalten
delay(1000); // 1000 Millsekunden warten
// Endlosschleife Ende
Nun sollte die interne LED auf dem Board leuchten.
Schritt 2: Externe LED An den Arduino-Pin 13 wird eine LED zusammen mit einem ca. 150 Ohm-Widerstand
angebunden. Damit der Stromkreis geschlossen ist, verbindet man mit ‚GND‘.
Setzt man den Pin 13 nun durch Programmierung auf ‚HIGH‘, dann wird er angeschaltet.
Und dann liefert er Spannung, um die LED zum Leuchten zu bringen.
Der Quelltext bleibt dabei gleich.
NIEMALS die LED ohne Widerstand mit demArduino verbinden!
Exkurs: Berechnung Vorwiderstand für LED: Eine rote LED benötigt IMMER 1,6 Volt Betriebsspannung.
Der Arduino liefert 5 Volt an jedem PIN.
5 Volt – 1,6 = 3,4 Volt müssen „vernichtet“ werden.
Zusätzlich dürfen maximal 25 Milli-Ampere Stromstärke herrschen.
Mit R = U/I = 3,4 Volt / 0,025 Ampere = 150 Ohm dimensioniert man den Widerstand.
https://www.elektronik-kompendium.de/sites/bau/1109111.htm
100 Ohm bis
330 Ohm
Abbildung 1: Ansteuerung einer LED
100 Ω 150 Ω 220 Ω 330 Ω 470 Ω
Abbildung 2: Beispiele für LED-Vorwiderstände.
Widerstandswerte werden durch die Farben der Ringe codiert:
Die oberen beiden Ringe entsprechen einer Zahl, der dritte Ring einem Multiplikator (z.B. “mal 10” oder “mal 1000”. Der letzte Ring gibt die Genauigkeit wider.
https://www.elektronik-
kompendium.de/sites/bau/1109051.htm
6
Potentiometer, LDR, Taster: einfache Sensoren Als Beispiel für Sensoren sind hier Potentiometer und LDR gezeigt. Viele andere Sensoren lassen sich genauso programmieren und an den Arduino anschließen.
Abbildung 3: Poti am Arduino
Abbildung 4: Simple Sensorschaltung
Ein ‚Potentiometer‘ am Arduino: Der Arduino misst, wie weit das Poti nach links oder nach rechts gedreht ist. Daraus erzeugt er einen Wert zwischen 0 und 1023.
Ein ‚Helligkeitssensor‘ am Arduino: Der Arduino misst, wie stark das Licht eingestrahlt wird. Der LDR bildet mit dem zweiten Widerstand einen sogenannten Spannungsteiler, genauso wie ein Potentiometer. Deshalb liest man den Sensor genauso aus.
int sensorwert = 0; //Variable für Sensor
void setup()
pinMode(A0, INPUT);
Serial.begin(9600); //Ausgabe an PC vorbereiten
void loop()
sensorwert = analogRead(A0); //Sensor auslesen
Serial.println(sensorwert); //auf dem PC ausgeben
int sensorwert = 0; //Variable für Sensor
void setup()
pinMode(A0, INPUT);
Serial.begin(9600); //Ausgabe an PC vorbereiten
void loop()
sensorwert = analogRead(A0); //Sensor auslesen
Serial.println(sensorwert); //auf dem PC ausgeben
10 kOhm-
Potentiometer
LDR: “Light Dependent Resistor”
7
Abbildung 5: Schalter am Arduino
Weitere analoge/lineare Sensoren: Beschleunigungssensor, z.B. ADXL335
Temperatursensor, z.B. LM35 (0-100°C)
Licht/Farb/Infrarotsensoren, z.B. CNY70
Magnetsensoren, z.B. Allegro A1324
Barometer (Drucksensoren), z.B. MPX 4115A
Kraftsensoren, z.B. FSR 400
Ein ‚Schalter‘ am Arduino: Der Arduino misst, ob man den Schalter gedrückt hat oder nicht. Der Wert ist 0 oder 1.
int taster = 0; //integer-Variable für Taster
void setup()
pinMode(A0, INPUT);
Serial.begin(9600);//Ausgabe an PC vorbereiten
void loop()
taster = digitalRead(A0);//Sensor auslesen
Serial.println(taster);//auf dem PC ausgeben
10 kOhm-
Widerstand
8
Kombination von Sensoren und Aktoren
Helligkeit einer LED über Potentiometer/Sensor steuern
int sensorwert = 0; //integer-Variable für Sensor
void setup()
pinMode(A0, INPUT); //zum Auslesen des Potis
pinMode(11, OUTPUT); //zum Ansteuern der LED
Serial.begin(9600); //Ausgabe an PC vorbereiten
void loop()
sensorwert = analogRead(A0); //Sensor auslesen
analogWrite(11, sensorwert/4); //PWM-Ansteuerung der LED
Serial.println(sensorwert); //auf dem PC ausgeben
Erläuterung: zu „analogWrite(11, sensorwert/4)“:
Der Befehl „analogRead“ liefert Werte zwischen 0 und 1023.
Der Befehl „analogWrite“ schreibt aber nur im Bereich zwischen 0 und 255.
Daher muss der Bereich von 0-1023 auf den Bereich von 0-255 „gemapped“ (abgebildet) werden.
Das erreicht man, indem man durch vier teilt.
Abbildung 6: Sensor und Aktor zusammen
9
Die PWM (Pulsweitenmodulation) Ein Mikrocontroller wie der Arduino Uno kann keine unterschiedlichen Spannungswerte ausgeben.
(moderne Mikrocontrollerboards wie z.B. der Arduino Due besitzen sogenannte DACs (digital to analog-Konverter) ).
Die Helligkeit der LED wird also nicht durch die Spannung des Uno gesteuert, sie erhält immer 5 Volt. Die Steuerung erfolgt über schnelles Ein- und Ausschalten der 5-Volt-
Spannung.
Helles Licht bedeutet „Lange anschalten, kurz ausschalten“, weniger helles Licht erreicht man durch
„kurz anschalten, lange ausgeschaltet lassen“.
Die unterschiedlichen Verhältnisse zwischen An- und Ausgeschaltet bezeichnet man als „Duty-Cycle“.
Ein Duty-Cycle von 50% bedeutet, dass die „An“-Dauer so lange ist wie die „Aus“-Dauer.
Der Arduino schaltet dabei den Analogpin sehr schnell: er ist normalerweise mit 500Hz getaktet,
schaltet also ca. 500mal pro Sekunde an- und aus.
Abbildung 8: PWM gemessen am Oszilloskop
Abbildung 7: Prinzip der PWM
10
Die H-Brücke Problem: Ein Motor kann nicht vom Arduino direkt angesteuert werden, denn er benötigt viel Energie, die der Arduino nicht liefern kann.
Größenordnung: Maximale Leistungsabgabe Arduino Uno 200mA bei 5 Volt, entspricht 5V * 0,2A = 1 Watt. Anforderungen Motor z.B. Pololu 73:1 Metal Gearmotor: 3,3
Ampere maximal bei 6Volt entspricht 19,8 Watt.
Es muss also ein Bauteil zwischen Arduino und Motor zwischengeschaltet werden, welches einerseits vom Arduino Signale annimmt und weiter die Motoren ansteuert.
Da hier elektrische Leistung gefordert ist, spricht man von sogenannter Leistungselektronik. Eine H-Brücke kann darüber hinaus einen Motor sowohl vorwärts als auch
rückwärts laufen lassen. Für einen Roboter ist die H-Brücke daher ein zentrales Bauteil!
Die Geschwindigkeit des Motors wird über die H-Brücke mit einer PWM gesteuert. Je geringer der Duty-Cycle, desto langsamer bewegt sich der Motor.
Der L298N beinhaltet 2 voneinander unabhängige H-Brücken. Jede einzelne H-Brücke kann einen Motor ansteuern. Diese H-Brücken können betrieben werden zwischen 5
Volt und 35 Volt zur Motorsteuerung, und vertragen dabei maximal 2 Ampere
Stromstärke mit 20 Watt maximaler Gesamtleistung.
Output Motor 2 Output Motor 1
Motor-
Versorgungsspannung
PINs zur Motorsteuerung:
Hier ist die Verbindung
zum Arduino
Abbildung 10: Beschaltung laut Datenblatt des L298N
Abbildung 9: H-Brücke von oben
11
Beschaltung des L298n: Abbildung 11: Ausschnitt aus der Schaltung
Abbildung 12: Schaltung für "Vorwärts"
Abbildung 13: Schaltung für "Rückwärts"
12
EnA („Enable A“) ist die Vorrausetzung für die Schaltung.
Ist EnA ausgeschaltet, wird auch gleichzeitig die Motor-
versorgung abgeschaltet.
bedeutet „Logisches UND“ ,
bedeutet „Logisches UND mit einem
Invertierenden Eingang“
Schaltlogik für EnA:
EnA In1 V1 R2 EnA In2 R1 V2
0 0 0 0 0 0 0 0
0 1 0 0 0 1 0 0
1 0 0 1 1 0 0 1
1 1 1 0 1 1 1 0
• Um die H-Brücke 1 „vorwärts“ zu schalten, müssen
V1 und V2 angeschaltet,
R1 und R2 ausgeschaltet sein.
Es muss also: In1 = HIGH, In2 = LOW
• Um die H-Brücke 1„rückwärts“ zu schalten, müssen
R1 und R2 angeschaltet,
V1 und V2 ausgeschaltet sein.
Es muss also: In1 = LOW, In2 = HIGH
int EnA = 10;
int IN1 = 3;
int IN2 = 5;
void setup ()
pinMode (EnA, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
void loop ()
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
for (int i=0; i<256; i++)
analogWrite (EnA, i);
delay (10);
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
for (int i=0; i<256; i++)
analogWrite (EnA, i);
delay (10);
digitalWrite (IN1, LOW);
digitalWrite (IN2, LOW);
analogWrite (EnA, 0);
Abbildung 14: L298N mit Arduino
13
Ultraschallsensor HC-SR04 Gute Quelle: http://www.mikrocontroller-elektronik.de/ultraschallsensor-hc-sr04/
int trigger = 3; // Arduino Pin an HC-SR04 Trig
int echo = 2; // Arduino Pin an HC-SR04 Echo
void setup()
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
Serial.begin(9600);
void loop()
long entfernung = 0;
long zeit = 0;
//Mess-Sequenz start
digitalWrite(trigger, LOW); // Trigger ausschalten
delayMicroseconds(3); // kurz warten
noInterrupts(); // Störungsfreien Betrieb der Messung sicherstellen
digitalWrite(trigger, HIGH); // Trigger Impuls 40 Kilohertz AN ...
delayMicroseconds(10); // ... für 10 Mikrosekunden
digitalWrite(trigger, LOW); // Trigger wieder ausschalten
zeit = pulseIn(echo, HIGH); // Nun wird die Echo-Zeit gemessen.**
interrupts(); // Jetzt darf wieder "gestört" werden
//////////////////////////// // Mess-Sequenz Ende, nun erfolgt Umrechnung
zeit = (zeit / 2); // Zeit halbieren, weil Schall hin- und zurückläuft
entfernung = zeit / 29.1; // Umrechnung Zeit in Zentimeter (v = 343 m/s)
Serial.println(entfernung);
** Der Messvorgang wird durch eine fallende Flanke am Trigger-Eingang ausgelöst. Das vorhergehende High-Signal muss dabei eine Mindestzeit von 10 Mikrosec anliegen.
Strombedarf: 2mA pro Messung
Signalart: TTL-Puls (HIGH/LOW)
Max. Entfernung: 3m
Min. Entfernung: 2 cm
Max. Messungen/s: 50
Genauigkeit: ca. 3mm (naja…)
Abbildung 15: Schaltung SR04
14
Adafruit DVR8833 H-Brücke Der TI 8833-Motortreiber arbeitet im Bereich zwischen 2,7 – 10,8 Volt. Standardmäßig ist eine
Strombegrenzung von 1,2 A pro H-Brücke eingestellt. Das hält einige Motoren leider davon ab,
zu starten. In diesem Fall wirken die 1,2 A als Anlaufstrombegrenzung, der Motor bleibt
stehen. Mit zwei Methoden lässt sich das eventuell ändern:
a) 0,2 Ohm-Widerstand zwischen AS (BS)-Kanal und GND verdoppeln die Maximalstromstärke.
b) Die PWM-Frequenz kann heruntergesetzt werden (bis herunter auf 30 Hertz).
Bei niedriger PWM-Frequenz läuft der Motor zwar unrund, startet aber bei geringen Duty-
Cycles. Im Skript unten wird der eher unkritische Timer1 verändert, sodass delay ()- und
milli()-Funktionen unverändert funktionieren.
void setup()
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
cli(); //Interrupts aus.
TCCR1B = TCCR1B & 0b11111000 | 0x05; //PWM auf 30 Hz
sei(); //Interrupts an.
void loop()
digitalWrite(10, LOW); //Vorwärtslauf
for (int i = 1; i < 255; i++) //Beschleunigen
analogWrite(9, i);
delay(10);
for (int i = 255; i > 0; i--) //Abbremsen
analogWrite(9, i);
delay(10);
delay(100);
digitalWrite(9, LOW); //Rückwärtslauf
for (int i = 1; i < 255; i++) //Beschleunigen
analogWrite(10, i);
delay(10);
for (int i = 255; i > 0; i--) //Abbremsen
analogWrite(10, i);
delay(10);
7,4V LiPo
0,2 Ohm-
Widerstand
Abbildung 16: Verdrahtung DRV8833
Abbildung 17: Foto des Aufbaus
15
DRV8833: Schaltlogik laut Datenblatt
xIN1 xIN2 xOUT1 xOUT2 Funktion
0 0 0 0 Gleiten
0 1 LOW HIGH Rückwärts
1 0 HIGH LOW Vorwärts
1 1 LOW LOW Bremse
DRV8833: PWM-Betrieb laut Datenblatt
xIN1 xIN2 Funktion
PWM 0 Vorwärts mit schnellem Stromabklingen
PWM 1 Vorwärts mit langsamem Stromabklingen
0 PWM Rückwärts mit schnellem Stromabklingen
1 PWM Rückwärts mit langsamem Stromabklingen
Erläuterung zu den Tabellen:
xIN1, xIN2, xOUT1, xOUT2: “x” steht für
Entweder Kanal A oder Kanal B
SLP, Sleep-Modus:
In Abbildung 16 direkt an 5V angeschlos-
sen, also auf HIGH. Kann auch digital an-
gesteuert werden.
Wird SLP auf LOW gesetzt, wird der
gesamte Chip abgeschaltet.
Abbildung 18: Sleep-Funktion
16
Pololu DRV8835 H-Brücke Der TI DRV8835-Motortreiber beinhaltet zwei unabhängige H-Brücken und arbeitet im Bereich zwischen 1,5 und 11 Volt. Er kann kontinuierlich 1,2 Ampere pro H-Brücke liefern und im Peakbereich bis 1,5 Ampere. Bei Vergleich mit dem Datenblatt sieht man, dass der Motortreiber im PHASE/ENABLE mode und nicht im IN/IN mode betrieben wird. Die Logiktabelle sieht wie folgt aus:
xIN1 (xEnable)
xIN2 (xPhase)
xOUT1 xOUT2 Funktion
0 0 LOW LOW Bremsen
1 1 LOW HIGH Rückwärts
1 0 HIGH LOW Vorwärts
void setup()
pinMode(9, OUTPUT); //Motor 1: PWM-PIN
pinMode(7, OUTPUT); //Motor 1: Richtungs-PIN
pinMode(8, OUTPUT); //Motor 2: PWM-PIN
pinMode(10, OUTPUT);//Motor 2: Richtungs-PIN
void loop()
beideVorwaertsRueckwaerts();
beidePWM();
void beidePWM()
for (int i = 0; i < 255; i++)
analogWrite(9, i);//M1 vorwaerts
digitalWrite(7, LOW);
analogWrite(10, i);//M2 vorwaerts
digitalWrite(8, LOW);
delay(20);
for (int i = 0; i < 255; i++)
analogWrite(9, i);//M1 rueckwaerts
digitalWrite(7, HIGH);
analogWrite(10, i);//M2 rueckwaerts
digitalWrite(8, HIGH);
delay(20);
void beideVorwaertsRueckwaerts()
digitalWrite(9, HIGH);//M1 vorwaerts
digitalWrite(7, LOW);
delay(1000);
digitalWrite(9, HIGH);//M1 rueckwaerts
digitalWrite(7, HIGH);
delay(1000);
digitalWrite(9, LOW);//M1_stopp
digitalWrite(7, LOW);
digitalWrite(10, HIGH);//M2 vorwaerts
digitalWrite(8, LOW);
delay(1000);
digitalWrite(10, HIGH);//M2 rueckwaerts
digitalWrite(8, HIGH);
delay(1000);
digitalWrite(10, LOW);//M2_stopp
digitalWrite(8, LOW);
Erläuterung zu der Tabelle: xIN1, xIN2, xOUT1, xOUT2: “x” steht für
Entweder Kanal A oder Kanal B
Abbildung 19: Pololu DRV8835 Verdrahtung
17
WS2812B „Neopixels“ Hierbei handelt es sich um Dreifarb-RGB-LEDs, die 2563 = 16,7Mio Farben darstellen kann.
Die LED besitzt einen eigenen Controller, der mittels einer Adafruit-Bibliothek angesteuert
werden kann (Einbindung der Bibliothek siehe Abbildung 21):
https://github.com/adafruit/Adafruit_NeoPixel/archive/master.zip
Mittels dieser Bibliothek kann die LED recht einfach programmiert werden. Diese sogenannten
„Neopixels“ lassen sich in hoher Anzahl hintereinanderschalten und programmieren. Hier
ist die Programmierung eines einzelnen Neopixel beispielhaft an Pin 11 abgebildet:
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixel=Adafruit_NeoPixel(1,11,NEO_GRB+NEO_KHZ800);
void setup(void)
pixel.begin();
void loop(void)
pixel.setPixelColor(0, pixel.Color(255, 0, 0)); pixel.show();
delay(5); pixel.setPixelColor(0, pixel.Color(0, 255, 0));
pixel.show();
delay(5);
pixel.setPixelColor(0, pixel.Color(0, 0, 255));
pixel.show();
delay(5); pixel.setPixelColor(0, pixel.Color(0, 0, 0));
pixel.show();
delay(5);
Neopixel-Bibliothek
1. Neopixel: LED Nr.0
Anzahl Neopixels
Arduino-Pin
Abbildung 20: Schaltschema
Neopixel
Abbildung 21: Einbindung der
Bibliothek
Abbildung 22: Anschlüsse
Neopixel
18
Der I2C-Bus (sprich: „I-Quadrat-C“) Problem: Viele Sensoren sind in der simplen Spannungsteiler Schaltung zu ungenau (Stichwort: 10-Bit Auflösung des Arduino-Uno-ADC).
Außerdem benötigen viele Sensoren eine aufwendige Datenaufbereitung, die schnell sein muss. Ein gutes Beispiel ist der nebenstehend
abgebildete BNO055, ein „Orientierungssensor“, bei dem Gyro-, Beschleunigungs- und Kompass-Sensor zusammenwirken: Jeder der drei
Sensortypen liefert x-, y- und z-Rohdaten. Diese insgesamt 9 verschiedenen Daten müssen mathematisch sehr aufwendig verarbeitet werden.
Das würde einen einzelnen Arduino deutlich überfordern.
Deshalb verbaut man oftmals Sensoren mit eigenen kleinen Mikrocontrollern zusammen. Der Sensor-eigene Mikrocontroller ist dann einerseits
für die Datenverarbeitung zuständig. Weiterhin stellt dieser Sensor-Controller dem Arduino dann die fertig aufbereiteten Daten zur Verfügung.
Die Daten fließen vom Sensor-Controller zum Arduino in einer eigenen standardisierten Sprache, die über eigene standardisierte Leitungen
erfolgt. Man spricht bei der Sprache von einem sogenannten „Protokoll“, die Leitungen nennt man „BUS“ (BUS für „binary unit system“).
Tipp: Bevor man ein I2C-Gerät besorgt und anschließt, bitte UNBEDINGT darauf achten, dass
a) eine gute ausführliche Dokumentation zum Gerät vorhanden ist
b) eine Bibliothek für den Arduino bereits geschrieben ist.
Sonst verliert man Zeit und Nerven!
Spannungsversorgung
für den Sensor
Serial Clock
Datenleitung
Abbildung 23: I2C-Beispiel BNO055
Abbildung 24: Verkabelungsprinzip I2C-Sensor am Beispiel Adafruit TSL2561
MASTER SLAVE
19
Beispiele einiger I2C Sensoren/Aktoren für die Robotik: Sensor BNO055
Lagesensor TMP006 Infrarotsensor
TCS34725 Farbsensor
Abbildung
Speicher 7716 Byte (23%) 11116 Byte (34%) 6874 Byte (21%)
Libraries Adafruit_BNO055-master.zip
Adafruit_TMP006-master.zip
Adafruit_TCS34725-master.zip
Sensor VL53L0X „Time Of Flight“ Distanz-S.
AKTOR: OLED Display SSD1366
Abbildung
Speicher 17256 Bytes (53%) 6308 Bytes (19%)
Libraries Adafruit_VL53L0X-master.zip
Adafruit_SSD1306-master.zip Adafruit-GFX-Library-master.zip
Erläuterung: Die Bibliotheken für die Sensoransteuerung benötigen oftmals
selbst eine große Menge an Speicher. Da der Uno nur 32kB an nutzbarem
Speicher besitzt, muss man hier mit dem Speicherbedarf aufpassen und
kalkulieren!
// i2c_scanner
// This sketch tests the standard 7-bit addresses
#include <Wire.h>
void setup()
Wire.begin();
Serial.begin(9600);
Serial.println("\nI2C Scanner");
void loop()
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++ )
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
else if (error == 4)
Serial.print("Unknow error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000);
20
OLED128x32 I2C mit SSD1306-Controller
Der Controller besitzt die I2CAdresse 0x3C. Angeschlossen wird das Display wie folgt:
OLED Arduino UNO
VCC +5V
GND GND
SCL A5 (I2C Anforderung)
SDA A4 (I2C Anforderung)
Als Bibliotheken werden verwendet:
https://github.com/adafruit/Adafruit_SSD1306/archive/master.zip
https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Time.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
void setup()
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// I2C addr 0x3C
void loop()
display.clearDisplay();
display.setTextSize(0.5); // Textgröße festlegen
display.setTextColor(WHITE);// Textfarbe
display.setCursor(0,0); // Position des Cursors
display.println("Programm laeuft seit:");
display.println(millis());
display.display();
delay(1000);
Abbildung 25: OLED Anschlüsse
21
Der MPU 6050 IMU-Sensor Der Controller besitzt die Adresse i2C-Adresse 0x68, wenn ADO auf LOW (bzw. Nicht angeschlossen) liegt und 0x69, wenn ADO auf HIGH gesetzt
wird. Datenaustausch erfolgt via I2C, allerdings wird noch ein weiterer PIN am Arduino für einen Interrupt benötigt. Wir verwenden hier Pin 2
(sollte man so verwenden, weil die Bibliotheken darauf ausgerichtet sind). Der Interrupt bewirkt folgendes: Der MPU besitzt einen kleinen internen
Speicher, der sich durch die permanenten Messungen füllt. Läuft dieser Speicher voll, funktioniert der MPU nicht mehr korrekt – allerdings meldet
er sich dann via Interrupt-Signal über den INT-Pin. Durch diesen Interrupt wird in der Arduino-Bibliothek die Leerung des Speichers initiiert und der
Controller läuft im Anschluss weiter.
Schritt 1: Die Bibliotheken von Jeff Rowberg
https://github.com/jrowberg/i2cdevlib
Packt man die Zip-Datei aus, die man auf der Github-Webseite herunterladen kann, erhält man eine große Anzahl verschiedener
Bibliotheken, von denen wir zwei (2!) Stück benötigen. Wir wechseln in den Arduino-Unterordner und wählen I2Cdev und MPU6050
aus. Diese werden dann per Hand in den Arduino-Library-Ordner kopiert. Im Anschluss kann man die Bibliotheken und Beispiele in
der Arduino-Entwicklungsumgebung verwenden.
Schritt 2: Verkabelung Der MPU6050 benötigt VCC bei 3,3 Volt (5V läuft u.Umständen instabil!)
Abbildung 27: Libraries einbinden
Abbildung 26: Der MPU6050
Abbildung 28: Verkabelung MPU 6050
22
Schritt 3: Kalibrierung des MPU 6050 Der MPU besitzt einen Offset durch Fertigungstoleranzen. Diesen Offset muss man
durch Kalibrierung kompensieren. Man nutzt dazu ein Skript, das den individuellen
Offset eines jeweiligen Sensors bestimmt und als Zahl ausgibt. Diese Zahlenwerte
muss man im Anschluss in sein eigentliches Skript einbauen. Das Skript ist hier:
http://42bots.com/tutorials/arduino-script-for-mpu-6050-auto-calibration/
http://wired.chillibasket.com/2015/01/calibrating-mpu6050/
Das Skript wurde geschrieben von [email protected].
Die aktuelle Version ist: “Version 1.1 (31th January 2014)”. Danach kann man
googeln. Die Werte setzt man nun in sein Skript ein. Hier wurde das Skript
DMP6 verwendet.
Schritt 4: Test des MPU 6050 Getestet wird mit einem Processing-Skript, welches die Sensorneigung visualisiert. Processing ist eine
portable Java-Entwicklungsumgebung und kann unter www.processing.org heruntergeladen werden.
Es wurde mit der 32-bit-Variante der Version 3.3.6 gearbeitet. Nach der Installation wechselt man in
das Verzeichnis \processing\modes\java\libraries.
In diesen Library-Ordner werden die sogenannten “Toxic-Libs” kopiert, eine OpenSource-Physics-
Bibliothek. Diese Biblioteken findet man unter:
https://bitbucket.org/postspectacular/toxiclibs/downloads/
Abbildung 29: Ausgabe Kalbrierskript
Abbildung 30: Eintragen der Kalibrierwerte
Abbildung 31: Toxiclibs in Processing einbinden
23
Das DMP6-Skript, in dem bereits in Schritt 3 die Kalibierungswerte eingetragen wurden, wird nun auf die Processing-
Demo umgestellt. Dazu wird Zeile 100 auskommentiert und Zeile 117 aktiviert, sodaß die OUTPUT_TEAPOT-Demo
von Processing funktioniert. Das so abgeänderte Skript wird kompiliert und auf den Arduino geladen.
In Processing lädt man aus dem Jeff-Rowberg-Ordnersystem die MPUTeapot.pde – Javadatei:
Es handelt sich dabei um eine Demo, welche sich über die Serielle Schnittstelle mit dem Arduino verbindet, auf diese
Art die Sensordaten des MPU 6050 empfängt und in einem kleinen Grafikfenster visualisiert. Startet man das Programm,
so erscheint ein Fenster mit einem kleinen Flugzeugmodell, welches auf die Bewegung des Sensors reagiert.
Abbildung 32: Anpassung des DMP6-Skripts
Abbildung 33: Demofenster
von Processing
24
Ersatz für den Ultraschall: VL53L0X-TOF-I2C-Sensor Der Sensor benutzt das I2C-Protokoll, und besitzt die Adresse 0x29.
Der VL53L0X funktioniert im Prinzip wie ein Ultraschallsensor. Während beim
Ultraschallsensor aber Schallwellen genutzt werden, bei dem die Zeit bis zum Echo in
einen Abstand mittels Schallgeschwindigkeit umgerechnet wird, geschieht dies beim
einem TOF („Time Of Flight“)-Sensor durch die Nutzung von Licht: 940nm-Lichtpulse
(Infrarot) werden ausgesendet, an entfernten Gegenständen reflektiert und zum
Sensor zurückgeworfen. Misst man die Zeit zwischen Licht-Aussenden und Licht-
Empfangen, kann mittels Lichtgeschwindigkeit die Entfernung berechnet werden.
Die notwendige Elektronik ist aufgrund der Zeitanforderungen allerdings deutlich
aufwendiger, weil sie andere Zeiten auflösen muss: Schall legt etwa 300 Meter pro
Sekunde zurück, Licht hingegen 300.000 Kilometer pro Sekunde. Will man einen
Gegenstand zum Beispiel in 1,5 Meter Entfernung messen, läuft der Lichtstrahl 1,5 m
hin, dann 1,5 m zurück und löst dann im Photodetektor ein Ereignis aus. Der
Lichtstrahl ist also 3 m insgesamt gelaufen. Die Zeit dafür berechnet sich für 1,5m
Objektdistanz, bzw. 3m Lichtlauflänge:
𝑡𝐿𝑖𝑐ℎ𝑡 = 3𝑚
300.000𝑘𝑚
𝑠
=3𝑚
300.000.000𝑚
𝑠
= 1
100.000.000𝑠 = 10 𝑛𝑠 (𝑀𝑖𝑙𝑙𝑖𝑎𝑟𝑑𝑠𝑡𝑒𝑙 𝑆𝑒𝑘𝑢𝑛𝑑𝑒𝑛)
Wie in Abbildung 34 zu sehen ist, besitzt der Sensor einen Öffnungswinkel von 25°.
Bei einer Entfernung von 1 m entspricht das einer Breite von 43 cm.
Es handelt sich bei diesem Sensor um einen Klasse-1-Laser, weshalb man vorsichtig sein sollte:
Da der Laser im Infrarotbereich strahlt, kann man dessen Laserlicht nicht sehen. Aber: wie in Abbildung 34
zu sehen ist, besitzt der Laserstrahl eine Aufweitung von 35°, weshalb eine Gefährdung für die Augen nur
in unmittelbarer Nähe zur Emitteröffnung gegeben ist.
Also: Mindestabstand vom Sensor 30cm.
Der VL53L0X besitzt eine maximale Reichweite von 2m unter Optimalbedingungen (weisse Fläche), 80cm
bei grauen Flächen; damit sollte er für ein Robotik-Wettkampffeld ausreichen.
Abbildung 34: VL53L0X TOF Sensor
Abbildung 35: Definition Laserklasse 1 Die zugängliche Laserstrahlung ist unter venünftigerweise vorhersehbaren Bedingungen ungefährlich.
25
//Analogsteuerung *******************************
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
int A0Wert = 0;
int A0Alt = 0;
void setup()
Serial.begin(115200);
Wire.begin();
sensor.init();
sensor.setTimeout(500);
sensor.setMeasurementTimingBudget(200000);
sensor.startContinuous();
pinMode(A0, INPUT);
void loop()
A0Wert = analogRead(A0);
if ((A0Wert == 0) && (A0Wert !=A0Alt))
long zeitStart = micros();
int distanz = sensor.readRangeContinuousMillimeters();
long zeitDifferenz = micros() - zeitStart;
Serial.print("Distanz: "); Serial.println(distanz);
Serial.print("Zeit: "); Serial.println(zeitDifferenz);
A0Alt = A0Wert;
//Interruptsteuerung *******************************
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
bool neueMessung = false;
void setup()
Serial.begin(115200);
Wire.begin();
sensor.init();
sensor.setTimeout(500);
sensor.setMeasurementTimingBudget(200000);
sensor.startContinuous();
attachInterrupt(digitalPinToInterrupt(2), Fertig, FALLING);
void loop()
if (neueMessung)
int distanz = sensor.readRangeContinuousMillimeters();
Serial.print("Distanz: "); Serial.println(distanz);
neueMessung = false;
void Fertig()
neueMessung = true;
26
Funktionsüberprüfung Um zu überprüfen, ob der Sensor funktioniert und Licht abstrahlt, kann man seine Smartphonekamera über den laufenden Sensor
halten. Der CCD-Chip in der Smartphonekamera ist dazu in der Lage, Infrarotstrahlung zu detektieren und darzustellen.
Verwendete Bibliotheken Es existieren zwei Bibliotheken, einmal von Adafruit und einmal von Pololu. Die Pololu-Bibliothek benötigt weniger Speicherplatz
und lässt sich besser konfigurieren. Allerdings ist sie ein wenig komplexer in der Anwendung. Wir nutzen hier die Pololu-
Bibliothek. Man findet sie hier: https://github.com/pololu/vl53l0x-arduino
Die Datei vl53l0x-arduino-master.zip wird, wie bereits unter WS2812B-Neopixels beschrieben, in die Arduino-Umgebung
importiert.
Interrupt-Modus des VL53L0X Problematisch sind die Betriebsmodi des VL53L0X: Nutzt man in den Standardbeispielen z.B. den SingleMode, so benötigt der Sensor mindestens 23ms für eine Messung,
und der Arduino „steht still und wartet“. Das ist indiskutabel! Der zweite, sinnvollere Modus nutzt einen Interrupt: Der Sensor tätigt seine Messung permanent, er läuft
damit im sogenannten „Continous Mode“. Ist eine neue Messung fertig, wird ein Interrupt am GPIO-Pin gesetzt. Dann kann normalerweise per Interrupthandler die
Messung abgerufen werden. Die Messzeit am Arduino benötigt hier anstelle von 23ms nur noch 1,3ms und findet etwa alle 30 ms statt.
Bei der Interruptsteuerung gibt es aber ein weiteres Problem: Der GPIO-Pin erzeugt maximal 2,8Volt – und das ist für einen Arduino-Uno-Interrupt eventuell zu wenig.
Der Interrupt wird vom Arduino womöglich nicht zuverlässig ausgelesen – das muss am jeweiligen Arduinoboard ausprobiert werden.
Als Alternative wird hier das Signal via A0-Analogpin ausgelesen: Ändert sich der Zustand des A0-Pins auf den Wert „0“ (Simulation fallende Signalflanke), so ist der Sensor
auslesbar. Zum Schutz werden 470 Ω eingebaut, welche die Stromstärke des Sensors limitieren.
Technisch sauber wäre ein Level-Shifting: Eine Übersetzung der 2,8V-Logik auf die 5V-Logik des Arduinos, was z.B. per BSS138-Chip geschehen könnte.
Erläuterung der Sensorbefehle im Quelltext:
a) sensor.setTimeout() maximale Zeit, die der Arduino auf Sensordaten wartet.
b) sensor.setMeasurementTimingBudget() Angabe in Mikrosekunden. Die Zeit, welche der Sensor zur Generierung von Messdaten erhält. Je höher der
Wert, desto genauer die Messung. Hiermit kann auch indirekt gesteuert werden, wie oft der Interrupt ausgelöst wird.
c) sensor.readRangeContinuousMillimeters() Erzeugt die Messwertausgabe.
Abbildung 36: Handyfotot laufender Sensor
27
„Blink“-Sketch neu: Timersteuerung In den bisherigen Sketch-Skripten wurde immer die delay()-Funktion verwendet. Für Mikrocontroller-Programmierung ist das aber von erheblichem Nachteil und sollte
vermieden werden. Der Grund ist, dass während eines delay-Warteschleife der Prozessor nichts anderes machen kann und man so wertvolle Zeit verschenkt. Zeit, in der
man Messungen, Motoransteuerungen und Berechnungen durchführen sollte.
Um diese Nachteile zu verhindern, unterteilt man das Programm in einzelne Aufgaben, die in bestimmten Zeitintervallen abgearbeitet werden. In einem ersten Schritt kann
man dazu das unten abgebildete Skript nutzen. Hier laufen zwei Prozesse – nämlich das LED-Blinken und die Serielle Kommunikation – zeitlich voneinander entkoppelt in
unterschiedlichen Zeitintervallen.
Skript-Variante 1: Timer-Prinzip unsigned long zeitVorbei_LED;
unsigned long zeitVorbei_Serial;
unsigned long zeitJetzt;
void setup()
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
zeitVorbei_LED = millis();
zeitVorbei_Serial = millis();
Serial.begin(9600);
void loop()
zeitJetzt = millis();
if (zeitJetzt - zeitVorbei_LED > 500)
zeitVorbei_LED = zeitJetzt;
digitalWrite(13, !digitalRead(13));
if (zeitJetzt - zeitVorbei_Serial > 333)
zeitVorbei_Serial = zeitJetzt;
Serial.println(zeitJetzt);
Skript-Variante 2: Zeitmessung eines Loops unsigned long zeitVorbei_LED;
unsigned long zeitVorbei_Serial;
unsigned long zeitJetzt;
unsigned long LOOPDURCHLAEUFE = 0;
void setup()
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
zeitVorbei_LED = millis();
zeitVorbei_Serial = millis();
Serial.begin(9600);
void loop()
zeitJetzt = millis();
if (zeitJetzt - zeitVorbei_LED > 500)
zeitVorbei_LED = zeitJetzt;
digitalWrite(13, !digitalRead(13));
if (zeitJetzt - zeitVorbei_Serial >= 1000)
zeitVorbei_Serial = zeitJetzt;
Serial.print(LOOPDURCHLAEUFE);
Serial.println(" Loopdurchlaeufe pro Sek.");
LOOPDURCHLAEUFE = 0;
LOOPDURCHLAEUFE++;
In Skriptvariante 2 wird gemessen, wie häufig die
loop-Funktion pro Sekunde durchlaufen wird. Im
Seriellen Monitor wird bei einem Standard-UNO
bei diesem Skript ein Wert von ca. 150.000
Durchläufen pro Sekunde angezeigt. Das
entspricht ca. 6,7 Mikrosekunden (Millionstel
Sekunden) für einen Loop-Durchgang.
Da sich in der Loop-Funktion etwa 5 Anweisungen
befinden (die Anweisungen innerhalb der if-Ver-
zweigung werden so gut wie nie aufgerufen und
spielen daher keine Rolle), kann man abschätzen,
dass eine Anweisung in ca. 1 Mikrosekunde
abgearbeitet wird (grob vereinfacht).
Programmiert man also ein delay() von z.B.
5 Millisekunden irgendwo ein, so verliert man bis
zu 5000 Berechnungsmöglichkeiten!
Arduino CheatSheet Robotik-AG
Aufbau Quelltext
void setup() // einmalige Anweisungen void loop()
// permanent wiederholte Anw.
Kontrollstrukturen
if (x == 1)
//Anweisungen
else
//andere Anweisungen
switch (x)
case 1: //Anweisungen1
break;
case 2: //Anweisungen2
break;
default://Anweisungen
for(int i=0;i<255;i++)
//Anweisungen
while(x==true)
//Anweisungen
Funktionsdefinition (Beispiel)
int Quadrat(int x)return x*x;
Rückgabewert FunktName(Parameter)
Anweisungen;
return-Anweisung;
Zeitmessung
unsigned long millis()//50Tage
unsigned long micros()//70Min.
delay(x)//x in Millisekunden
delayMicroseconds(x)//Mikro-s.
Präprozessor-Anweisungen
#define //Compiler-Direktive
#include “file“//externe Bib.
#include <file.h>//interne Bib
Datentypen
boolean//1bit: 0/1, false/true
char //8bit -127..128
unsigned char //8bit 0..255
byte // 8bit 0..255
int //16bit -32767..32768
unsigned int //16bit 0..65535
long //32bit ±2147483647
unsigned long //0..4294967295
float //32bit Kommazahl
(double //64bit, nur bei DUE)
void//KEIN (Rückgabe)-Wert
Mathematische Operatoren
+ // Addition
- // Subtraction
* // Multiplikation
/ // Division
% // Modulus
= // Zuweisung
Logische Operatoren
== // bool "gleich"
!= // ungleich
< // kleiner als
> // größer als
<= // kleiner gleich
>= // größer gleich
&& // bool UND
|| // bool ODER
! // bool NICHT
Bitweise Operatoren
& //Bitweise UND
| //Bitweise ODER
^ //Bitweise Exklusiv ODER
~ //Bitweises invertieren
x<<n //Bitshift n bit links
x>>n //Bitshift n bit rechts
Zufallszahlen
random(maxV)//Zufallszahl bis
random(minV,maxV)//Z.Z von/bis
randomSeed(x)//Initialisierung
Qualifier
static x //lokale Variable
//wird nicht gelöscht
volatile x//Interrupt-Variable
const x //Read Only-Variable
Mathematik
min(x,y)//gibt kleinere Zahl
max(x,y)//gibt größere Zahl
abs(x) //Entfernt Vorzeichen
constrain(x,minV,maxV)
//Beschränkt Wertebereich
map(x,vonL,vonH,bisL,bisH)
//Überträgt Wertebereich
pow(basis,exponent)
// "Basis hoch Exponent"
sqrt(x) // Wurzel x
sin(x) cos(x) tan(x)//Trig.
atan(x) //Arkustangens x
atan2(x,y)//Arkustangens x/y
log10(x) //Dekadischer Log x
x++ //Inkrementieren „plus 1“
x-- //Dekrementieren „minus 1“
PIN Input/Output
pinMode(pin,INPUT)//Eingang
pinMode(pin,OUTPUT)//Ausgang
pinMode(pin, INPUT_PULLUP)
//Eingang auf HIGH mit 10kOhm
digitalRead(Pin)//High od Low
digitalWrite(Pin, HIGH)//5V
digitalWrite(Pin, LOW)//0V
analogRead(Pin)//liest 0..1023
analogWrite(Pin,x)//0..255 PWM
Frequenzoutput an PWM-Pin
tone(Pin,freq)//PWM-Frequenz
//mit 50%Duty-Cycle,
//min 31Hz, max 65535Hz
tone(Pin, freq, dauer)//in ms
stop()//Stoppt Ton
noTone(Pin)//stoppt Ton an Pin
Arrays
int myVar[6]//Deklaration
int myVar[]=2,3,7,5
char text[5]= "Hallo"
char text[3]='H', 'a', 'l'
text.length//Anzahl Elemente
Zahlendarstellungen
x = 100; //Dezimal
x = 0144; //Oktal
x = 0b01100100 //Binär
x = 0x64 //Hexadezimal
Serielle Kommunikation
Serial.begin(9600)//bytes/s:
300,1200,2400,4800,9600,14400,
19200,28800,38400,57600,115200
Serial.end()
Serial.available()//test ob >0
char x = Serial.read()
Serial.write(x)//schreibe Byte
Serial.print(x)//Bytesequenz
Serial.println(x)//mit Newline
Serial.flush()//warte bis fertig
#include <SoftwareSerial.h>
SoftwareSerial xy(2,3)//Rx, Tx
xy.print/ xy.read / xyz.end …
Typecasting
float f=3.6; f = (int) f; //3
float g=3.6; g = (char) g; //3
int x= 256; x = (char) x;//255
int y= 3; y = (float) y; //3.0
Interrupts
attachInterrupt(IR,ISR,Modus)
//IR-Pin UNO: 2 od. 3,
//ISR: Interrupt Service Routine,
//Modus: Trigger, wenn Signal:
//LOW CHANGE RISING FALLING
detachInterrupt(IR)//entfernen
interrupts()//Interrupts an
noInterrupts()//Interrupts aus
PIN-Funktionen
Serial Pins: 0-Tx 1-Rx
PWM Pin: 5,6 Timer 0;
9,10 Timer 1;
3,11 Timer 2;
SPI: 10-SS, 11-MOSI,
12-MISO, 13-SCK
I2C: A4-SDA, A5-SCK
Interrupt: 2,3
dauer = pulseIn(pin, HIGH)
//wartet, bis Pin auf HIGH,
startet Zeitmessung, wartet auf
LOW und stoppt Messung. Liefert
die Pulslänge in Microsekunden.
FUNKTIONERT AUCH MIT LOW.