Posts mit dem Label Bootloader werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Bootloader werden angezeigt. Alle Posts anzeigen

2013-01-12

Die Kleinen - ATtiny Chips im Arduino IDE

Um kleinere "Arduino"-Schaltungen aufzubauen, eignen sich auch Microcontroller der ATtiny-Reihe. Kleiner nicht im Sinne von SMD-Technik, sondern im Sinne von weniger IO-Pins, weniger Speicher, günstigerer Preis, weniger Bauteile, etc.
Hier sind meine ersten Versuche mit den Chips ATtiny 85, 44 und 2313.

Dazu muss man die Chips entsprechend verkabeln, wiederum das Arduino Board als Programmierer verwenden (siehe Arduino-ISP2 im früheren Post) und dann noch die passenden Definitionen der Chips ins IDE einbauen.

Fangen wir mit dem einfachen Teil an: Die Verkabelung läuft eigentlich genauso wie im vorangegangenen Post zum ATMega beschrieben. Hier dennoch ein paar Bilder, reine Fleissarbeit, aber wenns mal schnell gehen soll, vermeidet man so vielleicht Probleme.


ATtiny85 verkabeln:

Hier sind noch zwei alternative Anleitungen (inkl. Setup mit 10uF Kondensator statt den Widerständen)


ATtiny44 verkabeln:

..

ATtiny2313 verkabeln:


..

Sicherheitshalber nochmal die Pinouts, um SCK, MISO,MOSI,Reset,Clock und die Stromversorgung richtig an den Chip anzulegen:
 

Natürlich ginge es auch mit ASCII-Art - das nächste Mal vielleicht :-)

// ATMEL ATTINY2313
//
//                  +-\/-+
//            PA2  1|    |20  VCC
// RX   (D 0) PD0  2|    |19  PB7 (D 16)
// TX   (D 1) PD1  3|    |18  PB6 (D 15)
//      (D 2) PA1  4|    |17  PB5 (D 14)
//      (D 3) PA0  5|    |16  PB4 (D 13)*
// INT0 (D 4) PD2  6|    |15  PB3 (D 12)*
// INT1 (D 5) PD3  7|    |14  PB2 (D 11)*
//      (D 6) PD4  8|    |13  PB1 (D 10)
//     *(D 7) PD5  9|    |12  PB0 (D 9)
//            GND 10|    |11  PD6 (D 8)
//                  +----+
//
// * indicates PWM port


----------------  2313 --------

RST -        - VCC
 P0 -        - P16
 P1 -        - P15
 P2 -        - P14
 P3 -        - P13*
 P4 -        - P12*
 P5 -        - P11*
 P6 -        - P10
*P7 -        - P9
GND -        - P8


Stared pins (7, 11, 12, 13) are PWM pins.



Einen schönen Überblick als Din-A4 Referenzblatt mit allen gängigen Pinouts habe ich hier gefunden: http://electronicavm.files.wordpress.com/2012/06/microcontroller-reference-sheet-a4.png


Arduino IDE Vorbereiten

Um Programme für die ATtiny Chips zu programmieren, muss man entsprechende Board-Beschreibungen und Core-Definitionen im IDE hinterlegen. Ich habe zwei Pakete ausprobiert, die sich auch parallel installieren lassen:
1.) "attiny" (wird nach "arduino-1.0.3\hardware\attiny" installiert):
 ATtiny (siehe GitHub repository, beschrieben in: "Programming an ATtiny w/ Arduino 1.0",
2.) "arduino-tiny" (wird nach "arduino-1.0.3\hardware\tiny" installiert  - nur tiny-Ordner entpacken):

http://code.google.com/p/arduino-tiny/


Zu 1: Es existieren einige Forks zu dem Projekt. Ich habe einen gewählt, der auch mit dem ATtiny2313 funktioniert:  https://github.com/fschaefer/attiny/archive/master.zip
Einen kleinen Fix muss man noch von Hand nachführen: https://github.com/damellis/attiny/issues/8

