Arduino Plattform
Die MSXFAQ ist beileibe keine Webseite für Hardware Basteleien aber es muss auch nicht immer ein großer Server mit vollwertigem Betriebssystem sein, um Spaß mit Programmierung zu haben. In meiner Lehrzeit war "Eletronikbasteln" noch überwiegend analoge Technik (Transistoren, Operationsverstärker) oder Digitaltechnik mit TTL-Chips. (74xx Serie). die zwar billig waren aber meist auch nur ein paar Gatter hatten. Die ersten Computer waren entsprechende TTL-Gräber und 1 MHz Taktrate, 64kByte RAM etc. waren schon Luxus.
Auch wenn die Arduino-Plattform noch viele Anhänger hat, so erwarten die meisten Projekte heute auch Bluetooth und WLAN. Hier lohnt sich dann ein Blick auf die ESP8266/ESP32-Geräte die mit der gleichen Arduino-IDE und oftmals identischen Libraries programmiert werden können.
Einstufung
Heute sieht die Zeit im Zeichen von PIC-Chips (AVR/ATTiny85 etc.), RaspberryPi (ARM) und auch Arduino schon anders aus. Ein Arduino ordne ich von der Rechenleistung, Speicherkapazität und Universalität unter einem RaspberryPi ein. Der hat ja doch ein vollwertiges Betriebssystem (Basierend auf Linux) an Bord, so dass sogar Skriptsprachen (PHP, PERL) laufen. Unterhalb des Arduino gibt es die noch sparsameren, kleineren Chips der PIC-Serie, die aber auch etwas aufwändiger zu programmieren sind.
Hardware
Der Arduino ist eine schöne Plattform in der Mitte, die relativ preiswert ist, aber letztlich mit ganz wenig Aufwand und einer einfachen Programmieroberfläche den Einstieg in die hardwarenahe Entwicklung erlaubt. Entwickelt wurde die Plattform in Italien wobei die Hardware selbst "offengelegt" wurde. Zudem wurde eine IDE zum Schreiben von Programmen entwickelt, die über Parameter flexibel auf verschiedene Geräte angepasst werden kann. Entsprechend gibt es mittlerweile neben dem "originalen" Arduino auch viele Nachbauten (speziell aus China) oder andere Varianten.
- Homepage des Arduino
http://arduino.cc/
http://arduino.cc/en/Products.Compare - Arduino-Plattform
http://de.wikipedia.org/wiki/Arduino-Plattform - List of Arduino boards and
compatible systems
http://en.wikipedia.org/wiki/List_of_Arduino_boards_and_compatible_systems - Virtuelle Arduino Emulatoren
- Spielen ohne Löten
Emulare: http://emulare.sourceforge.net/
Virtual Breadboard http://www.virtualbreadboard.com/ $
iArduino http://n.mtng.org/ele/arduino/iarduino.html
Simuino https://code.google.com/p/simuino/
simulide http://sourceforge.net/projects/simulide/ - Arduino Starterset (ca 80€)
http://www.segor.de/#/arduino-a-co/arduino-kits/arduino-starterset - Fritzing Creator Kit (ca.
90€)
http://www.reichelt.de/?ARTICLE=139321 - Allnet Arduino Starter Kit
(ca. 60€)
http://www.reichelt.de/?ARTICLE=144421 - Sensebox
www.sensebox.de
http://sensebox.uni-muenster.de/en/fuer-buerger/sensebox-basic/
OpenSenseMap http://sensebox.uni-muenster.de/opensensemap/
http://www.exp-tech.de/sensebox-basic 75€ - Selecting an Arduino
https://learn.adafruit.com/adafruit-arduino-selection-guide/selecting-an-arduino
Übersicht https://learn.adafruit.com/assets/6316
Gerade der zweite Link zeigt, wie vielfältig die Boards heute sein können sowohl in der Bauart und Größe als auch in der Anzahl der Pins. Sogar "waschbare" Boards die kleiner als eine Münze sind, sind dabei. für mich als alter Elektronik-Bastler ist es schon faszinierend, was mit ein bisschen Software umgesetzt werden kann, wofür man früher ganze diskrete Bauteile errechnet und gelötet hat. Mit ganz wenig externer Beschaltung lassen sich ganz viele Probleme lösen. Und Spaß macht es auch noch.
Da die Entwickler alles um Arduino als "Open Source" veröffentlichen, gibt es sehr viele Nachbauten. Insbesondere über Ebay finden sich Arduino-Clones, die oft weniger als 4 Euro/Stück kosten und portofrei in 3-6 Wochen per Post kommen und durchaus brauchbar sind. Denken Sie aber dran, das das Projekt auch von den Einnahmen die Weiterentwicklung finanziert.
Mit "Wiring" gibt es eine
ähnliche Plattform, zu der auch verschiedene
Hersteller interessante Hardware liefern und die
IDE für die Entwicklung sehr ähnlich ist. Es ist
schließlich die gleiche Prozessorfamilie
http://wiring.org.co/hardware/ ,
https://store.spark.io/ (z.B. Photon und
Core-Boards)
Achtung USB und SERIAL
Die ersten Arduino werden per serieller
Kommunikation programmiert und genutzt. Mit
einem USB-Anschluss war ein USB-Serial-Adapter
erforderlich, der bei einem Reset des Arduino
aber im PC "sichtbar" geblieben ist. Neuere
Arduino, die direkt USB auf dem Board haben.,
basieren auf dem auf dem ATmega32u4, der direkt USB unterstützt. Bei einem Reset verliert aber
auch kurz der PC den virtuellen COM-Port.
Anfang 2014 sind dies die Serien Leonardo, Mega,
Micro, Yun und LilyPad USB.
Die kleinen Arduinos kommen mit viel weniger Strom aus, als ein großer Computer und können Signale daher auch autark erfasst und speichern. Über Schnittstellen können die Daten ja immer noch ausgelesen und weiter verarbeitet werden. Das ist insbesondere z.B. für Zählen (Energieimpulse) und müssen (Spannungen) interessant, wo ich gar nicht einen PC mit Interrupt belegen will.
Einsatz bei der MSXFAQ
Den Weg zurück zur "Elektronik" habe ich über mehrere Anforderungen gefunden:
- Gebäudeautomatisierung
Durch den Bau eines Eigenheims habe ich mich natürlich mit den verschiedenen Möglichkeiten einer Steuerung beschäftigt, sei es KNX, LCN, HomeMatic um letztlich dann noch erst mal "klassisch" zu bauen. Wenn ich in ein Zimmer gehe und den Schalter drücke, dann muss das Licht angehen. Da ist der Mehrwert über eine Steuerung nicht immer nachvollziehbar. Nur die Rollläden werden zentral gesteuert. Zukünftig denke ich, dass allein die Menge an Altbauten für Nachrüstungen viele Produkte hervor bringt, die über das Stromkabel oder Funk sehr einfach funktionieren. Aber natürlich schaut man sich auch Dinge wie FHEM u.a. an. - Energiezählung (z.B.
Arduino und S0)
Ein klassisches Thema ist natürlich "Zählen von Impulsen". Auslöser war eine gefühlt hohe Stromrechnung für den Net at Work Serverbetrieb und die Klimaanlage. Zwischenzähler mit S0-Schnittstelle waren schnell installiert aber ablesen ist uncool. Und dann haben noch viele anderen Kollegen etwas "zählen" wollen aber keinen PC dafür abstellen. Auch ein RasPI bekommt native nicht alle Impulse sicher mit. Also was liegt näher als mit einem Arduino die Daten zu zählen und dann per COM-Port oder Ethernet abzufragen ? - Netzwerk-Probe
Ein RaspberryPi, ein "Arduino Ethernet" bzw. ein Netduino bringen mich auf den Gedanken, diese kleinen Boxen einfach als Ethernet-Probe zu verwenden um die Qualität der Netzwerkverbindungen zu müssen. So ein kleiner Arduino Ethernet könnte das sicher. Allerdings nicht mit großem Durchsatz. Dazu gibt es mitterlweile bessere Plattformen.
Die ersten Schritte
Wer bislang mit Windows gearbeitet hat, muss sich bei Arduino und anderen dieser kleinen Knechte erst mal umstellen. Auf dem System selbst lässt sich nicht wirklich entwickeln.
- Die EntwicklungsUmgebung
Sie benötigen also eine EntwicklungsUmgebung mit Editor und Compiler, was bei Arduino aber eine Java-gestützt EntwicklungsUmgebung ist. Ich habe mit der einfachen Arduino IDE begonnen, die die komplexen "Compile, Build, Flash"-Schritte stark vereinfacht.
http://arduino.cc/en/Main/Software
- Lerne die Sprache
Dann müssen Sie sich die Programmiersprache aneignen, was aber schon aufgrund der beschränkten Funktionen relativ zügig möglich ist, zumindest wenn Sie bislang schon mit C++ oder auch PowerShell gearbeitet haben. Entsprechende Beispiele unterstützen. - Code Deployment
Zuletzt müssen Sie den fertigen Code kompilieren und auf den Arduino "flashen". Auch das geht aber mit der IDE sehr einfach. Ein richtiges "Betriebssystem" gibt es also nicht. Der erzeugte Code wird direkt auf dem Prozesse ausgeführt. - Code Debugging
Einen richtigen "Debugger" gibt es leider nicht. Die Fehlersuche ist wie bei den früheren Skripten und Batchfiles, dass man an den fraglichen Stellen eine "Ausgabe" addiert. Beim Arduino wird dies meist ein schreiben auf den seriellen Port sein. Denkbar ist auch eine LED blinken zu lassen. Die Ausgabe auf dem Port ist natürlich ungeschickt, wenn dieser zugleich auch als Schnittstelle zur Kommunikation mit dem Programm genutzt werden soll. Einige Arduino haben einen zweiten COM-Port oder sie opfern ein paar Leitungen und klemmen z.B. ein LCD für die Fehlersuche an. Klassisch
Aber genau das macht es ja interessant. Auf dem Arduino kann quasi auch immer nur ein Programm geladen (geflashed) und entsprechend ausgeführt werden. Da das alles sehr hardwarenah ist, startet das Programm auch direkt nach dem Einschalten. Ein langes "Booten" etc. gibt es nicht wirklich.
Introduction to Arduino
https://www.youtube.com/watch?v=jRqLFn9rDJs
Ca. 8h Video mit Links zu Sketchbooks etc.
Ziemlich zäh
Everything You Need To
Know About Arduino
https://www.youtube.com/watch?v=E6KwXYmMiak
Tutorial Videos
http://makecourse.weebly.com/arduino-videos.html
Es gibt durchaus noch andere Entwicklungsumgebungen:
- Visual Studio
http://playground.arduino.cc/Code/VisualStudio - MariaMole
http://dalpix.com/mariamole - Gnoduino - Plug-in für Evolution IDE
http://gnome.eu.org/index.php/Gnoduino - LEARN ARDUINO
https://learn.adafruit.com/category/learn-arduino - Ardublockly
https://ardublockly.embeddedlog.com/demo/index.html
Programmieren mit ISP
Die meisten Arduino können über den seriellen Port programmiert werden. Teilweise ist dazu ein USB2Serial (TTL)-Adapter erforderlich oder der Arduino hat direkt schon einen USB-Anschluss mit serieller Funktion.
Achtung: Bei einigen neueren Modellen wie z.B. der Micro ist die USB-Anbindung teil des Chips und beim Reset nach dem Flash "verschwindet" kurz auch das USB-Device am Host. Das kann nerven aber die direkte Einbindung erlaubt auch, dass ein Arduino z.B. sich als Tastatur ausgibt.
In diesen Fällen können Sie immer noch einen ISP nutzen, und den Chip direkt programmieren. Einige missbrauchen dazu selbst einen anderen Arduino. Es gibt aber auch fertige Module. Die Nutzung eines ISP ist immer dann erforderlich, wenn der Mikrocontroller selbst noch gar keinen Bootcode hat, damit er sich per serieller Schnittstelle programmieren lässt. Zudem kann man über diese Seiteneingang mit dem AVR Studio auch den Code auf dem Chip debuggen. Es gibt mehrere Typen von Programmierern:
Kurzname | Beschreibung | Preise |
---|---|---|
AVRISP |
Dieser
Programmierer
kommt direkt von
Atmel, dem
Hersteller des
Prozessors und
ist damit am
leistungsfähigsten.
Er erlaubt z.B.
auch das
Debugging von
Code auf dem
Chip. Allerdings
ist er auch am
teuersten und
eher für professionelle
Entwickler und
Designer, die
auch mit dem AVR
Studio arbeiten.
Das Gehäuse ist
enthalten |
35€ |
USBTinyISP |
Eine
Alternative zum
AVRISP, die
Kompatibel zur
Atmel Software
aber günstiger
ist, wenn man
selbst baut |
20€ |
USBasp |
Die
billigste
Variante aber
mit
Einschränkungen.
Scheinbar gibt
es viele
Hersteller und
nicht jeder
installiert eine
aktuelle
Firmware. Dafür
ist das sehr
günstig |
ab 3€ |
Parallel |
Es gibt auch Programmierer, die über den parallelen Port des PCs angeschlossen werden. Da diese Schnittstelle aber immer mehr verschwindet, machen diese Programmier auch immer weniger Sinn. |
|
Ob der Programmierer nun 6 oder 10 Pins hat ist nicht relevant, da die 4 zusätzlichen Pins redundant oder nicht anschlossen sind. Hier eine Auswahl an weiteren Links
- AVR Programming Tool AT AVR
ISP2 mit USB
http://www.reichelt.de/?ARTICLE=45040 - Using an Arduino as an AVR
ISP (In-System Programmer)
http://arduino.cc/en/Tutorial/ArduinoISP - Segor Arduino ISP (ca 14€)
http://www.segor.de/#Q%3DArduinoISP%26M%3D1 - Arduino Downloader (2,99€)
http://www.bima-elektro.de/eshop.php?action=article_detail&s_supplier_aid=4127280 - ArduinoISP
https://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduinoisp - The Idiot's Guide to
Programming AVR's on the Cheap (with
the Arduino IDE!)
http://www.instructables.com/id/The-Idiots-Guide-to-Programming-AVRs-on-the-Chea/ - How to program Arduino by using USBasp without bootloader
http://tutorial.cytron.com.my/2011/09/30/how-to-program-arduino-by-using-avr-USBasp-programmer/
Gerade der uSPASP V2.0 scheint sehr günstig zu sein. Ist es doch auch nur ein kleiner Atmel mit eingebautem USB-Anschluss und einer kleinen Firmware zum Programmieren. Allerdings muss man für die ArduinoIDE drei Änderungen vornehmen, damit die IDE den Sketch direkt per ISP-Schnittstelle in den Arduino lädt:
- Editieren von C:\Documents
and Settings\”User”\Application
Data\Arduino\preferences.txt
Hier müssen Sie die Zeile "upload.using = bootloader" durch "upload.using = USBasp" ersetzen - C:\Program Files
(x86)\Arduino\hardware\arduino\programmers.txt
Hier müssen Sie eventuell die zwei Zeilen am Ende addieren, wenn Sie noch nicht enthalten sind:
USBasp.name=USBasp USBasp.protocol=USBasp
Eine Suche nach "ISP programmer" z.B. auf Ebay zeigt sehr viele weitere kostengünstige Alternativen. Stellen Sie aber sicher, dass diese nicht nur mit dem AVR Studio von Atmel, sondern auch mit der Arduino IDE funktionieren.
Alternative IDEs
Eine "dicke IDE" wie Visual Studio ist für Batchfile, PowerShell-Skripte etc. einfach zu schwerfällig. Der kleine Notepad aber reicht hinten und vorne nicht aus. Vor vielen Jahren bin ich Auf Notepad++ gestoßen, der mich seit dem begleitet. Die Arduino IDE ist relativ überschaubar in den Funktionen. Also war es nur eine Frage der Zeit, bis ich Notepad++ als Editor verwenden wollte. Das ist auch relativ einfach, da es entsprechende "Sprachdateien" für Notepad++ schon gibt und er auch den Compile/upload aufrufen kann.
Hier nur eine kleine Auswahl der Blogs, die ähnliches beschreiben.
- Visual Studio Code mit Platformio
Der Open Souce Editor von Microsoft ist schon an sich viel besser als Notepad oder auch der Arduino Editor. In Verbindung mit PlatformIO könen Sie sehr einfach für andere Microprozessoren entwickeln. Unbedingt naschauen!.
Atmel Studio
http://www.atmel.com/tools/atmelstudio.aspx
-
Tutorial: using Atmel Studio 6
with Arduino projects
http://www.engblaze.com/tutorial-using-atmel-studio-6-with-arduino-projects/ -
Atmel Studio mit Arduino
http://www.asensar.com/blog/programming-arduino-using-avrdude/
http://www.asensar.com/blog/how-to-integrate-avrdude-with-atmel-studio/
http://www.asensar.com/blog/how-to-setup-atmel-studio-for-arduino-development/ - http://playground.arduino.cc/Code/VisualStudio
- Notepad++ User Defined
Language für Arduino
http://forum.arduino.cc/index.php/topic,141050.0.html - Using Notepad++ Instead of
the Arduino IDE
http://sriramiyer.net/blog/2014/02/12/using-notepad-plus-plus-instead-of-the-arduino-ide/ - Editing Arduino code with
Notepad++
http://make.guerrillagis.net/?p=419 - Arduino für Visual Studio
2015
https://channel9.msdn.com/coding4fun/blog/Arduino-for-Visual-Studio-2015-Beta
- PlatformIO - alternative IDE
für Arduino und Co
http://platformio.org/
Die Arduino IDE enthält auch ein "Terminal Fenster", welches mit CTRL-SHIFT-M erreichbar ist. Nach meinen Beobachtungen initiiert dieses Fenster aber einen "RESET" des Arduino. So kann man schön den Startup beobachten aber das ist natürlich stören, wenn der Arduino schon einige Zeit läuft und sie sich erst dann aufschalten wollen.
Die Funktion "setup()"
Diese Funktion wird einmal beim Start des Code ausgeführt und könnte wie folgt aussehen
void setup() { // Dieser Code wird beim Einschalten oder Start einmalig ausgefuerht. // ideal für die Initialisierung von Variablen und Vorarbeiten // Normal wird der serielle Port initialisiert für spätere Ausgaben. Serial.begin(9600); while (!Serial) { ; // wait für serial port to connect. Needed für Leonardo only } Serial.println("Setup gestartet"); }
Sie ist auch ein idealer Platz Variablen initial zu belegen. Die Funktion kann natürlich andere unterfunktionen aufrufen, die durchaus auch im Code weiter hinten stehen können. So bleibt die Übersichtlichkeit gewahrt.
Die Funktion "loop()"
Nachdem das "setup()" durch ist führt der Arduino-Loader diese Funktion immer wieder aus. Ich muss also nicht extra eine "while true {}"-Schleife" bauen. Hier passiert sequentiell die Magie.
void loop() { // Diese Funktion wird nach dem Setup immer wieder wiederholt. Serial.println("Loop gestartet"); delay(1000) }
Dieses Beispiel enthält nun natürlich keinen wirklichen Sinn. Zudem kann der Arduino die Daten schneller ausgeben als der serielle Port die Daten überträgt. Insofern muss man beim Debugging auch wieder sich beschränken oder den Code absichtlich "verlangsamen".
Schlafen und Interrupts
Nun kann es durchaus sein, dass ein Code nicht andauern "pollen" soll. Das kostet einfach Energie. Wenn der Arduino eh mit mehr Spannung betrieben wird und der Spannungsregler auf dem Board darauf 5Volt macht, dann ist das Einsparpotential gering, da der Spannungsregler schon 10mA "verheizt". Wer dann noch eine LED als Signal angeschlossen hat, wird noch ein paar mA mehr verbrauchen. Interessant ist dies also, wenn der Arduino z.B. über Batterien betrieben wird.
Wenn ein Arduino einmal "schlafen" gelegt wurde, dann kann ihn nur ein Interrupt oder ein Reset wieder erwecken. Sie müssen also "Vorarbeiten", das einer der beiden Eingänge 2 oder 3 immer dann ein Signal sendet, wenn es etwas zu tun gibt und sie müssen eine Funktion einbauen, die dann aufgerufen wird. Die Funktion eines Interrupt ist aber auch hilfreich, wenn Sie auf Vorgänge reagieren wollen, z.B. StatusÄnderungen einer Leitung. Wichtig ist nur zu wissen, dass nicht alle Eingänge auch einen "Interrupt" auslösen. Die Leitung 2 ist aber meist auch mit dem seriellen Port verbunden, so dass ein eingehendes Zeichen einen Interrupt auslöst. So können Sie den Arduino auch vom PC aus ansteuern-
- Sleep - How to let your
Arduino go to sleep and wake up
on an external Event.
http://playground.arduino.cc/Learning/ArduinoSleepCode - attachInterrupt()
http://arduino.cc/en/Reference/AttachInterrupt
Auf einigen Arduino gibt es sogar noch weitere vorgefertigte Funktionen die in der Basis oder über Libraries verfügbar werden. Der ATMega 328 hat eine ganze Liste:
Interrupt | Bezeichnung | Auslöser |
---|---|---|
1 |
Reset |
kein |
2 |
External Interrupt Request 0 (pin D2) |
INT0_vect |
3 |
External Interrupt Request 1 (pin D3) |
INT1_vect |
4 |
Pin Change Interrupt Request 0 (pins D8 to D13) |
PCINT0_vect |
5 |
Pin Change Interrupt Request 1 (pins A0 to A5) |
PCINT1_vect |
6 |
Pin Change Interrupt Request 2 (pins D0 to D7) |
PCINT2_vect |
7 |
Watchdog Time-out Interrupt |
WDT_vect |
8 |
Timer/Counter2 Compare Match A |
TIMER2_COMPA_vect |
9 |
Timer/Counter2 Compare Match B |
TIMER2_COMPB_vect |
10 |
Timer/Counter2 Overflow |
TIMER2_OVF_vect |
11 |
Timer/Counter1 Capture Event |
TIMER1_CAPT_vect |
12 |
Timer/Counter1 Compare Match A |
TIMER1_COMPA_vect |
13 |
Timer/Counter1 Compare Match B |
TIMER1_COMPB_vect |
14 |
Timer/Counter1 Overflow |
TIMER1_OVF_vect |
15 |
Timer/Counter0 Compare Match A |
TIMER0_COMPA_vect |
16 |
Timer/Counter0 Compare Match B |
TIMER0_COMPB_vect |
17 |
Timer/Counter0 Overflow |
TIMER0_OVF_vect |
18 |
SPI Serial Transfer Complete |
SPI_STC_vect |
19 |
USART Rx Complete |
USART_RX_vect |
20 |
USART, Data Register Empty |
USART_uDRE_vect |
21 |
USART, Tx Complete |
USART_TX_vect |
22 |
ADC Conversion Complete |
ADC_vect |
23 |
EEPROM Ready |
EE_READY_vect |
24 |
Analog Comparator |
ANALOG_COMP_vect |
25 |
2-wire Serial Interface (I2C) |
TWI_vect |
26 |
Store Program Memory Ready |
SPM_READY_vect |
Davon ist aber nur eine Teilmenge für den normalen. Arduino Entwickler sinnvoll zu nutzen. Sehr viele werden nämlich schon innerhalb der entsprechenden Klassen verwendet, so dass man sich eigentlich nur im die Pins 2 und 3 kümmert. Und selbst dann muss man immer beachten. dass nur eine Interrupt Service Routine laufen kann und in der Zeit weitere Interrupts blockiert sind.
- serialEvent(){ //statements
}
http://arduino.cc/en/Reference/SerialEvent
Wird aufgerufen, wenn auf dem seriellen Port etwas ansteht. (nicht auf Esplora, Leonardo, or Micro)
Allerdings nur, wenn das Programm nicht durch ein "DELAY" blockiert ist. Der Event wird immer am Ende von "Loop" aufgerufen. - keypadEvent(KeypadEvent eKey)
{
http://playground.arduino.cc/KeypadTutorial/EventSerialKeypad
reagiert auf Tastatureingaben. - SimpleTimer Library
http://playground.arduino.cc/Code/SimpleTimer - Nick Gammon: Interrupts
http://gammon.com.au/interrupts
Sehr gute Beschreibung und unbedingt lesenswert - Pause muss auch mal sein -
Beispiele zum nichtblockierenden
Programmablauf
https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/pause-muss-auch-mal-sein-beispiele-zum-nichtblockierenden-programmablauf
Wenn eine Routine also auf etwas "länger warten" muss, aber andere Codeteile weiter arbeiten sollen, dann sollten Sie einfach ihren Code überspringen und bei jedem Durchlauf erkennen, ob sie schon was tun können.
Performance, Timing und Multitasking
Auch wenn ein Arduino mit ein paar Megahertz arbeitet, so fühlt man sich schon wieder etwas in die alte 8Bit Welt (6502/Z80) versetzt, bei der man noch zu jedem Assembler-Befehl wusste, wie viele CPU-Takte dieser benötigte und wenn ein Programm zu "schnell" war, hat man eben ein paar Schleifen mit einem "NOOP" (No Operation) addiert und so die Verzögerungen in Takten festgelegt. Beim Arduino geht das mit dem "DELAY" einfacher, da er den Prozessor einfach die angegebene Zeit in Millisekunden anhält. Allerdings ist das dann auch eine richtiges "HALT", denn ein Multitaskting kennt der Arduino nicht.
- delay()
http://arduino.cc/en/Reference/delay - delayMicroseconds()
http://arduino.cc/en/Reference/DelayMicroseconds
Wer also etwas verzögern will, aber dennoch quasi "parallel" noch andere Dinge verarbeiten will, sollte das Programm nicht über "DELAY" anhalten, sondern über die Funktion "Millis" besser prüfen, ob die Wartezeit schon vorbei ist und ansonsten den Codeteil einfach überspringen.
- millis()
http://arduino.cc/en/Reference/Millis - micros()
http://arduino.cc/de/Reference/Micros - Blink Without Delay
http://arduino.cc/en/Tutorial/BlinkWithoutDelay -
Bigger and Better Projects
https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview
So bekommt man zwar kein "Multitasking" hin, aber wenn die verschiedenen Bestandteile eines Codes untereinander stehen und keiner der Teile den Code "blockt" sondern einfach rausspringt und später wieder aufgenommen wird, dann kann man was ähnlich erreichen. Alternativ können Sie natürlich immer noch auf Interrupts reagieren, sofern das Programm nicht mit einem "Delay" zum Schlafen gesendet wurde.
Eine Abfrage wie "Serial.available()" blockt übrigens nicht den Prozess. Aber auch ein "Serial.read()" liefert nur ein "-1", wenn kein Zeichen ansteht aber blockiert nicht durch ein Warten auf eine Eingabe.
Performance Messwerte
Interessant ist natürlich schon, wie "schnell" bestimmte Aktionen erfolgen, Ich habe mir daher ein paar kleine Beispielcodes gebaut, die ganz trivial bestimmte Aktionen oft genug durchführen und am Ende die Zeit in "Millis()" müssen. Per Default puffert der Arduino bis zu 64 Zeichen auf dem seriellen Port.
Als Testsystem diente ein "Arduino Ethernet Rev 2" (http://arduino.cc/en/Main/ArduinoBoardEthernet)mit ATmega328
Messung | Ergebnis | Code |
---|---|---|
DigitalReadIch habe einen digitalen Port einfach 100.000 mal abgefragt ohne weitere Verarbeitung. Das dauert weniger als eine halbe Sekunde, d.h. 466ms/100.000 = 4,66 Mikrosekunden. Die Zahl ist natürlich nicht repräsentativ. Ohne Berechnung könnte man also 214592 "digitale Zustände " pro Sekunde ermitteln. liest man in jedem Durchlauf 4 Ports ein, dann dauert dies mit 1720ms etwas weniger als 4mal so lang. |
466ms |
|
Einfluss Serial OutputIch habe dann absichtlich "viele Zeichen" ausgegeben. Sofern man also mit dem Arduino und den COM-Port mit dem PC kommunizieren will, kann dies ein Engpass werden. Die Ausgabe von 10 Zeichen kostet ca. 1ms aber danach 8ms und dann weiter 22ms. (Die Ausgabe enthält auch noch die Strings ! Es scheint als wenn der Puffer von ca. 64 Zeichen voll ist und noch nicht ausgelesen wurde, dann wird das Programm verzögert. Das ist beim Datenaustausch über die "Serial"-Schnittstelle zu beachten. |
|
|
Liste wird fortgesetzt |
|
|
Das sind natürlich sehr optimistischer Werte. Einfache mathematische Funktionen und Schleifen sind gar nicht mal das Problem, aber z.B. Serielle eingaben und Ausgaben, die "blockieren" können die Reaktionszeit deutlich verlängern.
Serial Input / Output
Kommen wir gleich zu der primären Schnittstelle, mit der eine Software mit dem Entwickler kommunizieren kann. Es ist sehr einfach mit Serial.print und Serial.PrintLn ausgaben auf die Console zu schreiben und mit Serial.ReadString auch wieder Eingaben anzunehmen. Aber zuerst müssen Sie natürlich den seriellen Port initialisieren. Ich mache das immer am Anfang der SETuP-Funktion.
void setup() { Serial.begin(9600); // INIT Serial Port while (!Serial) {blinkled(300);} // wait für serial port to connect. Needed für Leonardo only Serial.println("----- Sketch SETuP Start -----");
Bei neueren Boards mit dem ATmega32u4 sollten Sie auf den Port "warten", da er per USB bereit gestellt wird und nach dem Reset der PC vielleicht etwas braucht. Die Funktion "blinkled" ist weiter unten beschrieben. Beim Einlesen gibt es nun einige Optionen:
String command = Serial.readString(); // Liest alle Zeichen ein bis zum Timeout (100ms) String command = Serial.readStringuntil('\n'); // List alle Zeichen ein bis zum Timeout oder dem angegebenes Zeichen char inputchar = Serial.read(); // Liest genau ein Zeichen ein String command= String(inputchar); // convert char to string
Auch wenn "ReadString" sehr einfach ist, so wird das ausgeführte Programm bis zu 1 Sek "angehalten". Wenn das Skript dann natürlich kurze Impulse (z. B. S0 = 30ms) zählen soll, dann führt so eine Ausgabe zu Verzögerungen.
- readString()
http://arduino.cc/en/Reference/StreamReadString - readStringuntil()
http://arduino.cc/en/Reference/StreamReadStringuntil
Dann sollten Sie besser mit Serial.Available() die Anzahl er im 64 Byte langen Buffer stehenden Bytes ermitteln und manuell einlesen und entsprechend parsen., auch wenn das etwas umständlicher ist. Es ist keine gute Idee, den Timeout sehr klein zu stellen, da er dann auf alle von der "Stream"-Klasse abgeleitete Routinen angewendet wird, z.B. auch Wire, EthernetServer, EthernetClient, SD-Card etc.
- setTimeout()
http://arduino.cc/en/Reference/StreamSetTimeout - Stream
http://arduino.cc/en/Reference/Stream
Eine einfache Version, die ein einzelnes Zeichen einliest. habe ich hier veröffentlicht. Ich konvertiere das Zeichen aber zu einem String, damit ich die Groß/Kleinschrift nicht selbst behandeln muss und vielleicht brauche ich die Funktion ja noch mal um mehr Zeichen zu lesen.
(Serial.available()>0) { char inputchar = Serial.read(); String command= String(inputchar); // convert char to string if (command.equalsIgnoreCase("0")) { debuglevel = 0; Serial.println("Debuglegel = 0"); }
Wenn Sie direkt mit dem "Char" weiter arbeiten wollen, dann denken Sie beim Vergleichen mit "if" daran, dass die Anführungszeichen entscheidend sind. Einen "Char" sollten sie mit einem Buchstaben in einfachen Anführungszeichen vergleichen.
Hinweis:
Wenn mehr Zeichen empfangen werden, als der
Buffer speichern kann, dann werden alle
überzähligen Zeichen verworfen. Der Ringbuffer
wird also nicht überschrieben.
if (inputchar == 'a') {... // kann ausgeführt werden if (inputchar == "a") {... // wird nie ausgeführt da ein Char <> String
Auch bezüglich der Ausgabe sollten Sie immer beachten, dass der Ausgabepuffer 64 Zeichen umfasst und das Skript ausgebremst wird, wenn der Buffer voll ist und die Bytes langsam versendet werden. Seit Arduino 1.0 arbeitet zwar Serial.Print asynchron, d.h. kommt auch wieder zurück, ehe die Bytes versendet werde, aber eben nur, solange der Buffer die auszugebenden Bytes auch vorhalten kann.
- Serial
http://arduino.cc/en/Reference/Serial
Serial.write() http://arduino.cc/en/Serial/Write
Serial.print() http://arduino.cc/en/Serial/Print
Serial.Println() http://arduino.cc/en/Serial/Println - Reading from Serial on the
Arduino
http://hacking.majenko.co.uk/reading-serial-on-the-arduino - How to increase Serial
buffer size in arduino
https://www.youtube.com/watch?v=Aqc1SAtIJeu
Angeblich soll man in C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp die Buffersize anpassen können
Nachdem ich die 64 z.B. auf 164 gestellt habe, konnte mein Demo-Programm durchaus noch Schritt halten. Ich würde mich aber nicht weiter drauf verlassen. Zeitkritische Dinge sollten per Interrupt erledigt werden und dazu gibt es nur ein paar Anschlüsse je Board. (Siehe auch http://arduino.cc/en/Reference/AttachInterrupt)
Wer demnach Mehr als 64 Bytes/Zeichen innerhalb der maximalen Zeit senden will, muss mit einer Verzögerung des Programms rechnen oder Vorkehrungen treffen, z.B. indem man selbst einen Buffer mitführt und bei jedem Durchlauf prüft, ob man nicht "zu schnell" ist, denn ansonsten wartet das Programm.
// If the output buffer is full, there's nothing für it other than to
// wait für the interrupt handler to empty it a
bit
Quelle: HardwareSerial.cpp Zeile 464 Stand: 14
August 2012
Leider enthält der Code keine Funktion um zu ermitteln, wie voll die Sendequeue ist.
Tipp: In vielen Beispielen wird der serielle Port mit 9600 Baud initialisiert. Natürlich können auch höhere Datenraten (z.B. 115200) genutzt werden. Sie müssen dann aber auch ihre Auslesesoftware auf dem PC entsprechend anpassen.
param ( [string]$comport = "COM4", [long]$bitrate = "9600", # default baud rate ) $port= new-Object System.IO.Ports.SerialPort $comport,$bitrate,None,8,one $port.ReadTimeout=5000 $port.WriteTimeout=5000 write-host "Open Port $comport" $port.open() #write-host "Send Command" #$port.WriteLine('P') #write-host "Delay 1 Sec" #start-sleep -milliseconds 1000 write-host "Start Reading output" write-host $port.readline() $port.Close()
Schön dabei ist, dass Windows das komplette "Puffern" übernimmt.
- Writing and Reading info
from Serial Port
http://blogs.msdn.com/b/PowerShell/archive/2006/08/31/writing-and-reading-info-from-serial-ports.aspx - Serial Call and Response (handshaking)
with ASCII-encoded output
http://arduino.cc/en/Tutorial/SerialCallResponseASCII
Debugging, LED, LCD
Ich habe schon ein paar Zeilen vorher gesagt, dass es mit dem "Debugging" nicht so einfach ist. Ausgaben aus SERIAL kann ich nur am PC lesen, die Arduino-IDE erlaubt kein integriertes Debugging. Insofern wäre es doch hilfreich eine weitere Ausgabe zu haben. Natürlich könne man einen der viele l/O-Ports mit einem Vorwiderstand und LED bestücken und z.B. "Blinksignale" geben. Ich habe mir dazu mehrere Bausteine bereit gelegt:
Sie werden gleich sehen, das ich kein "Vollblut Programmierer" bin. andere würden diese Code-Schnipsel sicher in einer Library oder Class verstecken oder eine bestehende Library nutzen.
- SerialDebugger Library für Arduino
http://playground.arduino.cc/Code/SerialDebugger - Logging library für Arudino
http://playground.arduino.cc/Code/Logging
Der erste ist eine "DEBUG"-Ausgabe, die zwar auf die serielle Schnittstelle schreibt, aber einen "Level" respektiert.
// Global variable für debug output settings int debuglevel = 0; void loop () { debug(3,true,"Debug Level 3); } void debug(int level, boolean newline, String message) { if (level <= debuglevel ) { if (newline) { Serial.println(message); } else { Serial.print(message); } } }
So kann ich überall im Code meine "debug"-Ausgaben addieren und über die globale Variable vorgeben, wie detailliert ich das haben will..
Der zweite Block ist ein "Lebenszeichen". Nahezu jeder Arduino hat eine LED aufgelötet, die an Pin 9 oder 13 angeschlossen ist und per Software geschaltet wird. Wenn dieser Port für nichts anderes verwendet wird, dann habe ich mir angewöhnt hier per "Blinken" zu zeigen, dass das Programm noch läuft. Ich brauche dazu natürlich ein paar globale Variablen. Denn der Code sollte immer mal wieder aufgerufen werden, z.B. am Anfang der Loop-Funktion. Der Code selbst ist aber "non blocking", d.h. die LED wird im angegebenen Takt ein uns ausgeschaltet, aber der Code" wartet" nicht sondern prüft, ob die Wartezeit schon vorbei ist.
// Global variabled für blinking status led const int statusledport= 9; // Arduino Ethernet. status LED to show flashing status normally 13 boolean statusledstate = true; unsigned long statusledmillis = 0; void loop() { blinkled(1000); // Call BlinkingLED to indicate, that everything is fine } void blinkled(long blinkms) { // Flash Heartbeat LED if ((millis() - statusledmillis) > blinkms) { // Wait für elapsed time blink statusledmillis = millis(); if (!statusledstate) { debug(3,true,"HeartbeatLED:HIGH"); digitalWrite(statusledport, HIGH); statusledstate=1; } else { debug(3,true,"HeartbeatLED:LOW"); digitalWrite(statusledport, LOW); statusledstate=0; } } }
Bei Gelegenheit wollte ich diese Funktion vielleicht noch um eine Art "Morsezeichen" abwandeln. Aber gerade am Anfang habe ich im Code auch immer die Anforderung ein "richtiges Problem" zu melden und den Code anzuhalten. Dazu habe ich mir eine "finalerrorstatus"-Funktion gebaut, die den Fehler auf den serial-Post ausgibt aber parallel die LED eine anzugebende Anzahl von Impulsen blinken lässt und nach einer Pause widerholt.
void finalerrorstatus (int errorcount, String message) { debug(0,true," Raeaching a finalerrorstatus!"); while(true){ // no point in carrying on, so do nothing forevermore: für (int ledcount = 1; ledcount <= errorcount; ledcount++) { digitalWrite(statusledport, HIGH); // turn the LED on delay(500); digitalWrite(statusledport, LOW); // turn the LED off delay(500); } delay(4000); debug(0,false,"Final Error Status"); debug(0,false,message); debug(0,false,"Error:"); debug(0,false,String(errorcount,DEC)); } }
Diese Funktion ist natürlich im Gegensatz zur "blinkled"-Funktion blockierend. Das ist aber auch so gewollt.
Alles viel schöner geht das natürlich, wenn der Arduino auch eine Ausgabe "schreiben" kann, die nicht den COM-Port belegt. Leider hat der Arduino im Gegensatz zum RaspberryPI keinen Video oder HDMI-Ausgang und daher bleibt nur der Weg, ein LCD an die Ports anzuschließen. Das ist nicht schwer und auch nicht teuer aber je nach Anbindung kostet es viele, weniger oder ganz wenige Ports. Und da man mit Ports für eigene Ansteuerungen eher sparsam umgeht, würde ich ein Display mit I2C, TwoWire-Interface (TWI) vorziehen und nicht die kostenbaren Digitalports dazu verwenden. mit I2C kommt man mit zwei Leitungen hin und kann sogar noch andere Geräte an den gleichen Bus anschließen.
Ich habe noch kein LCD-Modul angeschlossen. Ich plane ein 2x16 oder 4x20 Zeichen Module über TWI/I2C anzuschließen, um damit Ausgaben zu ermöglichen.
- LCD Displays
http://playground.arduino.cc/Code/LCD - LiquidCrystal - "Hello
World!"
http://arduino.cc/en/Tutorial/LiquidCrystal
Basierend auf de Modul HD44780 belegt diese Lösung leider 6 kostbare PINs - Leistungsfähigere
LCD-Library
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
Inkl. Angaben zur Performance, was beim Ausgeben durchaus relevant sein kann. - Arduino and TM1638 LED
Display Modules
http://tronixstuff.com/2012/03/11/arduino-and-tm1638-led-display-modules/
https://code.google.com/p/tm1638-library/downloads/list - Arduino and the i2c Bus
http://tronixstuff.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
Ethernet und LAN
Es ist erstaunlich, wie einfach so ein kleiner Minirechner auch im Ethernet mitspielen darf. Mit dem "Arduino Ethernet" gibt es gleich ein Board, auf dem ein Ethernet-Anschluss gleich drauf ist. Aber auch die anderen Boards lassen sich recht schnell mit Ethernet nachrüsten. Entsprechende Module gibt es über ebay aus China für unter 5 Euro.
- Arduino Ethernet
- Arduino Ethernet und S0
- Mein Paket… …ein ENC28J60
Ethernet LAN Netzwerk Modul
http://arduino-hannover.de/2013/12/08/mein-paket-ein-enc28j60-ethernet-lan-netzwerk-modul/
Allen gemeinsam ist, dass vier PINs des Arduino benötigt werden und damit nicht mehr für andere Zwecke verwendet werden können. Die verwendeten Pins hängen von der verwendeten Library und dem Modul ab.
Library | |||
---|---|---|---|
Pin-Funktion | EtherCard | uIPEthernet | ETHER_28J60 |
Chip Select (SE) | 10 |
10 |
8 |
Daten vom Ethernet empfangen (MISO) | 11 |
11 |
11 |
Daten zum Ethernet senden (MOSI) | 12 |
12 |
12 |
CLK | 13 |
13 |
13 |
Das liegt auch daran, dass es nicht nur genau ein Ethernet Shield gibt, sondern verschiedene Chips per SPI angebunden werden können, unterschiedliche Hersteller eigene Erweiterungen für die offene Arduino-Plattform entwickelt haben und damit unterschiedliche Libraries für den Einsatz notwendig sind. Hier ein Bild eines sehr günstigen Shields basierend auf dem 28J60-Chip mit aufgestecktem Arduino Nano
Die meisten Adapter unterstützen nur 10/100 MBit und ich kenne keinen mit dem man per PoE den Arduino versorgen könnte. Wäre PoE noch nett, so ist Gigabit komplett überflüssig. Zudem erfolgt die Übertragung "seriell" und das hat direkt Auswirkungen auf die erreichbare Performance. Hinzu kommt, dass z.B. das W5100 nur bis zu 4 Ports direkt selbst in seiner IPv4-Engine verwalten kann. Muss man mehr Ports bedienen, muss man per MACRAW direkt alles selbst umsetzen. Zudem ist das SPI Interface nur für 4MHz spezifiziert und erlaubt nur "Single Byte"-Transfers. Erst das W5200 Modul hebt diese Grenzen leicht an.
Viel mehr als 100kByte/Sek wird ein Arduino kaum senden können und das nur, wenn er nicht noch was anderes macht. Auch beim Empfang sollten Sie keine Wunder erwarten. Auf der anderen Seite gibt es aber auch nicht viele Daten, die ein kleiner Arduino mit 16MHz Taktfrequenz, 16kb Programmspeicher und 2k RAM senden oder empfangen kann.
- Arduino und S0
- Arduino Ethernet Shield
http://arduino.cc/en/pmwiki.php?n=Main/ArduinoEthernetShield - W5100 Ethernet Shield
http://wiki.iteadstudio.com/W5100_Ethernet_Shield - Wiznet W5200 Arduino Shield
by Elecrow
http://feilipu.me/2013/08/03/wiznet-w5200-arduino-shield/ - Arduino and ENC28J60
Ethernet Controller
http://www.tweaking4all.com/hardware/arduino/arduino-enc28j60-ethernet/ - Cactus Micro Rev2 Esp8266
Module ESP-03
http://www.seeedstudio.com/depot/Cactus-Micro-Rev2-Arduino-compatible-plus-esp8266-p-2544.html
Arduino mit ESP8266 WiFi Controller (ca. 11 US-$)
Arduino und WiFi
Mittlerweile gibt es von Adafruit auch ein Shield, welches auf dem Texas Instruments CC3000 basiert und per SPI an die verschiedenen Arduino-Systeme angebunden werden kann. Damit kann ein Arduino oder anderes Device mit SPI-Schnittstelle relativ einfach in ein WIFI-Netzwerk angebunden werden. Das ist insbesondere interessant, wenn am Einsatzort kein LAN zur Verfügung steht oder der Arduino mobil ist.
Wenn Sie mit dem Arduino Ökosystem arbeiten wollen aber WLAN und vielleicht Bluetooth gefordert ist, dann sollten Sie unbedingt die ESP8266 und ESP32 Serie lesen.
Es gibt z.B. von Adafruit ein Modul, welches über SPI sich anmelden und für unter 40 US-$ erhältlich ist.
- Adafruit CC3000 WiFi
Breakout with Onboard Ceramic
Antenna
http://www.adafruit.com/products/1469 - GitHub:
Adafruit_CC3000_Library
https://GitHub.com/adafruit/Adafruit_CC3000_Library - CC3000 (ACTIVE) SimpleLink™
Wi-Fi Module from Texas
Instruments
http://www.ti.com/product/cc3000
Es geht aber noch billiger, da es mittlerweile WiFi -Boards gibt, die seriell angeschlossen werden, z.B. auf Basis des "ESP8266". Allein über 4 Kabel (GND, +3,3V, RxD und TxD) wird das Modul programmiert und die Daten übertragen. Da kann man natürlich keine "HighSpeed"-Übertragung erwarten aber es reicht, um kleine Heartbeat-Signale oder z.B. Infos per UDP ins LAN zu schreiben. Es kann aber auch eine TCP-Verbindung als Client oder Server aufgebaut werden.
- First Impression on the
ESP8266 Serial-to-WiFi Module
http://rayshobby.net/first-impression-on-the-esp8266-serial-to-wifi-module/ - Erste Versuche mit dem
ESP8266-WLAN-Seriell-Funkmodul
http://thomaspfeifer.net/esp8266_wlan_seriell_modul_at_kommandos.htm - ESP8266 with Arduino
http://www.electrodragon.com/w/ESP8266_with_Arduino -
http://www.electrodragon.com/w/ESP8266_Firmware
http://www.electrodragon.com/w/Wi07c#V0.922
Mittlerweile gibt es aber sogar schon Arduino Nano Clones mit direkt angelötetem ESP8266, die von Conrad, Franzis etc. für 25-35€ vertrieben werden: Die serielle Verbindung des ESP8266 wird dabei auf die Datenpins D11/D12 gelegt und mit der SerialIO-Library angesteuert.
- Internet of Things mit dem NanoESP
http://iot.fkainka.de/ - WiFi Board: NanoESP bzw. Pretzel-Board
http://www.mikrocontroller-elektronik.de/wifi-board-nanoesp-bzw-pretzel-board/ - C-Control IoT WIFI Board 5 V (25€)
https://www.conrad.de/de/c-control-iot-wifi-board-5-v-1387029.html - Franzis Pretzel Board (30€)
http://www.franzis.de/elektronik/arduino-platinen/pretzel-board - PRETZELBOARD AKA NANOESP AKA C-CONTROL
DUINO
http://duinorasp.hansotten.com/pretzelboard-aka-nanoesp-aka-c-control-duino/ - Ping Watch mit dem NanoESP
http://fkainka.de/ping-watch/
Fehler, die mir selbst auch schon unterlaufen sind
Während meiner eigenen Arduino Programmierübungen bin ich natürlich auch in die ein oder andere Falle getappt:
- Zu viele Ausgaben per "Serial.print"
9600 Baud sind ca. 100 Zeichen/Sek, und das ist nicht viel, wenn man zum "Debugging" an jede Stelle eine Diagnoseausgabe setzt. Das verändert schon die Laufzeit. Das können Sie am unten vorgestellten S0-Zähler sogar "sehen", dass bei der Ausgabe das "Blinken" der LED quasi "angehalten" wird. Er also viele Daten auszugeben hat, sollte diese entweder "kompakt" speichern oder nicht auf einmal sondern in mehreren Schüben ausgeben. - Eingaben mit
"Serial.ReadString"
Wenn der String am Ende abgeschlossen ist, dann wartet das Skript auf das Ende. Wer nun zwei Zeichen mit 9600Baud sendet, braucht min 10ms pro Zeichen. Sobald das erste Zeichen anliegt, wartet das Skript auf mehr bis zu einem Timeout (1Sek ?) Besser ist es mit Serial.read zeichenweise abzuholen und das Skript weiter laufen zu lassen. - Grenzen von Variablen
beachten
Wenn man eine Variable als "INT" (integer) definiert, dann sollte man sowas nicht machen:
Diese Schleife kommt nie zurück da bei 32768 ein Rollover erfolgt und die 100.000 nie erreicht wird. - LowerCase und UpperCase
C++ ist "Case Sensibel", d.h. Befehle aber auch Variablen und Konstanten müssen genau eingegeben werden. Ein Stück weit unterstützt die IDE die Eingabe von vordefinierten Konstanten durch eine farbliche Kennzeichnung. Dennoch passiert es auch mir immer wieder, mich zu "vertippen". Schön wenn der Compiler sich dann beschwert. Unglücklich, wenn man zwei Variablen verwendet, die unterschiedlich geschrieben sind. - CHAR und String im Vergleich
Es ist ein unterschied, ob man "a" oder 'a' schreibt. In der PowerShell ist es fast gleich, nur dass bei einer auch Variablen ersetzt werden. Beim Arduino aber ist das doppelte Anführungszeichen ein "string" während der einfache Anführungsstrich ein "CHAR" ist. Das ist bei Vergleichen genau zu prüfen. - CTRL-SHIFT-M = SerialMonitor
Wenn man in der Arduino IDE den seriellen Monitor startet, dann zeigt er nicht nur an, was ab dem Moment dann ausgegeben wird, sondern bei mir hat er auch einen Reset zum Arduino gesendet, so dass das Programm wieder vom Anfang an losgelaufen ist.
Die Liste wird fortgesetzt.
Praktisches Beispiel
Auf der Seite Arduino und S0 habe ich ein Beispiel, wie der Arduino Ethernet eine S0-Schnittstelle liest und diese Daten per HTTP erreichbar macht. Auf der Seite Arduino Ethernet Probe habe ich weitere Beispiele für den Arduino mit Ethernet beschrieben. Ich hatte auch mal vor die UCWA-Schnittstelle von Lync mit einem Arduino direkt abzufragen aber das ist natürlich durch die Pflege von Zugangsdaten und Kennworten als "Code" nicht sehr einfach.
Auf dieser Seite beschränke ich mich wieder mit dem Aufbau eines S0-Zählers, der einfach nur die vielen Eingänge des Arduino abliest, aufaddiert und über den COM-Port bereit stellt. Da aber nur der Port 2 und 3 einen Interrupt auslösen und ich mir eine Zusatzschaltung über ODER-Gatter ersparen wollte, lese ich die Werte im "Polling" aus. Schnell genug ist der Arduino ja und durch den USB-Anschluss am PC zur Stromversorgung und Datenübergabe kommt es nicht auf das letzte mW an. Das Flussidagramm ist also überschaubar:
Das SETuP-Routine initialisiert den seriellen Port für die Datenausgabe, die Debug-Ausgabe, und Variablen. Die Loop-Routine liest dann einfach immer die Eingänge nacheinander ab und sucht an einer "Veränderung". Auf der Seite Arduino und S0 habe ich mehr Details über S0-Bus lesen und "Entprellung" per Software geschrieben. Die Zustände müssen 30ms anhalten, also wenn ich alle 10ms die Daten ablesen und zwei Messung "gleich" sind, dann habe ich einen stabilen Pegel und kann dies als "Wert" ansehen. Da der Arduino aber deutlich schneller ist, muss ich sogar die Messung verzögern. Um dabei aber nicht das gesamte Programm aufzuhalten, prüfe ich das über die "millis()" abfrage und vergleich ob die erforderliche Zeit schon verstrichen ist. In einen "Stromsparmode" fällte der Arduino damit natürlich nicht.
Aber damit kann ich in einem zweiten Schritt natürlich prüfen, ob eine Anfrage über den seriellen Port eingegangen ist, auf die ich antworten muss. Hier habe ich mir den Spaß erlaubt, gleich mehrere Funktionen anhand der Steuerung exemplarisch abzubilden. Um die Abfrage aber "einfach" zu halten, habe ich mich auf ein Zeichen beschränkt um nicht noch auf CR oder LF achten zu müssen.
- 0-0-5 = Ich kann damit über den COM-Port den "Debuglevel" entsprechend setzen.
- P = Ausgabe der Zählerstände gleich im "PRTG-Format"
- L = Ausgabe als "Liste
- S = Kurze (Short) Liste mit allen Werten in einer Zeile durch ";" getrennt um Verzögerungen durch die Ausgabe zu minimieren
- Alles andere
Eine kleine "Online Hilfe" mit den verfügbaren Programmen.
Hier erst mal der Code als Muster
Gerade bei der Auswertung der Rückgabe ist immer abzuwägen, ob die Ausgabe von vom Code auf dem Arduino für das Zielsystem aufbereitet wird oder ob eine Zwischenskript die komprimierten Daten für das Ziel umsetzt, was deutlich Flexibler bei Änderungen des Ziels ist.
mögliche Erweiterungen
- Zählerspeicherung
Der Arduino Ethernet hat einen 2KByte SRAM-Speicher, in dem man natürlich z.B.: die Zählerstände hinterlegen könnte. Das hätte aber den Nachteil, dass nach einer Spannungsunterbrechung nicht erkannt würde, dass die Zähler gestanden haben. So fangen die Zähler wieder bei "0" an und ein Monitoring kann dies erkennen - Zählerstandsreihe
Interessanter wäre hier schon die Funktion, die Messreihe zu speichern und so auch zu überbrücken, wenn der Host die Daten nicht zeitnah abholt. Den Zählerstand alle Minute in einer Variablen zu halten und dem Host dann die letzten 60 Minuten zu liefern könnte kurze Unterbrechungen des Hosts neutralisieren. - Min/Max-Erkennung anhand des
Abstands
Wenn man nur Impulse zählt und der Host regelmäßig die Daten abfragt, dann bekommt man auch nur Mittelwerte aber keine Spitzenwerte oder Minimalwerte. für den Arduino ist es ein einfaches nicht nur die Impulse sondern auch die Abstände dazwischen im Millisekunden/Mikrosekunden (micros()) zu müssen und damit auch Lastspitzen zu erfassen.
Arduino und Lync?
Der Arduino kann per Ethernet angesteuert werden aber interessant ist auch die Funktion des "Arduino Ethernet", welcher über IP und HTTP kommunizieren kann. Damit könnten sich natürlich neue Optionen anbieten, z.B. dass der Arduino per SIP oder UCWA sich am Lync Server anmeldet. Allerdings gibt es noch keine passende SIP-Library und selbst der HTTP-Client ist schon recht beschränkt. Zudem stellt sich natürlich die Frage, wie die Anmeldedaten auf den kleinen Arduino kommen. Sicher könnte man die per serieller Kommunikation übertragen, aber einfach wird das nicht.
Für den USB-Anschluss gibt es mit dem Busylight, Lync I-Buddy und Hinweisen (Statuslicht und Ideen) schon viele passable Lösungen. Ob es da sinnvoll ist, mit dem Arduino Ethernet z.B. eine Kommunikation zum Lync Server zu entwickeln, steht in den Sternen. Denkbar wäre natürlich eine Umsetzung über eine Middleware, z.B. eine IIS-Applikation auf dem Lync Server stellt ausgewählte Informationen über einen einfachen (anonymen) HTTP-GET bereit.
Dann wäre es natürlich sehr viel einfacher, einen Arduino dazu zu verwenden, z.B. abhängig vom Status einer Person eine Signalleuchte zu steuern oder auf bestimmte Aktionen (INPUT) eine Meldung an Lync zu senden. Es gibt ganz viele Dinge zu entdecken.
Arduino zum Lernen
Es ist relativ einfach, mit einem Arduino erst mal etwas zu bauen, was es schon gibt. Man kann dennoch dabei sehr viel Lernen. Überlegen Sie mal:
- "Fahrradcomputer"
Klar gibt es die beim Discounter schon für <10 Euro aber es geht ja um den Lerneffekt. Ein Arduino, ein per I2C-Bus angeschlossenes LCD-Display und ein Magnetschalter an einem der digitalen Eingänge erlaubt ihnen schon sehr viele Themen zu bearbeiten, z.B. Entprellung von Tasten, Frequenzzählung und Ausgabe auch dem LCD - Voltmeter/Multimeter
Auch die gibt es schon für wenig Geld aber mit den analogen Eingängen (0-5V) und einem LCD lässt sich natürlich auch ein Voltmeter nachbauen. Mit etwas externer Beschaltung (Wiederstand) auch ein Amperemeter. - Transistor-Meter/Grapher
Für das einfache LCD ist das sicher nicht mehr ausreichend, aber ein Arduino könnte sicher problemlos einen Transistor analog ansteuern und z.B. dessen Verstärkungsgrad ermitteln. - Morse-Zeichen
Die ersten Übertragung von Informationen per Kabel und Funk erfolgt über kurze und lange Töne. Lassen wir erst mal die LED in dem Takt blinken, wie die Zeichen z.B.: per COM-Port an den Arduino gesendet werden. Etwas schwieriger ist die Gegenrichtung, die Signale auf einem Eingang auszuwerten, da hier eine veränderliche Geschwindigkeit und die Trennung von Zeichen erkannt werden muss. Aber technisch geht das minimalen externen Beschaltungen. - Logik Analysator
Wenn man einen größeren Arduino nimmt, dann könne man damit z.B., einen CMOS/TTL-Chip-Tester bauen. Wobei heute immer weniger noch TTL-Gräber auf Basis eines 74xx bauen. - Wecker
Warum nicht einfach den Arduino mit einer I2C-Bus-Echtzeituhr ausstatten und mit dem LCD die uhrzeit anzeigen. Ein paar Taster gibt es sicher noch um die Zeit zu stellen oder vielleicht sogar eine Alarmfunktion einzubauen. So einen Wecker hat wohl niemand sonst neben seinem Bett stehen. - Würfelsimulation
Bei der ICE-Fahrt habe ich zwei Kinder beobachtet, die "Mensch ärgere dich nicht" gespielt haben. Klar dass der Würfel mehr auf dem Fußboden rumflog als auf dem Tisch landete. Natürlich gibt es auch fertige Bausätze für 4-10 Euro, aber es geht ja um den Bastelspaß. - Reaktionstester
Der Arduino schaltet in Licht ein und zählt die Dauer die der Spieler braucht um eine Taste zu drücken. Die Dauer kann er auf einem LCD ausgeben oder eine LED-Zeile. Wer reagiert wohl am schnellsten. - Arduino als Kennwortsafe
Es gibt Arduinos, die sehen schon aus wie ein USB-Stick und erscheinen nicht nur als COM-Port, sondern können sogar eine Tastatur/Maus emulieren. Da könnte man doch mit einer kleinen Software auf dem Host ein paar Steuerdaten an den COM-Port senden, so dass der Arduino dann das passende Kennwort als Tastatur "eintippt". Gerne noch mit einer PIN-Eingabe auf dem Arduino. Und schon wäre das Kennwort ein stück sicherer. - Netzwerk-Thermometer
Kombiniert man einen Arduino Nano mit einem Ethernet-Shield, dann hat man für ca. 12€ schon einen "Netzwerk Arduino". Verpasst man dem dann noch z.B. einen LM75 Temperatursensor per I2C-Bus. Dann hat man schnell ein Ethernet Thermometer. Alternativ kann man per 1-Wire Bus Sensoren wie den DS18B20 verwenden und das gleiche erreichen. Klar geht das auch mit einem RaspberryPi aber mit viel mehr Overhead. Allerdings muss man die Daten schon noch abfragen und weiter verarbeiten.
Je länger ich drüber nachdenke, desto mehr kleine Projekte fallen mir ein. Suchen Sie einfach etwas im Internet und ein paar ungewöhnliche Projekte habe ich hier noch aufgeführt.
- Arduino: Eine Kontrollstation bauen -
PAL Fernseher ansteuern
https://www.heise.de/ratgeber/Arduino-Eine-Kontrollstation-bauen-5062038.html - Arduino: Eine Lärmpegelampel bauen
https://www.heise.de/ratgeber/Arduino-Eine-Laermpegelampel-bauen-5056666.html
Sie brauchen nur etwas im Internet stöbern, um massenhaft Projekte zu finden
Ardunio "Verwandte"
Der Erfolg der Arduino-Plattform und deren "Offenheit" fördert natürlich auch andere Projekte. Aus China bekommen Sie sehr billig jede Art von Arduino-Nachbau aber es gibt auch Leute, die spezielle Versionen daraus weiter entwickeln, z.B. solche mit Funktechniken oder sehr kleine Geräte:
- RFduino: iPhone, Bluetooth
4.0 LE, Arduino Compatible
Board!
http://www.youtube.com/watch?feature=player_detailpage&v=arWBdGwCJcM
https://www.kickstarter.com/projects/1608192864/rfduino-iphone-bluetooth-40-arduino-compatible-boa
http://www.rfduino.com/
http://t3n.de/news/rfduino-fingernagelgroser-452515/ - WiFiDuino
https://www.indiegogo.com/projects/wifiduino
https://www.youtube.com/watch?v=jHANV4FIXOA
http://www.geeky-gadgets.com/wifiduino-chip-sized-arduino-with-wi-fi-and-mini-oled-screen-02-06-2014/ - LinkIt Smart 7688 12US$
https://labs.mediatek.com/site/global/developer_tools/mediatek_linkit_smart_7688/whatis_7688/index.gsp
http://www.seeed.cc/linkit_smart_7688/
http://www.seeedstudio.com/depot/category_products?themes_id=1422
Arduino + Wifi + OpernWRT - Controllino
https://www.controllino.com/product/controllino-maxi/
Arduino Mega 2650 auf Hutschine (ca 200€)
Es gibt sicher noch einige andere Geräte und ich kann unmöglich hier einen Marktüberblick oder eine Empfehlung geben. Nutzen Sie einfach eine Suchmaschine.
Weitere Links
- RaspberryPI
- PIC/Atmel
- Arduino und S0
- Arduino Ethernet Probe
- Arduino Presence
- ATTiny85
-
Großer Pool mit Tutorials und
Beispielen.
https://create.arduino.cc/ -
Firmata - generische Firmware
zum Testen der Hardware
http://firmata.org/wiki/Main_Page -
Entprellung
http://www.mikrocontroller.net/articles/Entprellung -
Arduino Builder – standalone utility für building and uploading Arduino sketches
http://arduinodev.com/arduino-uploader/ -
Arduino Cheeet Sheet
http://robodino.org/resources/arduino
Arduino Tutorial - 15
Videos a a 10 -20min zu Arduino
https://www.youtube.com/playlist?list=PLE0C7D8863F6DACCE
- Arduino Tutorials
http://tronixstuff.com/tutorials/ - Witing a Library für Arduino
http://arduino.cc/en/Hacking/LibraryTutorial - Die Rheinturmuhr mit Arduino
http://www.hjberndt.de/soft/rtc.html
http://www.hjberndt.de/soft/rtcsim.html - Ambilight Nachbau mit
Boblight und Adalight
http://www.onlymine.de/ambilight-nachbau-mit-boblight-und-adalight/
Arduino NANO als Schnittstelle zum PC und ein paar LEDs, die per Takts angesteuert werden. - Temperatursensor
http://www.mikrocontroller.net/articles/Temperatursensor - Touch Develop: Arduino
https://www.touchdevelop.com/app/#list:topics:topic:arduinotutorials:overview - Wiring: ähnliche Hardware und Konzepte
http://wiring.org.co
http://wiring.org.co/hardware/
https://store.spark.io/ (z.B. Photon und Core-Boards) - Heise Arduino
http://www.heise.de/thema/Arduino - Permanent storage using
EEPROM
http://lucstechblog.blogspot.com/2020/01/permanent-storage-using-eeprom.html