:AVR: Modellbau-Servotester mit AnzeigeSynopsis [Servos] Keywords Modellbau-Servo, Multiplexanzeige, PWM-Signal, Analog/Digitalwandung
![]() |
Ich wollte schon lange einen Servotester mit Anzeige der Pulsdauer bauen. Über ein Potentiometer wird der Winkel des Servos eingestellt. Eine 3 Farb-LED zeigt die Neutralstellung an. Bei der Wahl des Bausteins und dessen Pin-Belegung müssen die notwendigen Funktionen und die damit verbundenen Ausgänge bedacht werden:
Ich habe mich für einen [ATmega 8] entschieden (lag auch noch rum und die Pins sollten reichen). |
![]() |
![]() |
Ein Modellbauservo sollte spätestens alle 20 ms einen Steuerimpuls bekommen. Die Impulslänge ist proportional zum Stellwinkel des Servos. Sie bewegt sich zwischen 0,3 und 2,7 ms. Für den Modellbauer interessant ist vor allem die Impulsdauer der Mittelstellung des Servos - hier 1,4 ms. Ich möchte eine Anzeige mit einer Auflösung von 10 µs also ein Anzeigebereich von 0,20 ms bis 3,00 ms.
Die erste Überlegung betrifft das Timing zur Erzeugung des PWM-Signals. |
| Hersteller | Max µs | Neutral µs | Min µs |
|---|---|---|---|
| robbe Futaba | 2120 | 1520 | 920 |
| robbe alternativ | 2300 | 1600 | 1000 |
| Modelcraft Servotester | 2000 | 1500 | 1000 |
| Graupner | 2000 | 1500 | 1000 |
Die Pulsweite soll in 10 µs Servo-Schritten verstellbar sein. Hier die naheliegenden Kombinationen:
| CPU Frequenz | Vorteiler | µs pro Zahl | Bewertung |
|---|---|---|---|
| 1 MHz | 1:1 | 1 | Int. Oszillator ist vorkalibriert, Standard, Multiplikation mit 10 notwendig |
| 4 MHz | 1:8 | 2 | Mehraufwand bei Kalibrierung, Multiplikation mit 5 notwendig |
| 8 MHz | 1:8 | 1 | Mehraufwand bei Kalibrierung, Multiplikation mit 10 notwendig |
![]() |
Gewählt 1 MHz mit Vorteiler 1:1, zum Multiplizieren mit 10 gibt es ja beim Mega8 praktische Befehle.
Um die 20 ms = 20 000 µs zu zählen brauchen wir den 16 Bit Timer1 -Doku Seite 76ff. Betriebsart Fast PWM Mode siehe Seite 90ff. Der Timer zählt von 0 bis zu einem einstellbaren TOP Wert und springt dann wieder auf 0. Ein Ausgang kann beim Sprung von TOP auf 0 gesetzt und bei Erreichen eines einstellbaren Wertes OCR1A wieder rückgesetzt werden. ICR1 als TOP weil nicht verändert mit Wert 19 999 für 20 ms Wiederholungsintervall, OCR1A = Servo-Schritt * 10. Ausgang ist PB1 (OC1A). |
| Register | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Beschreibung |
|---|---|---|---|---|---|---|---|---|---|---|
| TCCR1A | Bedeutung | COM1A1 | COM1A0 | COM1B1 | COM1B0 | FOC1A | FOC1B | WGM11 | WGM10 | Ausgang OC1A bei 0 setzen und bei OCR1A löschen |
| Wert | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
Waveform Generation Mode: Fast PWM mit ICR1 als TOP |
|
| TCCR1B | Bedeutung | ICNC1 | ICES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 | |
| Wert | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | Keine Vorteilung Timer mit CPU-CLK (No prescaling) |
Die Wandlung funktioniert nach dem Sukzessive-Approximations-Prinzip mit 10 Bit Auflösung. Es stehen im 28 Pol-PDIP-Gehäuse 5 Eingänge zur Verfügung. Man lese in der [Doku zu ATmega8] ab Seite 196 für genauere Details. Es müssen Entscheidungen getroffen werden:
| Register | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Beschreibung |
|---|---|---|---|---|---|---|---|---|---|---|
| ADMUX | Bedeutung | REFS1 | REFS0 | ADLAR | - | MUX3 | MUX2 | MUX1 | MUX0 | Externe Referenzspannung, Wert ist rechtsbündig in ADCH:ADCL |
| Wert | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | Poti an PC5 (ADC5) | |
| ADCSRA | Bedeutung | ADEN | ADSC | ADFR | ADIF | ADIE | ADPS2 | ADPS1 | ADPS0 | Wandler an, Free Running, Interrupt frei |
| Wert | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | Vorteiler auf CLK/16 |
![]() |
![]() |
In der Bastelkiste fanden sich noch 7-Segmentanzeigen mit der Aufschrift [HP 5082-7730].
Die Segmente haben eine gemeinsame Anode und der Dezimalpunkt ist links. Die Anzeige ist gemultiplext, LED laufen auf gemeinsame Anode Dig1..Dig3 zusammen.
|
||||||||||||||||||||||||||||||||||||||||||||
![]() |
Berechnung der Widerstände:Durch die 8 Segment-LEDs (incl. Dezimalpunkt) sollen 20 mA Strom (ISegment) fließen. Bestimmendes Bauteil ist hierbei Rseg. Die Spannung an Rseg ist 5V - Ueb - Ud = 5V - 0,1V - 1,8V = 3,1V. Rseg = 3,1V / 20 mA = 155 Ohm. Zur Verfügung stehen 150 Ohm oder 180 Ohm - gewählt Rseg = 150 Ohm. Durch den Transistor fließen maximal 8 * 20 mA = 160 mA. Ich habe noch [BC307B] Transitoren, deren minimaler Stromverstärkungsfaktor (Ic/Ib) Hfe liegt zwischen 222 und 455, sie können gerade eben den maximalen Strom aufnehmen. Da sie als Schalter fungieren sollen übersteuere ich sie 10 fach und gehe von einem Stom Ib = 160 mA / 20 = 8 mA aus. An Rb fällt eine Spannung von URb = 5V - Ube = 5V - 0,7V = 4,3V ab. Somit ist Rb = 4,3V / 8 mA = 537 Ohm - gewählt Rb = 560 Ohm. |
| Binär | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Hex | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
| BCD (Binary coded Dezimal) | HEX | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
![]() |
r | ||||||||||||||||
| Zahl | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
| Pos. Log. | 3F | 06 | 5B | 4F | 66 | 6D | 7D | 07 | 7F | 6F | 77 | 7C | 39 | 5E | 79 | 71 | 50 |
| Neg. Log | C0 | F9 | A4 | B0 | 99 | 92 | 82 | F8 | 80 | 90 | 88 | 83 | C6 | A1 | 86 | 8E | AF |
Der 8 Bit Timer0 wird mit 1/8 Systemtakt betrieben und zählt damit von 0 bis 255. Mittels Interrupt wird so 488 mal pro Sekunde ein Anzeigenstellenwechsel durchgeführt.
Ansicht von Oben![]() |
Eine 3 Farb LED soll die Servostellung anzeigen Blau = Mitte, Grün < Mitte und Rot > Mitte.
Die Vorwiderstände der LEDs werden ermittelt: LEDBlau: 5V - 3,9V / 10 mA = 110 Ohm - gewählt 100 Ohm LEDRot: 5V - 2,0V / 10 mA = 300 Ohm - gewählt 270 Ohm LEDGrün: 5V - 2,3V / 10 mA = 270 Ohm - gewählt 270 Ohm |

