Attiny13-ElbugVersion 3


von Ralf Beesner, DK5BU
Elektronik-Labor   Projekte   AVR 




Mit einem kleinen 8-poligen Attiny 13, der ca. 1 Euro kostet, wenigen zusätzlichen Bauteilen und etwas Basic (Bascom-AVR; es reicht die kostenlose Demo-Version) lässt sich recht einfach eine elektronische Morsetaste realisieren.

Sie erzeugt kurze und lange Morsezeichen automatisch (Punkte und Striche; ein Strich ist drei mal so lang wie ein Punkt). Die Zeichen werden mit einem Bedienhebel erzeugt, tippt man ihn rechts an, wird ein langes Zeichen plus normgerechter Pause erzeugt; tippt man links, ein kurzes Zeichen plus Pause. Es gibt auch "Squeeze"- Tasten, sie haben zwei Hebel; drückt man beide, wird eine alternierende Folge von kurzen und langen Zeichen erzeugt; so kann man komplexe Zeichen mit wenigen Tastbewegungen "zusammensetzen".

Auf dem Bild sieht man eine leichtgewichtige Portabel-Gebemechanik (ein Kontaktsatz aus einem Spezialrelais) und das aufgeklappte Gehäuse (in der oberen Halbschale die Elektronik, in der unteren ein 80-mAh-Akku mit 3 Zellen und die Steckverbinder).

Auf Kurzwelle muss man manchmal lange herumrufen, um einen Funkpartner zu finden. Daher ist ein Speicher mit einem (fest programmierten) Ruftext hilfreich; er wird mit dem kleinen Taster neben dem Drehknopf gestartet und durch Antippen des Punkthebels gestoppt.

Bei den Versionen 1 und 2 des Attiny- Elbugs, die auf www.elo-web.de unter der Rubrik "Mikrocontroller/Bascom" zu finden sind, hatte ich das Aufwecken des Microcontrollers aus dem Tiefschlafmodus auf eher ungeschickte Weise gelöst. Beim Atmega8, mit dem ich die ersten Programmierversuche unternommen hatte, geht das nur über die Interrupt- Pins INT0 und INT1,  neuere Prozessoren (auch der Attiny 13) lassen sich eleganter mit Pin Change Interrupts (die für fast alle I-O-Pins verfügbar sind), aufwecken.

Version 3 nutzt daher Pin Change Interrupts; dadurch wird einer der knappen I-O-Pins frei, so dass nun Mithörton und Sender- Schalttransistor auf separate Pins gelegt werden konnten.




Der Elbug soll ständig an der Batterie verbleiben und möglichst wenig Strom verbrauchen, wenn er nicht genutzt wird. Eine so geringe Energieaufnahme erfordert den Power-Down-Modus, in dem jedoch der  Taktoszillator abgeschaltet wird und der Mikrocontroller nur durch den externen Interrupt INT0 und die Pin Change Interrupts geweckt werden kann.

Punkt- und Strich- Eingang ("Dit" und "Dah") liegen an PB3 und PB2. Die Eingänge werden über interne Pullup- Widerstände des Microcontrollers auf Plus gezogen und sind gegen HF- Einstrahlung mit 3,3 nF abgeblockt. Punkt- und Strichtaster schalten gegen Masse und ziehen den jeweiligen Eingang auf "Low", wenn sie gedrückt werden.

Die Morsegeschwindigkeit wird durch den AD-Wandler vorgegeben. Ein Potentiometer an PB4 bestimmt die Zeitkonstante. Man kann den Einstellbereich per Software oder per Hardware festlegen. Wegen des Stromverbrauchs ist ein Poti mit 470 kOhm oder 1 MOhm (log.) günstig; da ich nur ein Potentiometer mit 100 kOhm (log.) hatte, habe ich beides gemacht: in Reihe mit dem Poti habe ich einen Festwiderstand mit 560 kOhm gelegt und zum ausgelesenen Wert jeweils 32 addiert. Der AD-Wandler löst 10 bit auf (0...1023). Verwendet man ein 1-MOhm-Poti, muss man sich den Einstellbereich per Software "zurechtbiegen"

