budo's Web
Hier findet ihr einiges zu meinen Hobbies

Eieruhr oder wie man einen neuen Chip in Arduino einbindet

Bei meinen Tests der Terrarien-Schaltzeiten ist mir das Thema Kurzzeitwecker eingefallen, da ich die Kontrollzeiten immer wieder vergessen habe. Der erste Gedanke war ein eine "Eieruhr" basierend auf einem budoini (ATtiny 45 oder 85) mit einem Widerstandsnetzwerk zur Erzeugung einer analogen Spannung anhand von DIL-Schalter Einstellungen, die man dann per ADW misst. Für ein so genanntes R2R Netzwerk benötigt man aber Umschalter, um die Widerstände einmal gegen Masse und das andere mal gegen VCC zu schalten. Da ich aber DIL-Schalter benutzen wollte ist ein Treiber IC erforderlich. Hieraus ergibt sich eine Schaltung mit 8-pol. ATtiny, ca. 20 pol. Treiber, DIL-Schalter, 16 Widerstände für das R2R Netzwerk und eines Spannungsreglers (wegen der ADW Messung).

Stromlaufplan basierend auf ATtiny

str

Kurzzeitwecker basierend auf budoini (ATtiny85)

Meine ursprüngliche Ablehnung einen ATmega zu verwenden, hat sich bei der obigen Betrachtung verflüchtigt. Da mir ein ATmega 328 hierfür zu schade ist, dachte ich an einen ATmega48, da ich ein solches Exemplar in meinem Bastelkiste gefunden habe. Dabei könnte man gleich noch das Thema "Einbindung eines neuen Chips in die Arduino Software Umgebung" dazu fügen, da eine "Eieruhr" ja an sich nicht besonders erwähnenswert ist. Eine entsprechende Schaltung ergibt im Vergleich zu obiger Schaltung einen 28 pol. ATmega mit DIL-Schalter. Der Spannungsregler entfällt, da die ADW entfällt.

bei beiden Versionen wurde auf jeglichen Komfort verzichtet. Die Bedienung ist rein binär.

Stromlaufplan basierend auf ATmega

str

Kurzzeitwecker basierend auf budoini (ATmega48)

Ein ATmega48 ist der kleine Bruder vom ATmega328 mit einem deutlich kleineren Speicher (4k anstelle 32k Flash, 0,5k anstelle 2k SRAM, 256 anstelle 102 Byte EEPROM) und fehlendem Self Program Memory, was heißt, dass der ATmega48 keinen separaten Boot Loader Bereich hat.

Zur Einbindung eines neuen Chip in die Arduino Programmierumgebung ist ein Eintrag in der Datei board.txt im Arduino Programmverzeichnis im Subdirectory hardware/arduino/ erforderlich. Der Eintag für den UNO im board.txt ist wie folgt:

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

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard

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

Für den ATmega48 ändern wir alle "uno/Atmega328" in Atmega48 und den Namen machen wir eindeutig, in dem wir den Chip, die Frequenz und den Uploadmechanismus angeben. Der Upload soll per Diamex Programmer (AVRISP mkII kompatibel) erfolgen. Als Quarz habe ich einen exotischen 6,5536 MHz Quarz ausgesucht, weil er einerseits in meiner Bastelkiste war und andererseits einen deutlichen Unterschied zu den üblichen 16 MHz Quarzen darstellt, da ich die Auswirkung auf delay und baudrate später messen möchte. Passend hierzu ändern wir das upload.protocol von arduino (d.h. per bootloader) in avrispv2 und die Frequenz f:cpu auf 6553600L. Die Bootloaderdatei-Zeilen kommentieren wir mit einem '#' aus. Die Baudrate setzen wir auf einen moderaten Wert von 19200, da wir erst die Auswirkung vermessen müssen. Maximum_size wird auf den gesamten Flashbereich des ATmega48 gesetzt, da ja kein Bootloaderbereich abgeogen werden muss. Der in die board.txt Datei einzubindende Text sieht dann wie folgt aus:

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

Atmega48.name=ATmega48 (6.5536MHz) w/Diamex
Atmega48.upload.protocol=avrispv2
Atmega48.upload.maximum_size=4094
Atmega48.upload.speed=19200
# Atmega48.bootloader.path=optiboot
# Atmega48.bootloader.file=optiboot_atmega328.hex
Atmega48.build.mcu=atmega48
Atmega48.build.f_cpu=6553600L
Atmega48.build.core=arduino
Atmega48.build.variant=standard

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