| Belegung | Bedeutung | Pin | Pin | Bedeutung | Belegung | |
|---|---|---|---|---|---|---|
| Reset | (Reset) PC6 | 1 | A T M E G A 8 |
28 | PC5 (ADC5) | Poti |
| a | (RXD) PD0 | 2 | 27 | PC4 (ADC4) | BattSpannung | |
| b | (TXD) PD1 | 3 | 26 | PC3 (ADC3) | ||
| c | (INT0) PD2 | 4 | 25 | PC2 (ADC2) | Dig1 | |
| d | (INT1) PD3 | 5 | 24 | PC1 (ADC1) | Dig2 | |
| e | (T0) PD4 | 6 | 23 | PC0 (ADC0) | Dig3 | |
| VCC | 7 | 22 | GND | |||
| GND | 8 | 21 | AREF | |||
| LEDRot | (XTAL1) PB6 | 9 | 20 | AVCC | ||
| LEDGrün | (XTAL2) PB7 | 10 | 19 | PB5 (SCK) | Taster | |
| f | (T1) PD5 | 11 | 18 | PB4 (MISO) | ||
| g | (AIN0) PD6 | 12 | 17 | PB3 (MOSI/OC2) | Piezopieper | |
| DP | (AIN1) PD7 | 13 | 16 | PB2 (SS/OC1B) | LEDBlau | |
| Eingang Empfänger | (ICP1) PB0 | 14 | 15 | PB1 (OC1A) | Servo |
| Bedeutung | Pin | 6 Pol | Pin | Bedeutung |
|---|---|---|---|---|
| MISO | 1 | 2 | VTG (VCC) | |
| SCK | 3 | 4 | MOSI | |
| Reset | 5 | 6 | GND |


Ich wollte auch die Signale eines Empfängers messen und habe dazu den ICP-Eingang verwendet. Der Taster S1 dient nun zur Umschaltung zwischen Servoausgabe oder Empfängermessung.
Prinzip der Messung:
| Register | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Beschreibung |
|---|---|---|---|---|---|---|---|---|---|---|
| TCCR1A | Bedeutung | COM1A1 | COM1A0 | COM1B1 | COM1B0 | FOC1A | FOC1B | WGM11 | WGM10 | Ausgang OC1A ohne Funktion |
| Wert | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | CTC Mode mit OCR1A als TOP | |
| TCCR1B | Bedeutung | ICNC1 | ICES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 | Input Capture pos Flanke |
| Wert | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | Keine Vorteilung Timer mit CPU-CLK (No prescaling) |
| Assembler [Quellcode] | C [Quellcode] |
|---|---|
; *** Servotester V 0.5 (c) Oliver Mezger 23.2.2010
|
// Servotester V 1.0 (c) Oliver Mezger 7.9.2010 |