High Low Tech hat auch noch eine schöne Beschreibung und einen Überblick:
http://hlt.media.mit.edu/?p=1229  (inkl. LED Beschaltung)

Wichtig: nicht vergessen, das IDE neu zu starten, nachdem man die Hardware-Pakete oben ergänzt hat, damit die zusätzlichen Boards in der Auswahlliste auftauchen.

Zum Laden eines Programmes dann den entsprechenden Chip auswählen und erst den "Bootloader" programmieren (setzt nur die Fuses), dann das Programm kompilieren und hochladen:
["ArduinoISP" Programm auf das Board geladen?]Board:  ATtiny85 (internal 8Mhz clock)Port:  COMProgrammer: Arduino as ISP
Wenn man in der Auswahlliste der Boards zu viele Einträge hat, kann man die "boards.txt" Dateien in den Unterordnern von arduino-1.0.3\hardware\* etwas entrümpeln. Insbesondere kann man sich alle Einträge mit externer Clock sparen.

Für einen ersten Versuch eignet sich das Demo-Programm "Blink":
  • Den Pin im Programm entsprechend anpassen (z.B. Pin 0).
  • Eine LED mit einem 1k Ohm Vorwiderstand an den Pin anschliessen
  • Programm kompilieren und auf den Chip laden.

Die Led sollte nach dem Hochladen zu blinken beginnen.

Bei einem ersten Versuch hatte ich ein sehr langsames Blinken - delay(1000) sollte im Sekundentakt blinken - Irgendwie lief es nach dem 2. Flashen besser.
Eine mögliche Erklärung: Die Definitionen in boards.txt und in den Definitionen enthalten Angaben zum Takt und zum Timing (Einfluss der Fuses?). Kann durchaus sein, dass ein Programm, das für ein 8 Mhz "Board" kompiliert wurde, anders als gedacht läuft, wenn man die Fuses für den 1Mhz Boardeintrag gesetzt hatte.

Troubleshooting

ATtiny85: Wenn es beim Programmieren zu einer Fehlermeldung kommt:
avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85
avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85


Ignorieren!

ATtiny2313: Hier funktioniert das "Brennen" des Bootloaders (d.h. letztlich nur das Setzen der Fuses) problemlos. Beim Programm-Upload mit dem Arduino-ISP2 hab ich dann lange versucht einen Fehler zu beheben, der anscheinend gar keiner ist. Die Fehlermeldung
Binary sketch size: 912 bytes (of a 2,048 byte maximum)
avrdude: stk500_initialize(): programmer not in sync, resp=0x15

kann man getrost IGNORIEREN.




Weitere Troubleshooting-Quellen:
Baud-Rate fix für die ISP Programmierung der ATtiny Chips:  http://www.sirmc.net/view/2002/

Referenzen und Ideen für künftige Projekte:

Infos und Tipss zum 2313 (Pinouts, Bootloader, etc.): http://www.ernstc.dk/arduino/2313.htm

Falls es doch ein Bootloader für die ATtiny Serie sein darf:
Den ATtiny85 als USB Gadget verwenden:
...braucht dann allerdings wohl doch einen externen 12 Mhz Quartz als Taktgeber für das USB-timing.

Konkreter Einsatz (lässt sich aber auch für wenige EUR fertig kaufen):


2013-01-11

ArduinoISP - AVR Chips programmieren

Ich wollte erst mal klein anfangen und schauen, ob die zusätzlichen Mikrocontroller, die ich bestellt habe auch funktionieren. Dazu reicht mir ein "Hello World", sprich das minimale "Blink"-Programm des Arduino IDE (übrigens: 1.0.3), um eine LED dann zum Blinken zu bringen.
Zusätzliche Elemente, wie z.B. einen Quartz wollte ich mir nach Möglichkeit ersparen.

