Arduino ohne Arduino

Die letzten Jahre habe ich es immer geschafft mich dem Arduino-Wahn zu entziehen. Wenn jemand für ein kleines Projekt ein komplettes (und damit auch recht teures) Arduino-Board verbaut bin ich erst einmal der Meinung, dass die Person nicht wirklich weiß, was sie da tut. Oftmals reicht schon ein kleiner ATtiny in Minimalbeschaltung für wenige Euro. Jetzt hat mir aber mein Mitbewohner neulich einen Klon geschenkt…

Kompilieren mit gcc

Die Arduino(klone) haben eines gemeinsam: sie benutzen Atmel Chips. Meiner hat einen Atmega328p, also ziemlich Standard. Mit dem avr-gcc kann man eigene Programme für die Chips unter Linux (vermutlich auch OS-X) kompilieren.

avr-gcc -o output.elf main.c

Das nimmt die Datei main.c und kompiliert sie zu output.elf. Hat man mehr als eine Quelldatei kann man diese einfach hintereinander auflisten.

Warte mal, das ist ja nur ein Standard C-Compiler, der kann garnicht die fancy Arduino Bibliotheken?! Ja das stimmt, von denen bin ich auch kein großer Freund. Es ist toll, dass man in der Arduino IDE recht schnell einzelne Tasks vervollständigen kann (das gilt zumindest für Standardsachen wie Pins an/aus oder PWM generieren). Mit ein bisschen Übung geht das ohne aber ähnlich schnell. Vorallem lernt man dabei wie der Code bzw die Architektur funktioniert und wer versteht wie es funktioniert schreibt besseren und performanteren Code!

Wie man einen Atmega in C programmiert kann man hier lernen.

Das Programm flashen

Der Klon kommt mit einem 6-poligen ISP-Header, wofür ich auch ein Programmiergerät besitze, aber das nette an den Arduinos ist ja der Bootloader durch den man kein Programmiergerät braucht. Glücklicherweise kann avrdude auch mit Hilfe des Bootloader den Atmega flashen.

avrdude -V -F -p atmega328p -P /dev/ttyUSB0 -c stk500v1 -b 57600 -U flash:w:programm.hex

Das geschieht unter der Annahme, dass der Klon dem tty-device /dev/ttyUSB0 zugeordnet wird. Sollte vorher ein anderes Gerät einer ähnlichen Klasse angeschlossen worden sein, kann die Zahl auch höher sein. Mit ls /dev | grep ttyUSB kann man sich anzeigen lassen welche das aktuell sind.

Wer aufmerksam mitgelesen hat wird merken, dass avr-gcc eine .elf Datei ausspuckt, avrdude aber eine .hex Datei erwartet. Die kann man recht einfach mit avr-objcopy generieren.

avr-objcopy -j .text -j .data -O ihex output.elf programm.hex

Okay, jetzt habe ich ja alles was ich brauche um den Chip zu Programmieren? Naja, fast. Noch gehört /dev/ttyUSB0 root und der Rest hat keine Schreibrechte. Das kann man mit einem einfachen chown ändern und muss jedes mal gemacht werden wenn der Klon angesteckt wird.

sudo chown benutzername /dev/ttyUSB0

Passieren muss das mit root-Rechten, deshalb das sudo am Anfang.

udev-rule

Das es mich nervt jedes mal beim Einstecken die Schreibrechte für das tty-Device zu setzen, habe ich eine udev-rule geschrieben die das für mich macht.

Zuerst mit lsusb Produkt-ID und Vendor-ID herausfinden. Der Klon hat nicht mal einen richtigen FTDI-Chip sondern irgendwas richtig günstiges wie es scheint.

Bus 002 Device 026: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

Wobei 1a86 die Vendor-ID ist und 7523 die Produkt-ID.

Unter /etc/udev/rules.d/ habe ich die Datei 82-usb-arduino-clone.rules erstellt, welche dem Gerät die Gruppe plugdev hinzufügt und einen Symlink zu ttyArduino erstellt. Falls man beispielsweise zusätzlich einen RS232-Adapter angeschlossen hat muss man nicht erst rätseln was ttyUSB0 und was ttyUSB1 ist, sondern kann den Klon bequem über ttyArduino ansprechen.

ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0660", GROUP="plugdev", SYMLINK="ttyArduino"

Ein makefile sie alle zu knechten…

TARGET = test
CC = avr-gcc
CDEFS = -DF_CPU=16000000UL -Os
DEVICE = atmega328p

SRC = $(wildcard src/*.c)
OBJECTS = $(patsubst %.c,%.o,$(SRC))


all: $(TARGET).elf
	avr-size --mcu=$(DEVICE) -C $(TARGET).elf


$(TARGET).elf: $(OBJECTS)
	$(CC) $(CDEFS) -mmcu=$(DEVICE) -o $(TARGET).elf $^

%.o: %.c
	$(CC) $(CDEFS) -mmcu=$(DEVICE) -o $@ -c $^


uart:
	picocom /dev/ttyArduino -b 9600 -r -l



.PHONY: flash
flash: $(TARGET).hex
	avrdude -V -F -p $(DEVICE) -P /dev/ttyArduino -c stk500v1 -b 57600 -U flash:w:$(TARGET).hex

$(TARGET).hex: $(TARGET).elf
	avr-objcopy -j .text -j .data -O ihex $(TARGET).elf $(TARGET).hex



.PHONY: clean
clean:
	rm -f src/*.o
	rm -f $(TARGET).elf $(TARGET).hex
Categories: linux
Tags: german, microcontroller, electronics