PB0 ist als Ton-Ausgang konfiguriert. Bei richtiger Wahl der Timer- Parameter ergibt sich ein hörbarer Ton, den man durch Umprogrammierung des Datenrichtungs-Registerbits DDRB.0 ein- und ausschalten kann. Die NF treibt einen Piezo-Summer (Buzzer); die Lautstärke ist mit dem Trimmer R2 einstellbar.

Das Schaltsignal für den Sender liegt an PB1, ein BC548 fungiert als (invertierender)  Schalttransistor. An "TX" liegt also das Schaltsignal für den Telegrafieeingang eines Senders. Da für den Abruf des Speichertextes kein Pin mehr frei ist, muss der Reset-Pin herhalten; durch Drücken von S1 wird ein Reset ausgelöst.

Als Energieversorgung ist eine Lithium-Primärzelle im Mignon-Format vorgesehen (erhältlich z.B. bei Reichelt; ca. 4 EURO). Sie liefert 3,6 Volt und sollte den Ruhestrom für die Schaltung (ca. 25 µA) jahrelang liefern können. Man kann auch 3 Mignonzellen oder einen kleinen 3-Zellen-NiMH-Akku 3,6V / 80 mAh verwenden (bei Reichelt unter 3 EURO). Sicherung nicht vergessen!

Da die Schaltung nur aus wenigen Bauteilen besteht, kann man sie leicht auf einem Stück Streifenleitungsplatine aufbauen, sie ist so klein, dass man sie im Gehäuse per Einlochbefestigung des Potis fixieren kann. Lediglich die Batterie ist separat unterzubringen.




Erläuterungen zur Software

Die Software ist in Basic geschrieben (Bascom-AVR - www.mcselec.com). Zunächst werden die Variablen definiert und die Hardware- Register des Attiny konfiguriert. Da der Reset-Pin als Speicher-Abruf- Taste fungiert, wird nach einem Reset als erstes der Speichertext ausgegeben. Unterbrechen kann man ihn durch Antippen der Punkt-Taste, dann verzweigt das Programm in den Keyer-Betrieb (Unterprogramm Keyer). Der Speichertext "steckt" in den Data-Zeilen am Ende des Programms. Die Codierung der Zeichen ist im Kommentarbereich des Quelltextes genauer beschrieben.

Ist keine Taste gedrückt, durchläuft das Programm einmal die Do-Schleife bis zum Befehl "Powerdown". Er stoppt fast die gesamte Hardware. Der Controller reagiert nur noch auf Potentialwechsel an den beiden zuvor definierten PCINT- Eingängen PB3 und PB2, an die der Punkt- und der Strich- Taster angeschlossen sind.

Drückt man einen der beiden, wacht der Controller auf, springt den auf "Powerdown" folgenden Befehl an ("Loop") und beginnt die Do-Schleife aufs neue. Da jedoch PB2 und/oder PB3 auf "Low"  gezogen wurden, verzweigt das Programm in den IF-EndIf-Schleifen; es laufen dann die Wait-Befehle und Umschaltbefehle für das Datenrichtungsregister ab, die den Ton durchschalten oder blocken und den TX-Pin umschalten.

Die If-EndIf-Schleife für die Morsestriche ist umfangreicher, weil hier auch abgefragt wird, ob zusätzlich auch der Morsepunkt-Hebel gedrückt wurde; dann wird eine Folge von abwechselnden Strich-Punkt- Signalen erzeugt (Sqeeze-Modus) bzw. ein rudimentärer Punktspeicher bei Einhebel-Tasten realisiert. Im Quelltext sind weitere Kommentare zu den einzelnen Befehlen angefügt.



Flashen des Attiny13

Zunächst muss der Speichertext auf die eigenen Verhältnisse angepasst und mit Bascom-AVR von MCS Electronis (www.mcselec.com) kompiliert werden. Das entstandene HEX- File kann mit einem beliebigen Programmer in den Chip übertragen werden. Da die Morsetaste aus dem Franzis-"Lernpaket Microcontroller" enstanden ist, bietet sich jedoch die  Hardware und Software des Lernpakets an. Das Lernpaket enthält ein sehr einfach gehaltenes Programm (LPMicroISP.exe), mit dem man Hexfiles über die serielle Schnittstelle eines PC in den Attiny13 flashen und die Taktrate des Attiny13 ändern kann. Es funktioniert auch mit USB-Seriell-Wandlern; die Übertragung ist dann allerdings sehr langsam. LPMicroISP.exe ist ein reiner Programmer, der den Code im robusten ISP-Modus in den Microcontroller überträgt.

