Doppelte Geschwindigkeit für den Arduino Uno! Die Idee ist von Jan Ostman auf hackster.io. Doch leider geht es nicht ganz so einfach, wie es dort beschrieben wird. Das Problem ist, dass avrdude die Baudrate 230400 nicht mag. Nachdem ich den Bootloader angepasst hatte, dass er mit 115200 Baud arbeitet, tauchte ein weiteres Problem auf. Aus irgendwelchen Gründen funktionierte die Kommunikation immer noch nicht. Aus ungeklärter Ursache lag die Baudrate ein wenig unter der erwarteten. Eine Korrektur der Angabe der CPU-Taktfrequenz auf 31,5 MHz hat's dann gerichtet. Das Programmieren mit einem ISP-Programmer klappt jedoch einwandfrei.
Wenn man jedoch mit der Arduino-IDE entwickeln will, muss man ein paar Dinge an die geänderte Taktfrequenz anpassen. Ohne ISP-Programmer geht es dabei aber nicht!
Wegen der Hardware-Änderungen funktioniert avrdude zunächst nicht. Man benötigt für das Laden sowohl der Testprogramme als für den Bootloader einen eine ISP-Programmer.
Da Prinzip ist recht einfach. Statt des im Arduino eingebauten Quarzes und dem internen Quarzoszillator wird ATmega328 wird ein externer Quarzoszillator mit einer Taktfrequenz von 32 MHz angeschlossen. Die Verwendung eines 32 MHz Quarzes mit dem internen Quarzoszillator funktioniert nicht. Der interne Oszillator funktioniert nur bis etwa 20 MHz. Mit einer externen Takt-Quelle funktioniert der Chip auch bei 32 MHz noch einwandfrei.
Man benötigt:
& | oder | |||
Arduino UNO | Quarzoszillator 32 MHz (DIL14) (Dies ist natürlich kein 32 MHz Quarz, sondern nur ein Muster für die Bauform) |
Quarzoszillator 32 MHz (SMD) (Dies ist natürlich kein 32 MHz Quarz, sondern nur ein Muster für die Bauform) |
Man kann natürlich eine kleine Platine nehmen, wie bei hackster.io beschrieben. Der Nachteil ist, dass dann die Bauteile über die Buchsenleisten des Boards herausragen würden. Eine aufgestecktes Shield würde also Kontakt mit dem Oszillator und dem ATmega bekommen. Das ist nicht gut. Ich habe stattdessen den Quarzoszillator mit doppelseitigem Klebeband neben den ATmega geklebt und die Pins mit angelöteten Kabeln mit dem Prozessor verbunden.
Die Pins XTAL1 (Pin 9) und XTAL2 (Pin 10) sind auf dem Arduino-Board mit dem "normalen" Quarz verbunden. Die einfachste Methode diese Verbindung zu kappen ist: ATmega aus der Fassung herausnehmen, Pins hochbiegen, wieder einstecken.
Die Pins des Oszillators beschriftet man am besten vor dem Anbringen von unten. Das reduziert die Fehlermöglichkeiten enorm. Zusätzlich sollte man -ebenfalls zur Fehlervermeidung- mit farbigen Drähten arbeiten. Den freien vierten Pin des Oszillators kappt man am besten. Mit einem kleinen Stück doppelseitigem Klebeband klebt man den Oszillator auf die freie Fläche des Boards. Zum Schutz gegen ungewollte Kontakte und zur Fixierung der Drähte habe ich den Oszillator dann noch mit einer Schicht Heißkleber überzogen. Das ganze sieht dann so aus:
Quarzoszillator installiert ... | ... und mit Heißkleber isoliert |
Man sollte einen Arduino nehmen, auf dem bereits ein Programm geladen ist, z.B. das mitgelieferte Blink. Dann kann man gleich erkennen, ob man erfolgreich gearbeitet hat. Die LED müsste dann nach Anschluss an eine Stromversorgung blinken, aber eben mit der doppelten Frequenz.
Der ATmega funktioniert auch mit der Standardeinstellung der Fuses. Sicherer ist es jedoch, die Clock Source (CKSEL) passend einzustellen. Dies muss mit einem ISP-Programmer erfolgen. Im Zweifelsfall geschieht dies spätestens, wenn der neu erstellte Bootloader mit der Arduino-IDE installiert wird. Hierbei werden auch die in der Board-Beschreibungsdatei aufgeführten Fuse-Einstellungen programmiert.
Wie bereits zu Beginn erwähnt, funktionierte die Kommunikation zwischen avrdude und den Bootloader nicht einwandfrei. Grund waren leicht unterschiedliche Baudraten. Deshalb ist es am sinnvollsten, zunächst einmal zu überprüfen, unter welchen Bedingungen die Kommunikation funktioniert. Hierzu schreibt man ein kleines Programm, das nicht mehr macht als über die serielle Schnittstelle empfangene Zeichen wieder zurück zu senden ("Echo").
#include "Arduino.h"
void setup()
{ Serial.begin(115200);
UBRR0 = 0x22;
}
void loop()
{ if (Serial.available())
{ char a = Serial.read();
Serial.print(a);
}
}
Mit einem einfachen Terminalprogramm, wie z.B. vbTermie, kann man nun testen, ob die Verbindung funktioniert. Einfach ein paar Zeichen senden und schauen, ob das Echo korrekt angezeigt wird. Dieses Programm muss mit einem ISP-Programmer programmiert werden, da der ATmega bereits mit der neuen Taktfrequenz läuft.
Interessant ist die rot markierte Zeile: "UBBR0 = 0x22;". Hiermit wird die Baudrate nachjustiert. Wenn die Taktfrequenz genau genug bei 32 MHz liegt, wäre der Wert 0x22 korrekt. Klappt die Übertragung nicht, kann man diesen Wert erniedrigen oder erhöhen bis die Verbindung funktioniert. Mehr als zwei oder drei Punkte sollte sie jedoch nicht daneben liegen. Dann ist vermutlich etwas anderes falsch.
Hat man einen passenden Wert für UBRR0 (bei mir war der Wert bei 0x21), gilt es, eine passende Taktfrequenz zu ermitteln. Hierzu eignet sich hervorrangend das Programm avrcalc. Man trägt die bekannten Wert für UBBR ein und variiert die Clock Frequenz, bis sich bei UBBR der passende Wert ergibt. Mann sollte hier etwas zugeben und nicht genau die Grenze austesten, um damit den Rundungsfehlern bei den unterschiedlichen Arten der Ermittlung der des UBBR-Wertes Rechnung zu tragen. Bei mir war 31,4 MHz ein passender Wert (F_CPU=31400000L).
In der aktuellen Version des Arduino werden die optiboot-Bootloader verwandt. Diese befinden sich im Verzeichnis ...\hardware\arduino\bootloaders\optiboot. Dort sind die Quellen, eine Makefile, ein .bat-datei, die die Kompilierung startet, und diverse vorübersetzte .hex-Dateien enthalten.
Als erstes gilt es die Makefile anzupassen. Diese enthält einen Eintrag für den ATmega328. Die entsprechenden Zeilen beginnen mit "atmega328:". Die Zeilen werden dupliziert und angepasst. Zu ändern ist der Name "atmega328_turbo" und der Eintrag für AVR_FREQ. Hier muss die neue Taktfrequenz 31400000L eingetragen werden:
atmega328_turbo: TARGET = atmega328
atmega328_turbo: MCU_TARGET = atmega328p
atmega328_turbo: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega328_turbo: AVR_FREQ = 31400000L
atmega328_turbo: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
atmega328_turbo: $(PROGRAM)_atmega328_turbo.hex
atmega328_turbo: $(PROGRAM)_atmega328_turbo.lst
Man passt sinnvollerweise die Datei "omake.bat"- zur Erstellung der Bootloader an. Das zusätzliche Pause-Kommando am Ende verhindert, dass das Kommando-Fenster nach Durchführung des Kompilierungsvorgangs direkt wieder geschlossen wird. Man kann so die Compiler-Meldung in aller Ruhe auswerten.
okame.bat:
..\..\..\tools\avr\utils\bin\make OS=windows ENV=arduino %*
pause
Am einfachsten geht es, wenn man eine .bat-Datei erstellt, die omake mit den richtigen Parametern aufruft. Die Erstellung des des neuen Bootloaders erfolgt dann per Klick auf diese Datei.
turbo_make.bat:
omake atmega328_turbo
Im Verzeichnis ...\hardware\arduino befindet sich die Datei boards.txt. In dieser Datei sind alle Boards mit deren Einstellungen verzeichnet. In diese Datei muss eine neuer Eintrag eingefügt werden. Dies geschieht am besten gleich nach dem Eintrag für uno. Wie man unschwer erkennen kann, heißt das neue Board unoturbo.
##############################################################
unoturbo.name=Arduino Uno Turbo
unoturbo.upload.protocol=arduino
unoturbo.upload.maximum_size=32256
unoturbo.upload.speed=115200
unoturbo.bootloader.low_fuses=0xe0
unoturbo.bootloader.high_fuses=0xde
unoturbo.bootloader.extended_fuses=0x05
unoturbo.bootloader.path=optiboot
unoturbo.bootloader.file=optiboot_atmega328_turbo.hex
unoturbo.bootloader.unlock_bits=0x3F
unoturbo.bootloader.lock_bits=0x0F
unoturbo.build.mcu=atmega328p
unoturbo.build.f_cpu=31400000L
unoturbo.build.core=arduino
unoturbo.build.variant=standard
##############################################################
Dies ist im Wesentlichen eine Kopie des Eintrags für den UNO. Die Bezeichnungen der Parameter sind eigentlich selbstsprechend. Geändert sind die Einträge für:
Der Rest ist unverändert. Nach dem nächsten Starten der Arduino-IDE ist jetzt an zweiter Stelle der Eintrag für den UNO Turbo:
Wie man das Atmel Studio einrichten muss, dass man Arduino-Programme damit erstellen kann, ist hier beschrieben: Arduino-Programme mit dem Atmel Studio entwickeln. Es ist eine zusätzliche Bibliothek notwendig, die mit den geänderten Parametern übersetzt wurde, und angepasste Projekt-Templates. Die angepassten Dateien können hier herunter geladen werden. Wie man die benötigten Dateien an andere Boards anpasst, ist hier beschrieben.
Zur Erstellung einer passenden Bibliothek kopiert man das Verzeichnis für den Uno, ändert alle Namen und passt im Atmel Studio dann noch die Taktfrequenzen an. Details zur Bibliothek-Erstellung siehe hier.
Details zur Erstellung der Templates findet man hier. Am einfachsten ist es, man kopiert das Template (ZIP-Datei) für den Uno und benennt es um in "ArduinoUnoTurbo". In dem ZIP-Ordner müssen zwei Dateien umbenannt werden:
In "ArduinoUnoTurbo.vstemplate" müssen folgende Tags angepasst ...
... und in "ArduinoUnoTurbo.cppproj" diese Konstanten geändert werden:
Bei einer anderen ermittelten Taktfrequenz ist natürlich diese zu benutzen!