Arduino als ISP (und als "Taktgeber"!)
Doch zunächst muss man die Chips zum Programmieren vorbereiten und einen ISP-Programmer (In-System-Programmer) braucht es auch noch.
Ersteren erhält man, in dem man das existierende Arduino-Board (UNO, Duemilanove, etc.) als Programmiergerät verwendet.
Beschrieben wird dies im Detail hier: http://arduino.cc/en/Tutorial/ArduinoISP

Es wird ein entsprechendes Programm "ArduinoISP" auf das Board geladen und danach verhält sich das Board gegenüber dem Arduino IDE bzw. avrdude wie ein Programmiergerät (genauer: "stk500"), so lange, bis man ein anderes Programm läd, also Vorsicht bei den folgenden Uploads :-)

Verfeinerung: Ich will es gleich vorweg nehmen, nicht alle Versuche waren sofort erfolgreich. 
Um sich den Ärger gleich zu sparen, nimmt man am Besten gleich die Weiterentwicklung des ArduinoISP, den ArduinoISP2


“This is a fork of Adafruit's ArduinoISP which is a fork of Arduino's ArduinoISP which adds an 8 MHZ 'crystal' output on pin #9 so you don't need an extra oscillator/crystal. Can also rescue some bricked chips with bad oscillator fuses”

Diese Version ist von der, die beim IDE mitgeliefert ist kaum zu unterscheiden (vermutlich ist es auch nur eine Frage der Zeit). Bis dahin: Wenn man im passenden Sourcecode nachschaut, sollte man diese Zeilen finden:
  // setup high freq PWM on pin 9 (timer 1) 
// 50% duty cycle -> 8 MHz
Dies ist extrem nützlich. Hat man nämlich beim Experimentieren einen Chip auf einen externen Taktgeber eingestellt (ggf. ist dies sogar die Werkseinstellung?), müsste man zum Programmieren im Setup eben auch wie im Tutorial ersichtlich einen Quartz und zwei Kondensatoren verbauen.
Denn sobald beim Initialisieren der Chips die sogenannten "Fuse-Bits" gesetzt werden und diese neben der Taktfrequenz auch die Verwendung eines externer Taktgeber definieren, reagiert der Chip nicht mehr ohne auf weitere Programmierversuche.

Die Spezialversion des ArduinoISP liefert immerhin einen 8Mhz Taktgenerator, der dieses Problem elegant umschifft (Pin 9 des Arduino Boards an XTAL1 des Chips anlegen).
Selbst wenn der Chip für 16Mhz konfiguriert wurde, sollte dies funktionieren.
Sonst gibt es hier noch eine nette Abhandlung zu den "Fuses" und zum Troubleshooting (wie man Chips retten kann, die man falsch programmiert hat): http://www.gammon.com.au/forum/?id=11643
Die offizielle Troubleshooting-Seite des Arduino hat mir bislang noch wenig geholfen.


When you buy a brand new, blank ATmega328p, it comes with a set of fuses (basically hardware settings) which give it maximum reliability, but they aren't the default that is required for the chip to work with the Arduino IDE and libraries.  In order to burn the correct fuses onto it, run the following command (this assumes that you're using Arduino-as-ISP on COM4);


avrdude -pm328p -cstk500v1 -b19200 -PCOM4 -v -C ..\etc\avrdude.conf -U lfuse:w:0xFF:m -U hfuse:w:0xD6:m -U efuse:w:0x05:m -B250

Diese Zeile dient nur zur Illustration. Man kann im IDE unter Einstellungen den Upload ausführlicher ausgeben lassen. Dann erhält man auch die avrdude Kommandozeile. Der -B Parameter passt das Timing beim Programmieren an. Ggf. ein Tipp, der hilft, wenn alles verloren scheint. Oder eben doch ein Setup mit externen Quartz?