Auf der Website des Autors gibt es ein Update des Programms unter "www.b-kainka.de/LPmicrosUpdate.zip". Es enthält zwei exe-Files; das zweite Programm LPMicros.exe ist auf die Experimente des Lernpakets zugeschnitten und für das reine Programmieren eines Attiny13 weniger geeignet. Man kann zum Programmieren die Original- Hardware verwenden oder eine weiter vereinfachte Schaltung mit nur 8 Bauteilen, die sich ebenfalls problemlos auf einem Stück Streifenleitungsplatine aufbauen läßt.

Ab Werk werden die Attiny13 mit einem Takt von 9,6 MHz und Vorteilerfaktor 8 ausgeliefert, also 1,2 MHz. Die Fusebits des Attiny13 brauchen daher nicht umprogrammiert zu werden. Möchte man die Taktrate ändern (z.B. um den Stromverbrauch noch weiter zu drosseln), muss man die Variable  $crystal   und die Timerkonstanten (Tonhöhe) anpassen.

Download:
Bascom-Firmware  (update 19.3.13)
PDF-Version des Artikels


' Programm: Morsekeyer mit Textspeicher
'
' Sprache: Bascom-AVR-Basic
'
' Erläuterungen:
'
'
' Hardware:
'
' Tastkontakte für Punkt und Strich an PB3 und PB2.(Tastung gegen Masse).
' Tonausgang (Buzzer) an PB0.
' Schaltausgang an PB1.
' Poti zur Geschwindigkeitseinstellung an PB4
' (Spannungsteiler aus 560 kOhm und 100kOhm log. - Schleifer an PB4).
' Starten des Textspeicher- Auslesens durch Reset- Taster
'
'
' Software:
'
' Nach Reset wird der Textspeicher ausgelesen; nach Textende 5 sec. Wartezeit, dann
' Neustart des Auslesens.
' Unterbrechung durch Betätigen des Punkt- Tastkontakts, danach geht die Schaltung in den
' Gebemodus.
' Im Gebemodus geht der Prozessor in Powerdown, wenn kein Kontakt mehr gedrückt ist
' Aufwecken durch PinChange Interrupt
'
' Timer0 erzeugt den Mithörton. Pin PB0 wird als Timer0-Ausgang OC0A verwendet.
' ADC liest Gleichspannung an PB4, sie wird in die Punktdauer umgerechnet
'
'
' Codierung der Morsezeichen des Textspeichers:
'
' 1 Byte pro Zeichen, niederwertiges Bit zuerst.
' Hat das Bit den Wert 0: Morsepunkt (dit)
' Hat das Bit den Wert 1: Moersestrich (dah)
' Da Morsezeichen unterschiedlich lang sind, ist das Ende- Zeichen ebenfalls ein 1-Bit.
'
' Beispiel Morsezeichen "a" (dit dah): &B00000110
' Beispiel Morsezeichen "9" (dah dah dah dah dit): &B00101111

' Auslesen der codierten Zeichen:
' niederwertigstes Bit auslesen, Byte um 1 Stelle nach rechts schieben, niederwertigstes Bit
' auslesen. Ist der Wert des gesamten Bytes nur noch 1, ist das Zeichen komplett.
'
'
'
'
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Grundeinstelllungen:
$regfile = "ATtiny13.dat"
$crystal = 1200000 ' Taktfrequenz: 1,2 MHz
$hwstack = 8 ' Platz für nur 4 Unterprogramme reserviert, spart SRAM
$swstack = 0 ' wird nicht gebraucht
$framesize = 0 ' dito


'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Konstanten

Const Tonhoehe = 14 ' Tonhöhe

'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Variablen dimensionieren:

Dim I As Byte ' wird in Zählschleife verwendet
Dim N As Byte ' Aktueller Morsebuchstabe
Dim M As Byte ' wird fürs Auslesen der Morsebits verwendet
Dim L As Byte ' wird für niederwertigstes Bit von M verwendet
Dim Dit As Word ' Länge Punkt
Dim Dah As Word ' Länge Strich
Dim Wort As Word ' Länge Wortabstand
Dim P As Bit ' Punktspeicher


'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Initialisierung des Programms:
'

