Wie voor het eerst een Arduino-microcontrollerbordje programmeert, doet dat doorgaans in de Arduino IDE, een grafische ontwikkelomgeving. Minder bekend is dat er ook een officiële commandline-interface bestaat. In deze workshop gaan we daarmee aan de slag.
Auteur: Koen Vervloesem
Ben je tevreden over de Arduino IDE, of gebruik je een andere grafische ontwikkelomgeving zoals PlatformIO die ook Arduino-code ondersteunt, blijf dat dan gerust doen. Maar veel ontwikkelaars hebben een workflow waarin de commandline centraal staat, omdat ze zo efficiënter kunnen werken en de code eenvoudiger kunnen integreren in ontwikkelinfrastructuur, zoals ‘continuous integration’.
Gelukkig hang je niet vast aan een grafische ontwikkelomgeving als je Arduino-code wilt ontwikkelen. Er is zelfs een officieel project dat alle mogelijkheden van de Arduino IDE naar de commandline brengt: arduino-cli. In deze workshop ontwikkelen en flashen we een Arduino-schets volledig op de commandline.
Op de website van Arduino (https://www.arduino.cc/) vind je de commandlineversie niet. Daarvoor moet je op GitHub zijn, op de repository arduino-cli (https://github.com/arduino/arduino-cli). Het project is nog in actieve ontwikkeling en de documentatie die je erover vindt, komt niet altijd meer overeen met de huidige versie. Maar we hebben er al met succes mee gewerkt.
Zoek de laatste release op https://github.com/arduino/arduino-cli/releases (tijdens de redactiesluiting was dat versie 0.5.0-rc1), klik op het pijltje naast ‘Assets’ en download de versie voor je platform. Merk op: ook voor ARM is Arduino-cli beschikbaar, dus je kunt ook op je Raspberry Pi Arduino-schetsen bouwen!
Na het downloaden pak je de tarball uit (we pakken hier alleen het gewenste programma arduino-cli uit), en verplaats je het programma naar een plaats in je pad, bijvoorbeeld /usr/local/bin (zie Listing 1).
tar -z -x arduino-cli -f arduino-cli_0.5.0-rc1_Linux_64bit.tar.gz sudo mv arduino-cli /usr/local/bin
Als je gebruiker nog geen deel uitmaakt van de groep dialout (dat zie je met de opdracht id of groups), voeg de gebruiker dan aan de groep toe:
sudo usermod -a -G dialout gebruikersnaam
Daarna dien je opnieuw in te loggen.
Als je nu gewoonweg arduino-cli zonder parameters uitvoert, krijg je te zien welke deelopdrachten het programma kent. Voor elke deelopdracht kun je extra hulp vragen met arduino-cli deelopdracht –help. Als je wat met de werking van Arduino bekend bent, zul je hier al veel zelf mee kunnen uitzoeken, want de aanpak is gelijkaardig aan die van de Arduino IDE, maar dan op de opdrachtregel.
Werk eerst de lijst met Arduino-cores bij:
arduino-cli core update-index
Vraag dan de lijst met geïnstalleerde cores op:
arduino-cli core list
Als je al cores toegevoegd hebt vanuit de Arduino IDE, zie je die hier ook, want het commandlineprogramma maakt gebruik van dezelfde installatiebestanden (in ~/.arduino15 en ~/Arduino). Je krijgt de geïnstalleerde en de nieuwste versie te zien. Het is om die nieuwste versie te kennen dat we de lijst met cores eerst bijgewerkt hebben. Zie je bijvoorbeeld dat er van je core arduino:sam een nieuwere versie beschikbaar is, dan werk je die bij met:
arduino-cli core upgrade arduino:sam
Je kunt ook al je geïnstalleerde cores in één keer bijwerken:
arduino-cli core upgrade
Wil je weten of je een extra core dient te installeren voor je bordje, bijvoorbeeld de Arduino Due, controleer dit dan met:
arduino-cli board listall due
Als je niets te zien krijgt, is je bordje niet ondersteund in één van de geïnstalleerde cores. Dan moeten we nu zoeken welke core we nodig hebben:
arduino-cli core search due
Dat levert de core arduino:sam op, met als omschrijving ‘Arduino SAM Boards’ (32-bits ARM Cortex-M3), en dat klopt met wat je van de Arduino Due weet. Die core installeer je dan eenvoudig met:
arduino-cli core install arduino:sam
Controleer nu of je bordje wel bekend is:
arduino-cli board listall due
Je krijgt in dit geval twee resultaten: ‘Arduino Due (Native USB Port)’ en ‘Arduino Due (Programming Port)’, omdat je de Arduino Due op twee manieren kunt aansluiten. In de kolom FQBN (fully-qualified board name) zie je bij die eerste arduino:sam:arduino_due_x staan, en dat bevestigt dat de ondersteuning voor het bordje in de geïnstalleerde core arduino:sam te vinden is.
Als je nu je bordje aansluit, zou het herkend moeten worden:
arduino-cli board list
In de uitvoer krijg je de poort te zien, zoals /dev/ttyACM0, het type poort zoals Serial Port (USB), de naam van het bordje en de FQBN.
Voor de Arduino Uno, Mega, Nano en Duemilanove dien je de core arduino:avr te installeren.
Nu je bordje herkend wordt, is het tijd om daar iets mee te doen. Je creëert eenvoudig een nieuwe Arduino-schets met:
arduino-cli sketch new Blink
Dat creëert een directory Blink in je Arduino-directory (standaard ~/Arduino), met daarin een bestand Blink.ino. Dat bestand bevat een ‘lege’ schets, namelijk met de functies setup en loop die beide niets doen:
void setup() { } void loop() { }
En in plaats van nu de Arduino IDE te moeten gebruiken, kun je deze schets in je favoriete editor bewerken, zoals vim of Emacs. Als voorbeeld creëren we een knipperlicht met de ingebouwde led die elk Arduino-bordje heeft:
void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); delay(1000); }
Sla het bestand op als je klaar bent.
Zorg nu dat je bordje aangesloten is en herkend wordt. Kopieer de string in de kolom FQBN van de uitvoer van arduino-cli board list. Ga dan naar de directory van je schets en compileer ze:
cd ~/Arduino/Blink arduino-cli compile -b arduino:sam:arduino_due_x_dbg
Daarbij voer je achter de optie -b de FQBN van je bordje in. Als je code een syntaxisfout bevat, krijg je die nu te zien. Indien je code syntactisch correct is, wordt hij gecompileerd en vind je in je directory twee nieuwe bestanden, met de extensies bin en elf.
Kopieer dan nu de poort in de kolom Port van de uitvoer van arduino-cli board list, bijvoorbeeld /dev/ttyACM0. Upload het gecompileerde bestand naar je Arduino met:
arduino-cli upload -p /dev/ttyACM0 -b arduino:sam:arduino_due_x_dbg -i Blink.arduino.sam.arduino_due_x_dbg.bin
Je ziet dat we naast de seriële poort ook het FQBN weer dienen op te geven, evenals de bestandsnaam van het bin-bestand. Als alles goed gaat, krijg je nu de melding dat de code naar het flashgeheugen van de Arduino wordt geschreven. Daarna wordt de processor gereset en wordt onze code uitgevoerd: de ingebouwde led begint te knipperen. Nu kun je je Arduino van je pc verwijderen en gewoon via een andere bron van stroom voorzien (bij de Arduino Due de dc-stekker): het programma zit in het ingebouwde flashgeheugen en start elke keer weer als het Arduino-bordje opstart.
Een Arduino-schets is zelden zo eenvoudig als ons bovenstaande voorbeeld. Meestal maak je gebruik van een of meerdere bibliotheken, bijvoorbeeld voor communicatie met sensoren of andere apparatuur die je aansluit, of voor functionaliteit zoals JSON of MQTT.
Werk eerst de lijst met Arduino-bibliotheken bij:
arduino lib update-index
Vraag dan de lijst met geïnstalleerde bibliotheken op:
arduino-cli lib list
Als je al bibliotheken toegevoegd hebt vanuit de Arduino IDE, zie je die hier ook. Je krijgt de geïnstalleerde en de nieuwste versie te zien. Het is om die nieuwste versie te kennen dat we de lijst met bibliotheken eerst bijgewerkt hebben. Zie je bijvoorbeeld dat er van je bibliotheek ArduinoJson een nieuwere versie beschikbaar is, dan werk je die bij met:
arduino-cli lib upgrade ArduinoJson
Als je de nieuwste versie draait, bevat de kolom ‘Available’ niets.
Je kunt ook al je geïnstalleerde bibliotheken in één keer bijwerken:
arduino-cli lib upgrade
Merk overigens op: na je bibliotheken bij te werken naar de nieuwste versie, dien je al je Arduino-schetsen opnieuw te compileren en naar je Arduino’s te uploaden. Pas dan gebruik je effectief de nieuwste bibliotheken.
Dan tonen we hier een eenvoudige schets waarvoor we een extra bibliotheek nodig hebben. We willen namelijk een NeoPixel aansturen. NeoPixels zijn rgb-leds met bijbehorende ws2812-chip die met één draadje aan te sturen zijn. Ze bestaan in allerlei formaten: ledstrips, ledringen, ledmatrices of afzonderlijke leds.
Je zoekt nu eenvoudig naar een geschikte bibliotheek:
arduino-cli lib search neopixel
Bij elke bibliotheek krijg je heel wat uitleg te zien, zoals de auteur en de website. We kiezen voor de bibliotheek ‘Adafruit NeoPixel’ (je hebt de naam op de regel die begint met Name: nodig) en installeren die:
arduino-cli lib install "Adafruit NeoPixel"
We tonen hier hoe je een NeoPixel-jewel met zeven leds op de Arduino Due aansluit. Die kun je nog rechtstreeks via het Arduino-bordje voeden; gebruik je meer leds, dan heb je een externe voeding nodig.
Onze NeoPixel heeft zes aansluitingen: GND, VCC, IN en OUT, VCC, GND. De eerste GND sluiten we aan op GND van de Arduino Due en de eerste VCC sluiten we aan op 3V3 van de Arduino Due. IN verbinden we met een weerstand van 100 ohm, waarvan we de andere kant met pin PWM2 van de Arduino Due verbinden. In principe kun je de NeoPixel aansluiten met krokodillenklemmetjes, maar doe dat alleen voor een test, want dat is niet echt betrouwbaar. Voor een definitieve opstelling neem je voor elke aansluiting een jumperwire waarvan je één connector afknipt, waarna je enkele millimeters van de isolatie van het uiteinde stript en dit dan op de connector van de NeoPixel soldeert.
En wat dan met de drie andere aansluitingen van de NeoPixel? Die hebben we niet nodig. De NeoPixels kun je immers doorlussen naar elkaar. Dan sluit je OUT van de eerste NeoPixel aan op IN van de volgende NeoPixel, en met de tweede VCC en GND voed je de volgende NeoPixel. Aangezien we hier slechts één NeoPixel-module aansluiten, hebben we die dus niet nodig.
Dan maken we een nieuwe schets aan:
arduino-cli sketch new NeoPixel
En in het bestand ~/Arduino/NeoPixel/NeoPixel.ino maken we de volgende code aan van Listing 1.
#include <Adafruit_NeoPixel.h> #define PIXELS 7 #define PIN 2 #define BRIGHTNESS 32 // 0-255 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXELS, PIN, NEO_GRB + NEO_KHZ800); void setup() { pixels.begin(); pixels.setBrightness(BRIGHTNESS); pixels.show(); } void loop() { for(int p = 0; p < PIXELS; p++) { for (int i = 1; i >=0 ; i--) { for (int j = 1; j >=0; j--) { for (int k = 1; k >=0; k--) { pixels.setPixelColor(p, i * 255, j * 255, k * 255); pixels.show(); delay(50); } } } } }
Op de eerste regel zie je dat we de zojuist geïnstalleerde bibliotheek gebruiken. Daarna definiëren we het aantal pixels op de NeoPixel-jewel, de pin op de Arduino Due waarop we de IN-aansluiting van de NeoPixel aangesloten hebben, en de helderheid van de NeoPixel, die we vrij laag instellen: op volledige helderheid zijn de leds verblindend.
In de functie loop hebben we dan geneste lussen, die achtereenvolgens alle pixels en rgb-componenten overlopen. Het komt erop neer dat elke pixel acht kleuren achtereen krijgt met 50 ms vertraging ertussen, waarna de pixel uit staat (alle rgb-componenten zijn op het einde van de lus 0) en de volgende pixel aan de beurt komt. Het is een eenvoudige manier om te testen of al je pixels nog werken.
Daarna compileren en uploaden we de code:
cd ~/Arduino/NeoPixel arduino-cli compile -b arduino:sam:arduino_due_x_dbg arduino-cli upload -p /dev/ttyACM0 -b arduino:sam:arduino_due_x_dbg -i NeoPixel.arduino.sam.arduino_due_x_dbg.bin
En als alles goed gaat, moet je nu de pixels een voor een in verschillende kleuren zien oplichten.
Je kunt ook nog externe cores toevoegen. Dat gaat zelfs veel sneller dan in de Arduino IDE, waar je allerlei menu’s moet doorworstelen. Stel dat je de esp8266-core wilt installeren. Dan creëer je een bestand arduino-cli.yaml in je map ~/Arduino met de volgende inhoud:
board_manager: additional_urls: - http://arduino.esp8266.com/stable/package_esp8266com_index.json
Update daarna de lijst met cores:
arduino-cli core update-index
En daarna vindt arduino-cli ook een core voor je esp8266-modules:
arduino-cli core search esp8266
Die installeer je eenvoudig met:
arduino-cli core install esp8266:esp8266
De mogelijke FQBN’s voor esp8266-modules vind je met:
arduino-cli board listall esp
En vanaf nu kun je met arduino-cli ook je esp8266-modules programmeren met Arduino-schetsen.
We hebben hier de belangrijkste taken getoond die je met arduino-cli kunt uitvoeren, maar het programma kent nog heel wat opties om het gedrag aan te passen. Bekijk zeker de uitvoer van arduino-cli deelopdracht –help voor meer opties. De optie -v (voor verbose) is globaal geldig en interessant als je tegen problemen aanloopt: je krijgt dan meer informatie te zien, die je helpt bij het oplossen van problemen. Als je een tijdje met arduino-cli gewerkt hebt, wil je niet meer terug naar de Arduino IDE!