Aber damit genug zum Exkurs. Im Folgenden setze ich den ArduinoISP2 einfach voraus :-)
So kompliziert ist es gar nicht. Der erste Versuch war eben etwas steinig. Bis es lief - daher diese Tipps zuerst - damit ich mich beim nächsten Mal darauf stützen kann, wenn es klemmt.


Verkabelung - Ready to Program:

Auch hier wieder nur eine kleine Zusammenfassung der zahlreichen Versuche und Tipps, die ich ausprobiert habe, bis es klappte (habs gerade neu gezeichnet):

Das Bild sollte an sich eine gute Referenz sein und selbsterklärend (beim Verkabeln besser doppelt prüfen, dass man den richtigen Pin erwischt hat!).
Das macht übrigens richtig Spass mit dem Experimentierboard und ein paar vorkonfigurierten "Strippen", die sich leicht stecken lassen. Einen extra Programmer brauche ich vorerst nicht.

Neben dem zusätzlichen Clock-Signal von Pin D9 des Boards an XTAL1, muss man beim Thema Reset ggf. noch etwas nachbessern:

Slave-Chip (der zu programmierende Chip auf dem Experimentierboard):
Der Reset-Pin (Chip Pin 1?) kann optional mit einem Pull-Up Widerstand (1kOhm; braun-schwarz-rot-gold) an die Versorgungsspannung geführt werden.


Damit das Arduino-Board selbst nicht während dem Programmieren resettet wird (durch seine USB bzw. Serielle Verbindung), muss man dies ggf. unterbinden:
Beim UNO wohl durch einen 10 µF Kondensator (ELKO), dessen Minus-Pol an GND geht, die Plus-Seite an den Reset-Pin des Boards.
Ich habe beim Arduino Duemilanove stattdessen mit einem 110 Ohm Pullup Erfolg gehabt (aus 2 parallelen 220Ohm Widerständen.
!!! Diese Schaltung wieder entfernen, wenn man ein neues Programm auf das Board selbst laden will !!!

Wie gesagt: Bin mir nicht ganz sicher, welche davon es am Ende effektiv gebraucht hat. Der 1k Pullup am Slave-Chip war eher nicht erforderlich.

Bootloader Programmieren:
Letztlich ist dies nun gaaanz einfach: Man wählt im IDE die entsprechenden Einstellungen:

["ArduinoISP" Programm auf das Board geladen?]
Board:  "Arduino Duemilanove w/ ATmega328 - Optiboot" [siehe unten]
Port:  COM
Programmer: Arduino as ISP


Dann "Bootloader installieren" wählen und der Ausgabe gebannt folgen :-)

Warnung: Die Einstellung von "Board" ist hier extrem heikel! Sie bestimmt nun das Target-Board NICHT der Programmierer (der wird durch COM-Port und "Arduino as ISP" hinreichend beschrieben).
Beim "Board" sollte man aufpassen. Es steuert nicht nur, für welchen Target-Prozessor die Programme compiliert werden (insbes. Pins und Taktfrequenz), sondern auch, welche Fuses gesetzt werden und welcher Bootloader gebrannt wird.
Hier schliesst sich der Kreis: Wenn man hier daneben liegt, hilft der Trick mit dem Taktgeber oben hoffentlich weiter :-)

Arduino Duemilanove updaten:

Der Duemilanove ist fast baugleich mit dem UNO, insbesondere neuere Fassungen des Duemilanove haben einen ATMega 328 (statt 168). Der Bootloader des UNO ist allerdings etwas schlanker und schneller (Stichwort "Optiboot"):

Upgrade your Arduino for free with Optiboot   http://code.google.com/p/optiboot/Optiboot is an easy to install upgrade to the Arduino bootloader within Arduino boards. It provides the following features:
  • Allows larger sketches. Optiboot is a quarter of the size of the default bootloader, freeing 1.5k of extra space.
  • Makes your sketches upload faster. Optiboot operates at higher baud rates and has streamlined programming.
  • Adaboot performance improvements. Optiboot runs your sketches sooner, with no watchdog issues.
  • Compatible with 168 and 328 Arduinos including Lilypad, Pro, Nano