'On Int0 Ondit ' Interruptroutine bei Drücken von Punkt- oder Strichkontakt

Acsr.7 = 1 ' Analog-Komparator ausschalten, spart etwas Strom
Gimsk.5 = 1 ' Pin Change Interrupt Enable
Sreg.7 = 1 ' Global Interrupt Enable
Pcmsk.2 = 1 ' Pin Change Inerrupt PB2 aktivieren
Pcmsk.3 = 1 ' Pin Change Interrupt PB3 aktivieren
Ddrb = &B0000_0010 ' Pin PB1 als Ausgang konfigurieren (1), Rest ist Eingang (0)
Portb = &B0000_1100 ' PullUp-Widerstände für die Pins PB2 und PB3 aktivieren
'
'
' Morseton mit Timer0 erzeugen:

' Timer0 : Vorteilung(prescale) = 1 ; Bei Compare -match Toggle Pin Oc0a / Pb0
'
' Timer0 zählt das Register TCNT0 hoch. Es wird mit Register OCR0A verglichen.
' Wenn TCNT0 = OCR0A, wird Output OC0A/PB0 umgeschaltet (getoggled)
' Timer0 erzeugt so Dauerton; er wird jedoch nur an den Ausgangspin durchgeschaltet,
' wenn das Datenrichtungs- Register DDRB.0 = 1 ist. Bei 0 wird der Ton unterdrückt.

Config Timer0 = Counter , Prescale = 64 , Compare A = Toggle , Clear Timer = 1
Ocr0a = Tonhoehe

' AD- Konverter konfigurieren und erst mal starten
Config Adc = Single , Prescaler = Auto
Start Adc

'-------------------------------------------------------------------------------
' Hauptprogramm:



Speicher: ' Erst mal Speicher auslesen

Restore Message ' Data- Zeiger auf Datenfeld 1 setzen
For N = 1 To 128 ' Elemente des Datenfelds lesen (max. 128)
Gosub Adclesen ' Morsegeschwindigkeit abholen
Read M ' Zeichen aus Kette rauspicken
If M = 255 Then ' Ende- Zeichen
Wait 5 ' Speichertext zu Ende,etwas warten
Goto Speicher ' Speichertext erneut auslesen
End If
If Pinb.3 = 0 Then ' Abbruch, wenn Punkt- oder Strichhebel gedrückt
Waitms 500
Goto Keyer
End If
Gosub Morse ' Morsezeichen erzeugen
Next N


Keyer: ' hier beginnt der händische Tastenbetrieb

Do

Start Adc
Gosub Adclesen
If Pinb.3 = 0 Then ' Punktkontakt gedrückt
Ddrb.0 = 1 ' bei 1 wird Ausgang OC0A an Pin PB0 durchgeschaltet; Ton hörbar
Portb.1 = 1 ' Schaltausgang ein
Waitms Dit
Ddrb.0 = 0 ' bei 0 wird Tonsignal unterdrückt
Portb.1 = 0 ' Schaltausgang aus
Waitms Dit
End If

Mark:

If Pinb.2 = 0 Then ' Strichkontakt gedrückt
Ddrb.0 = 1 ' bei 1 wird Ausgang OC0A an Pin PB0 durchgeschaltet
Portb.1 = 1
Waitms Dah
If Pinb.3 = 0 Then ' Punktkontakt gedrückt
P = 1 ' Squeeze- bzw. Punktspeicher
End If
Ddrb.0 = 0 ' bei 0 wird Tonsignal unterdrückt
Portb.1 = 0
Waitms Dit
If P = 1 Then
Ddrb.0 = 1 ' Squeeze bzw. Punktspeicher auslesen
Portb.1 = 1
Waitms Dit
Ddrb.0 = 0
Portb.1 = 1
Waitms Dit
P = 0
Goto Mark
End If
End If


Schlafen:

If Pinb.2 = 1 And Pinb.3 = 1 Then ' Punkt- oder Strichkontakt sind nicht gedrückt
Stop Adc ' Strom sparen
Powerdown ' stärkster Stromsparmodus (auch Taktoszillator wird gestoppt)
End If

Loop



Morse: ' Morsezeichenerzeugung (nur Speicherbetrieb):


If M = 0 Then ' Sonderfall: Leerzeichen;
Waitms Wort
Goto Sign_end
End If