Jetzt fehlen nur noch die fuse bits und die lock bits, für deren Definition wir das Datenblatt zur Hand nehmen müssen.

Die Fuse Bits für den ATmega48 beinhalten folgende Bits:

Extended Fuse Byte: SelfPRGEN
High Fuse Byte: RSTDISBL, DWEN, SPIEN, WDTON, EESAVE und BODLEVEL2..0
Low Fuse Byte: CKDIV8, CKOUT, SUT1..0 und CKSEL3..0

Die Bits ClockSelect (CKSEL3..0) und StartUpTime (SUT1..0) werden durch den Oscillator bestimmt. Aufgrund des gewählten 6,5536 MHz Quarzes ergibt sich ein Frequenzband von 3-8 MHz ein von CKSEL3..1=110 und für eine ausgeschaltete Brown-out Detection und einen langsamen Spannungsanstieg ein CKSEL0=1 / SUT1..0=11. Der Frequenzteiler wird über CKDIV8=1 abgeschaltet und die Clock Ausgabe am CLKO Pin wird über CKOUT=1 ebenfalls abgeschaltet. Die High Fuse Bits werden wie folgt gesetzt: RSTDISBL=1 (NOT External Reset Disable), DWEN=1 (NOT debugWire Enable), SPIEN=0 (Enable Serial Program and Data Downloading), WDTON=1 (NOT Watchdog Timer Always On), EESAVE=1 (NOT EEPROM memory is preserved through the chip erase) und BODLEVEL2..0=111 (BOD disabled). Das Extended Fuse Bit SELFPRGEN wird nicht benötigt, dh. SELFPRGEN=1

Die Lock Bits für den ATmega48 beinhalten folgende Bits:

Lock bit Byte: LB2 und LB1

Mit LB1..0=11 wird der Lock Bit Modus 1 "No memory lock features enabled" ausgewählt.

Zusammengefasst werden die Fuse und Lockbits wie folght gesetzt:
Low Fuse Byte = 0xFD
High Fuse Byte = 0xDF
Ext. Fuse Byte = 0xFF
Lock Bit Byte = 0xFF (oder unlock_bits=0x3F und lock_bits=0x0F).
Der in die board.txt Datei einzubindende Text sieht dann endgültig wie folgt aus:

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

Atmega48.name=ATmega48 (6.5536MHz) w/Diamex
Atmega48.upload.protocol=avrispv2
Atmega48.upload.maximum_size=4094
Atmega48.upload.speed=19200
Atmega48.bootloader.low_fuses=0xfd
Atmega48.bootloader.high_fuses=0xdf
Atmega48.bootloader.extended_fuses=0xff
# Atmega48.bootloader.path=optiboot
# Atmega48.bootloader.file=optiboot_atmega328.hex
Atmega48.bootloader.unlock_bits=0x3F
Atmega48.bootloader.lock_bits=0x0F
Atmega48.build.mcu=atmega48
Atmega48.build.f_cpu=6553600L
Atmega48.build.core=arduino
Atmega48.build.variant=standard

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

Beim Setzen der Fuse Bits per Arduino (via Bootloader installieren bei ausgewähltem ATmega48 Board) gab es dann eine Überraschung mit folgender Fehlermeldung:

bl

Fehlermeldung

Eine Internet Recherche brachte als Ergebnis, dass die Anwendung von AVRDUDE aus Arduino heraus nicht stimmig ist. AVRDUDE prüft den Speicher ab und setzt hierfür ein vorheriges Löschen des Speichers voraus, Arduino führt allerdings kein Löschen durch. D.h., unter Umständen kommt eben obige Fehlermeldung.

Ich habe dann via myAVR_ProgTool über meinen Programmer (Diamex) die Fuse und Lock Bits gelesen und dann mit den Werten obiger board.txt Tabelle programmiert und verifiziert. Das hat wunderbar funktioniert. Ein anschließender Upload Test via Programmer eines LED-Blink-Programmes aus Arduino heraus, hat dann auch funktioniert, so dass ich mit meinen geplanten Test (siehe unten) weiter machen konnte.

Bilder