Die Idee für den Upgrade hatten schon andere vor mir:

Es passt hier aber eben gut her, deshalb kurz zusammengefasst:
Man könnte einfach den Board-Eintrag für das UNO nehmen. Ich habe mich entschieden, den Eintrag für das Duemilanove mit Optiboot zu ergänzen:

In der Datei arduino-1.0.3\hardware\arduino\boards.txt wird folgender Eintrag ergänzt:

##############################################################

Duemilanove.name=Arduino Duemilanove w/ ATmega328 - Optiboot

Duemilanove.upload.protocol=arduino
Duemilanove.upload.maximum_size=32256
Duemilanove.upload.speed=115200

Duemilanove.bootloader.low_fuses=0xFF
Duemilanove.bootloader.high_fuses=0xDE
Duemilanove.bootloader.extended_fuses=0x05
Duemilanove.bootloader.path=optiboot
Duemilanove.bootloader.file=optiboot_atmega328.hex
Duemilanove.bootloader.unlock_bits=0x3F
Duemilanove.bootloader.lock_bits=0x0F
Duemilanove.build.mcu=atmega328p
Duemilanove.build.f_cpu=16000000L
Duemilanove.build.core=arduino
Duemilanove.build.variant=standard


Damit der Eintrag wirksam wird, muss man das IDE wie gewohnt neu starten.
Der Bootloader wird dann über ArduinoISP gebrannt, die Einträge "protocol" und "speed" beziehen sich auf die Uploads der Programme später im Betrieb.

Generell habe ich die Liste der angebotenen Boards etwas ausgedünnt. Im nächsten Post beschreibe ich, wie man zusätzliche Chips in die Liste der Boards aufnimmt. Spätestens dann wird es unübersichtlich :-)

Hier sieht man schon ein paar Teile für den nächsten Aufbau :-)




















Nach der erfolgreichen Programmierung des Bootloaders, kann man den neuen Chip in den Duemilanove einsetzen. Dazu vorsichtig den Original-Chip aus dem Sockel hebeln und den frisch programmierten Chip in die Fassung einbauen. Dann mal ein Beispielprogramm laden, z.B. "ArduinoISP2".[Die Autoreset-Schaltung nicht vergessen - die müsste man nun abklemmen!!]
Der ausgebaute ATMega 328 kann dann sogleich auch einen Optiboot erhalten. Im schlimmsten Fall ist er so ein prima Ersatzchip sowohl für einen UNO als auch für den Duemilanove, wenn doch mal was beim Verkabeln schief geht.


Ein paar Extras

Nick Gammon hat ein paar interessante Programme ("Sketches") im Zusammenhang mit der AVR Programmierung zur Verfügung gestellt: https://github.com/nickgammon/arduino_sketches/archive/master.zip

http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123
http://www.gammon.com.au/forum/?id=11637
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=11635


Insbesondere diese zwei:
  • Atmega_Board_Detector - Liest ein paar Infos des angeschlossenen Chips aus, Typ, gesetzte Fuse-Bits, Bootloader,etc. 
  • Atmega_Board_Programmer - Damit wird das Arduino Board zum unabhängigen Programmer - er erkennt den angeschlossenen Chip und installiert einen Bootloader - Massenprogrammierung nach einem Grosseinkauf?

Für künftige Spezialfälle: Web-based fuse calculator http://www.engbedded.com/fusecalc

Noch zwei:

TinyDebugKnockBang - Serial like debugging for processors with an   uncalibrated / inaccurate clock.


  TinyISP 1.0 - Turn an ATmega328[P] Arduino compatible board (like an Uno) or
  a Teensy into an In System Programmer (ISP).  Based on MegaISP and
  ArduinoISP.