For I = 1 To 8
If M = 1 Then ' Das Byte hat nur noch den Wert 1; Zeichenende!
Goto Sign_end
End If
L = M And &B0000001 ' niederwertigstes Bit lesen
Ddrb.0 = 1 ' Ausgänge einschalten
Portb.1 = 1
If L = 1 Then
Waitms Dah ' ist das Bit 1 -> dah
Else
Waitms Dit ' ist das Bit 0 -> dit
End If
Ddrb.0 = 0 ' Ausgänge abschalten
Portb.1 = 0
Waitms Dit ' Pause innerhalb des Morsezeichens
Shift M , Right , 1 ' Bits um eine Stelle nach rechts shiften
Next I
Sign_end:
Waitms Dah ' Pause zwischen Morsezeichen
Return



Adclesen:

Dit = Getadc(2)
Dit = Dit + 32 ' für sinnvollen Einstellbereich 100k-Poti + 560k gegen Plus
'Dit = Dit + 256 ' stattdessen für sinnvollen Einstellbereich 1M-Poti
'Dit = Dit / 12 ' ""
Dah = 3 * Dit
Wort = 8 * Dit
Return



End

'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Codierung der Morsezeichen. Bei einem Prozessor mit viel SRAM würde man alle Zeichen
' in ein Array einlesen (Übersetzungstabelle), den eigentlichen Bakentext in einen String packen
' und diesen String zeichenenweise abarbeiten.
'
' Da der Attiny13 zu wenig SRAM hat und auch Flash knapp ist, ist der Weg hier anders:
' Die auszusendenden Zeichen sind direkt in der codierten Form in den Data- Zeilen ganz am Ende
' enthalten, allerdings in einer leicht lesbaren Schreibweise.
'
' Die Übersetzungstabelle ist mit Konstanten realisiert. Nur die wirklich benötigten
' Zeichen werden (beim kompilieren des Programmes) umgewandelt.


Const #a = &B00000110
Const #b = &B00010001
Const #c = &B00010101
Const #d = &B00001001
Const #e = &B00000010
Const #f = &B00010100
Const #g = &B00001011
Const #h = &B00010000
Const #i = &B00000100
Const #j = &B00011110
Const #k = &B00001101
Const #l = &B00010010
Const #m = &B00000111
Const #n = &B00000101
Const #o = &B00001111
Const #p = &B00010110
Const #q = &B00011011
Const #r = &B00001010
Const #s = &B00001000
Const #t = &B00000011
Const #u = &B00001100
Const #v = &B00011000
Const #w = &B00001110
Const #x = &B00011001
Const #y = &B00011101
Const #z = &B00010011
Const #ae = &B00011010
Const #oe = &B00010111
Const #ue = &B00011100
Const #0 = &B00111111
Const #1 = &B00111110
Const #2 = &B00111100
Const #3 = &B00111000
Const #4 = &B00110000
Const #5 = &B00100000
Const #6 = &B00100001
Const #7 = &B00100011
Const #8 = &B00100111
Const #9 = &B00101111

Const Leerz = 0
Const Anfuehrz = &B01010010
Const Kl_auf = &B00101101
Const Kl_zu = &B01101101
Const Plus = &B00101010
Const Komma = &B01110011
Const Minus = &B01100001
Const Punkt = &B01101010
Const Slash = &B00101001
Const Dopp_pkt = &B01000111
Const Gleich = &B00110001
Const Fragez = &B01001100
Const Ende = 255


Message:

Data #c , #q , Leerz , #c , #q , Leerz , #c , #q , Leerz , #d , #e , Leerz , #d , #k , #5 , #b , #u , Leerz , #d , #k , #5 , #b , #u , Leerz,
Data #c , #q , Leerz , #c , #q , Leerz , #c , #q , Leerz , #d , #e , Leerz , #d , #k , #5 , #b , #u , Leerz , #d , #k , #5 , #b , #u , Leerz,
Data #c , #q , Leerz , #c , #q , Leerz , #c , #q , Leerz , #d , #e , Leerz , #d , #k , #5 , #b , #u , Leerz , #d , #k , #5 , #b , #u , Leerz,
Data Plus , #p , #s , #e , Leerz , #k ,
Data Ende,



Elektronik-Labor   Projekte   AVR