tuzu

Eieruhr, Platine, mit Quarz auf separatem Träger zum schnelleren Austausch

ATmega48 spezifische Tests

Bei Arduino sollen die Funktionen wie delay() und die baudrate bei Serial.begin in Abhängigkeit des board.txt gleich bleibend funktionieren. Für die Funktion microSeconds() ist das nicht so. Das Ziel nach folgender Messungen ist diese Definitionen messtechnisch zu kontrollieren. Zusätzlich soll der Einfluss der Versorgungsspannungsänderung auf die Taktfrequenz bei Schaltungen ohne Spannungsregler gemessen werden. Die Funktionen von Arduino "Upload" und Upload mit Programmer" bezogen auf den neuen board.txt Eintrag soll ebenso kontrolliert werden. Die Zeit-Messungen erfolgen mit einem 100MHz Logic Analyzer.

ACHTUNG: Beim Anlegen von Signalen an den Pins, z.B. über den USB Serial Light Adapter, den SPI, oder sonstige Signale, ist darauf zu achten, dass der Pegel nicht größer als VCC +0,5V ist. D.h., Während den Messungen und sonstigen Ahtivitäten sollte VCC +5V sein. Den Batteriebetrieb mit kleiner Spannung sollte man nur während des Betriebs als Kurzzeitwecker nutzen.

clko

Clock-Messung am CLKO-Ausgang. Gemessen wurde eine Frequenz von 6,67MHz. Dies entspricht einer Abweichung von 1,8%, und ist somit innerhalb der Toleranz des Quarzes, der abhängig ist von Spannung und Temperatur.


del

Delay-Messung eines 100ms High-Impulses. Gemessen wurde eine Zeit von 97,68ms. Dies entspricht einer Abweichung von 2,3%, und ist somit innerhalb der Toleranz des Quarzes, der abhängig ist von Spannung und Temperatur.


delu

DelayMicrosseconds-Messung eines 1ms High-Impulses. Gemessen wurde eine Zeit von 1,26ms. Dies entspricht in etwa dem Verhältnis (1,22) der ATmega default Frequenz von 8MHz zur verwendeten 6,5536Mhz.


br

Baudrate-Messung mit Serial.print mit einer Baudrate von 9600 Baud. Gemessen wurden 104μs. 9600 Baud entsprechen 1s / 9600 = 104,2μs und passt zur Messung.


Funktion Upload & Upload mit Programmer: Der Upload funktioniert nur mit "Upload mit Programmer". Beim normalen "Upload" reklamiert Arduino, dass er den seriellen Port nicht findet. Kommentiert man im board.txt die upload.speed aus, die auf die serielle Schnittstelle deutet, so kommt zwar keine Fehlermeldung mehr, aber funktionieren tut der Upload so trotzdem nicht.

Fazit: Die Messungen bestätigen die Aussage, dass delay und baudrate über die board.txt Einträge an den jeweiligen Chip angepasst werden. DelayMicroseconds wird nicht angepasst, kann aber mit dem Faktor (Default-Freqenz / verwendete Frequenz) angepasst werden, in dem man den Einstellwert durch den Faktor teilt.

Die Messung von CLKO in Abhängigkeit der Versorgungsspannung brachte keinen nennenswerten Freuenzunterschied bei einer Spannungsänderung von 5V auf 3,5V. D.h., beim Einsatz als Kurzzeitwecker muss kein Delay in Abhängigkeit der Versorgungsspannung eingestellt werden. Zur Messung wurde CLKO über einen Transistor mit externer Stromversorgung entkoppelt, um die Pegelanpassung zwischen Prüfling und Logic Analyzer zu erreichen.

Nachtrag

Bei der Verwendung von Chip-Varianten, wie z.B. einem ATmega168PA anstatt dem üblichen ATmega168 meldet der AVRDUDE beim Bootloaden, das der erwartete Chip Code nicht stimmt. Für einen ATmaga168 oder 168A erwartet AVRDUDE 1E9406, ein ATmega168P oder 168PA liefert aber 1E940B. Hierzu muss man wie oben beschrieben ein neues board anlegen oder ein existierendes board ändern bezüglich xxx.build.mcu=atmega168 nach xxx.build.mcu=atmega168p, da der AVRDUDE den 168p schon implementiert hat.


Nach Oben