Synopsis [Servos] Keywords Modellbau-Servo, Multiplexanzeige, PWM-Signal, Analog/Digitalwandung
Ein Modellbauservotester mit 3 stelliger Anzeige
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). |
Features des Testers
- Einstellbereich von 0,30 bis 2,85 ms
- Farbled zeigt grün bei < 1 ms, grün blinkend von 1..1,47 ms, blau zwischen 1,48..1,52 ms, rot blinkend von 1,53..2,00 ms dann dauernd rot.
- Taster zum Umschalten der Anzeige und Betriebsmodus, Piezo gibt Beep aus. Betriebsmodi, Umschalten mit Taster:
- Anzeige ms
- Anzeige Versorgungsspannung
- Anzeige Servostrom
- Anzeige ms eines externen Signals
- Unterspannungswarnung durch Warnsignal
Ansteuerung von Modellbau Servos
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. |
Neutralstellung und Endausschläge verschiedener Hersteller
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 |
Timer und Pulsweitenmodulation
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). |
Einstellungen bei Initialisierung Servosignal ausgeben
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) |
A/D Wandler der ATmega Bausteine
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:
- Vorteiler (Prescaler) für Takt an Wandler (soll im Bereich 50kHz..200kHz liegen) einstellen. Mögliche Teilungen 2,4,8,16,32,64,128. Gewählt 16 = > 1 MHz / 16 = 62,5 kHz
- Referenzspannung für Wandler ist AVCC = Spannung am Potentiometer
- Wandlung mit Interruptauslösung wird durch Anzeigentimer am Ende ausgelöst
- Zusätzliche Messung von Servostrom und Spannung
- Auflösung 10Bit oder 8Bit? - 10Bit bei C-Lösung
Einstellungen bei Initialisierung
Register | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Beschreibung |
---|---|---|---|---|---|---|---|---|---|---|
ADMUX | Bedeutung | REFS1 | REFS0 | ADLAR | - | MUX3 | MUX2 | MUX1 | MUX0 | Interne Referenzspannung, Wert ist rechtsbündig in ADCH:ADCL |
Wert | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | Poti an PC5 (ADC5) | |
ADCSRA | Bedeutung | ADEN | ADSC | ADFR | ADIF | ADIE | ADPS2 | ADPS1 | ADPS0 | Wandler an, Start mit ADSCS, Interrupt frei |
Wert | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | Vorteiler auf CLK/16 |
Sieben Segmentanzeige mit gemeinsamer Anode
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. |
BCD nach 7 Segment umwandeln negative Logik
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 |
Multiplexen mit Timer0
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.
3 Farb LED
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 |
ATmega 8
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) | ServoStrom | |
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 |
Programmieradapter
Bedeutung | Pin | 6 Pol | Pin | Bedeutung |
---|---|---|---|---|
MISO | 1 | 2 | VTG (VCC) | |
SCK | 3 | 4 | MOSI | |
Reset | 5 | 6 | GND |
Prototyp
Schaltplan
Erweiterung zur Messung von Empfängersignalen
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:
- Wenn innerhalb 25ms kein Signal vom Empfänger kommt, wird TIMER1_COMPA Interrupt ausgelöst und dadurch die Meldung "0FF" ausgegeben.
- Der ICP-Eingang kann je nach Einstellung einen TIMER1_CAPT Interrupt bei positiver oder negativer Flanke auslösen, zusätzlich wird der Wert des Timers1 in ICR1 gespeichert.
- Durch die beiden Interrupt-Service-Routinen (ISR) für Anzeige und ADC wird auf das ICP-Signal nicht immer sofort reagiert, daher wird bei steigender Flanke der Wert des Timers1 gespeichert und vom Wert bei fallender Flanke abgezogen -siehe C-Quellcode.
- Ist der gemessene Wert ausserhalb 200-2500ms wird die Meldung "Err" ausgegeben
Einstellungen bei Initialisierung Impuls-Messung des Empfängersignals
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) |
Ausblick und ToDo
- Kontinuierliche automatische Servobewegung mit einstellbarer Geschwindigkeit.
- Erhöhung der Genauigkeit durch Kalibration.
- Die Anzeige könnte auf 4 Stellen erweitert werden.
- Statt LEDs eine mehrzeilige LCD-Anzeige.
- Schaltplan um 0,1Ohm Widerstand zwischen GND und Servo-GND ergänzen, Servo-GND ist an ADC3 (26) zwecks Strommessung angeschlossen.
Arduino-Quellcode
Der Servotester kann mit Arduino-Software programmiert werden, dazu muss ggfs. noch die Board-Erweiterung "MiniCore" für den Mega8 geladen werden, Projektseite:
https://github.com/MCUdude/MiniCore
Installationsanleitung (Englisch)
Unter Arduino -> Einstellungen bei Zusätzliche Boardverwalter-URLs dies hinzufügen:
https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
Dann unter Werkzeuge -> Board -> Boardverwalter MiniCore installieren.
Den Boardverwalter wieder schließen, unter Werkzeuge -> Board -> MiniCore -> ATMega8 wählen.
Einstellungen siehe Bild links, die Taktfrequenz wird in der Software für die delay-Funktion beim Compilieren beachtet, daher sollte die Clock mit dem verwendeten Takt auf dem Chip übereinstimmen.
Programmieren über z.B. USPasp, diese Warnung ignorieren:
Wichtig: Analog-EIngänge werden immer abgefragt, daher Spannungsteiler und Strommessung anschließen:
0,1Ohm Widerstand zwischen GND und Servo-GND ergänzen, Servo-GND ist an ADC3 (26) zwecks Strommessung angeschlossen.
Sonst piepst die Unterspannungswarnung ständig.