ATtiny202 mit VSCode und PlatformIO
Auf
der Suche nach einer möglichst einfachen Programmierumgebung für die
ATtiny 0/1 Familie wollte ich auch die Arduino IDE testen. Da gibt es
den megaTinyCore von SpenceKonde (https://github.com/SpenceKonde/megaTinyCore).
Allerdings läuft diese Erweiterung nicht in meiner aktuellen
Arduino-Version. Die automatische Einrichtung über den Boardmanager
funktionierte nicht. Die manuelle Einrichtung ging zwar, aber beim
Kompilieren gibt es Fehler. Der Versuch war aber nicht ganz nutzlos,
weil ich nun in die Beispiele anschauen kann, was manche Fragen
beantwortet.
Mein Sohn Fabian arbeitet schon länger mit VSCode und PlatformIO und
hat mir von den Vorteilen berichtet. Man sucht sich einen Controller
und eine Programmiersprache aus, und Plattform IO kümmert sich ganz
allein darum, alles nötige aus dem Netz zu holen und zu installieren.
Am Ende funktioniert es einfach. Dass irgendwelche Versionen nicht
zusammenpassen, gibt es nicht.
Also los: Zuerst muss Visual Studio Code (VSCode) installiert werden,
nicht zu verwechseln mit Microsoft Visual Studio. VSCode stammt zwar
ebenfalls von Microsoft, ist aber ein Open-Source-Projekt und zielt auf
eine Vielzahl unterschiedlicher Mikrocontroller. Es kann kostenlos
geladen werden: https://code.visualstudio.com/Download
Nach der Installation findet man unten links ein Zahnrad für die
Einstellungen. Hier wählt man Extensions. Es erscheint das Fenster
links mit den Erweiterungen. Am Anfang gibt es nur C/C++. Man soll aber
auch Python installieren, weil es von VSCode selbst benutzt wird.
Mitinstalliert wird dabei Pylance, ein Python-Zusatz für VSCode. Für
weitere Extensions kann man im oberen Eingabefenster "Search
Extensions" einen Begriff eingeben. Platform reicht, dann wird
PlattformIO vorgeschlagen, das nun installiert werden kann. Jede
Installation dauert mehrere Minuten, aber es lohnt sich.
Das PatformIO-Logo ist eine Ameise. Ein neues Projekt beginnt man auf
der Home-Seite, die jederzeit mit dem Häuschen-Symbol auf der unteren
Leiste erreicht werden kann.
Das Projekt soll Test1Tiny202 heißen. Dass ich dann ein Board
aussuchen soll, wo ich doch nur den blanken Chip habe, fand ich zuerst
entmutigend. Aber hier wird alles „Board“ genannt, auch wenn es nur ein
Controller ist. Im Board-Feld tippe ich Tiny202 ein, dann wird der
Eintrag sofort auf die korrekte Bezeichnung des Chips erweitert.
Außerdem schlägt PlatformIO nun das Arduino-Framework vor.
Einverstanden. Wenn all das zum ersten Mal verwendet wird, kommt wieder
eine längere Installations-Session. Man kann sich dabei mit dem guten
Gefühl zurücklehnen, dass PlatformIO sich um alles kümmert.
Nun erhalte ich mehrere vorbereitete Dateien. Zuerst öffnet sich
platformio.ini mit den wichtigsten Einstellungen. Damit ist schon alles
bereit, bis auf einen Punkt. Bisher geht PlatformIO noch davon aus,
dass ich einen Bootloader verwenden will. Dass ich direkt über UPDI
programmieren will, muss ich noch hinzufügen. Dazu später mehr. Erstmal
schaue ich mir unter scr den Sourcecode main.cpp an. Hier sieht man die
grundlegende Struktur. Oben steht #include <Arduino.h>, sodass
man alle Annehmlichkeiten des Arduino-Systems nutzen kann. Wenn man die
Zeile löscht, kann man auch einen nativen Code einfügen, den man z.B.
mit AVR Studio 7 vorher erzeugt hat.
Am Anfang weiß ich vielleicht nur, welche Ports der Controller
hat und muss mich nun herantasten, wie sie im Arduino-Framework heißen.
Ich probiere es mal mit den Ports A3 und A6.
Wenn ich
Strg drücke und dabei auf A6 oder A3 klicke, öffnet sich die Datei
pins_arduino.h, wo die Pins deklariert wurden. Hier findet man auch
eine Gesamtübersicht der Anschlüsse. Offensichtlich sind alle Ports
nach Arduino-Art von 0 bis 4 bezeichnet, wobei VCC, GND und der
UPDI-Pin ausgespart wurden. Aber Achtung, hier ist der ATtiny412
abgebildet. Beim Tiny202 liegt der TXD-Anschluss an PA6. Ich muss also
meinen Blinker auf einen andern Pin legen. RXD verwendet PA7. Für den
Blinker eignet sich PA2 bzw. der Arduino-Port 3.
// ATtiny412 / ARDUINO
// _____
// VDD 1|* |20 GND
// (DAC) (AIN6) PA6 0 2| |19 4~ PA3 (AIN3)(SCK)(EXTCLK)
// (AIN7) PA7 1 3| |18 5 PA0 (nRESET/UPDI)
// (MOSI)(TXD*)(SDA) (AIN1) PA1 2 4|_____|17 3 PA2 (AIN2)(MISO)(RXD*)(SCL)
//
Bei der Gelegenheit habe ich in setup() auch noch die bisher
vergessene Zeile Serial.begin (9600) eingefügt. Um diesen Quelltext zu
kompilieren, muss man unten das Häkchen rechts neben dem Häuschen
klicken. PlatfomIO meldet success und erzeugt die Datei firmware.hex.
Rechts daneben gibt es noch den Pfeil, mit dem man das Ergebnis gleich
in den Chip brennen kann. Aber dafür muss man zuerst in der Datei
plattformIO.ini sagen, wie das gehen soll. Außerdem muss ich hier
mitteilen, dass der Controller per default mit 20 MHz arbeitet. Arduino
ist 16 MHz gewohnt und erwartet, dass der Bootloader den Chip auf 16
MHz umstellt. Weil ich aber Pymcuprog verwende, bleibt es bei 20 MHz.
Der Inhalt von PlatformIO.ini ist nun:
[env:ATtiny202]
platform = atmelmegaavr
board = ATtiny202
; Clock frequency in [Hz]
board_build.f_cpu = 20000000L
framework = arduino
upload_speed = 115200
upload_flags =
--tool
uart
--device
attiny202
--uart
$UPLOAD_PORT
--clk
$UPLOAD_SPEED
upload_command = pymcuprog write --erase --verify $UPLOAD_FLAGS --filename $SOURCE
Beim Upload sieht man die bekannten Meldungen von Pymcuprog. Die LED
beginnt sofort zu blinken. Jetzt muss ich nur noch das Programmierkabel
an PA6 (TXD) stecken. Man kann auch PA6 mit UPDI (PA0) verbinden. Aber
vor dem nächsten Programm-Upload muss die Verbindung getrennt werden.
PlatformIO hat auch einen seriellen Monitor, den man mit dem
Steckersymbol startet. Hier sieht man nun die Messergebnisse des
AD-Wandlers.
Damit sind VSCode und PlatformIO erfolgreich in Gang gesetzt. Manches
war nicht ganz einfach, manchmal musste ich meinen Sohn um Hilfe
bitten. Aber wenn es einmal läuft, ist es nicht schwieriger als die
Arduino-IDE. Und man hat viele Vorteile und Hilfen, die wirklich die
Arbeit erleichtern.
//Ports und ADC Tiny202
#include <Arduino.h>
void setup() {
pinMode(3,OUTPUT);
Serial.begin (9600);
}
void loop() {
Serial.print (analogRead(4));
Serial.print (" ");
digitalWrite (3,1);
delay(500);
digitalWrite (3,0);
delay(500);
}