Servotester           

von Heinz D.                      
Elektronik-Labor  Projekte   AVR   T13-Contest

 

Einen Servo kann man nicht mit den (vorhandenen) einfachen Messgeräten testen. Bei Flugmodellen möchte man jedoch auf Nummer sicher gehen. "Kannst du mir ein paar Servo's testen?" ich: "Mal sehen, ich versuchs." Da kam nur ein Tiny13 in Frage. Zum Testen wird ein 50Hz-Rechteck mit einem einstellbaren Impuls von 1ms-2ms Breite benötigt. Zur Stromversorgung werden 4,8V-5,5V benötigt, unterhalb von 4,8V zicken manche Sevos, oberhalb von 5,5V zickt der Tiny13!

Frisch ans Werk, das Programm 8 (mit ADC und Timer) auf 1-2ms/50Hz angepasst und siehe da, der Verstellbereich hatte nur noch 8 Stufen. Das sah zwar lustig aus, aber die Servos arbeiten proportional, also sollten sie ein 256-stufiges Verhalten zeigen.

Also alles auf Anfang: einen Impuls von knapp 1ms erzeugen (main0), dann abhängig vom ADC-Wert noch gut 0-1ms dazu (main1+2) und für den Rest bis zur 20.ms eine Pause generieren (main3).

Mit den Cyclen (aus der Befehlstabelle) könnte man die genauen Zeiten berechnen, wenn da nicht der ADC-Interrupt wäre, der knapp 20% der Gesamtzeit verbraucht. Das Programm erreicht einen Verstellbereich von ~0,8ms-2,2ms, das ist der normale Arbeitsbereich (~ 100°) von Standardservos.

Sie sollten sich hüten, das Programm so zu ändern, das der (mechanische) rechte/linke Anschlag erreicht wird, weil der Strom dann stark ansteigt und die Elektronik aussteigt (IC ungekühlt!).



Download: servo-tester1-asm-hex-lst.zip

; Oster-Contest 2013
;
; servo1: 1 ms-2 ms / 50Hz (futaba 0,6-2,4ms)
;
; Das Poti/ADC(2) wird per Interrupt in r16 geholt.
; Das verbraucht etwa 20% der Gesammtzeit.
; Dadurch sind die Zeiten nur ungefähr berechenbar.
;
; Mit PB.1=1 wird r18 einmal durchgezählt (0-255), um den Pulsanfang von 0,8ms zu erzeugen,
; dann wird r18 noch einmal durchgezählt und mit r16(adc) verglichen,
; bei Übereinstimmung wird PB.1 auf 0 gesetzt,
; nun sind 2,3ms vergangen und die Rest-Pause (17,7ms) beginnt.
;
; das Ganze funktioniert nur bei 1,2MHz
;
; Lock FF, Fuse 6A = 0b0110_1010, Fusehigh FF
; devide=^ ^^^^=9,6MHz
;
; ATMEL ATtiny13
; _____ _____
; | |_| |
; o-|Res Vcc|-------o +5V
; | |
; | |
; | sck|
; o-|PB3 PB2|-o
; |ADC3 ADC1|
; | | |-o Servo schwarz
; ___ | miso| +5V o Servo rot
; +-|___|---|PB4 PB1|-------o Servo gelb/braun
; | 1k |ADC2 oc0b|
; | | |
; _v_ | mosi|
; +5V o-|___|-----+-|Gnd PB0|-o
; 10k | | oc0a|
; Poti |--+ |_____________|
;
;
.DEVICE ATtiny13 ;für gavrasm, für Symbolische Registerbezeichnungen (z.B.'DDRB')
.cseg ;codesegment
.org 0 ;adr 0
;Vector-Tabelle
rjmp init ;Reset vector
reti ;Int0 interrupt vector
reti ;PCINT0 vector
reti ;TC0 overflow vector
reti ;Eeprom ready vector
reti ;Analog comparator int vector
reti ;TC0 CompA vector
reti ;TC0 CompB vector
reti ;WDT vector
rjmp int_adc ;ADC conversion complete vector
;--------------------------------
Int_adc: ;Aufruf NUR, wenn neuer Wert verfügbar
in r16,ADCh ;Lese ADC-Wert, obere 8Bit
reti ;zurück ins Hauptprogramm
;--------------------------------
init: ;Vorbereitungen
ldi r16,ramend ;Stack vorbereiten
out spl,r16 ;auf RAMEND setzen
sbi ddrb,1 ;Ausgang definieren
init_adc: ;
ldi r16,0b00100010 ; - 0 1 - - - 1 0
Out Admux , R16 ;ref-^ ^adlar ^+^-adc2
ldi r16,0b00000000 ; - - - - - 0 0 0
Out Adcsrb , R16 ; ^+^+^-Free Run
ldi r16,0b11101111 ; 1 1 1 0 1 1 1 1
Out Adcsra , R16 ;ena-^ ^-start ^+^+^-prescale
sei ;Set Enable Interrupt (-Flag)
;--------------------------------
main: ;Hauptprogramm
sbi portb,1 ;Pulsanfang (1Cy) nur einmal
main0: ;Offset (us ~ 256 * 3Cy) ungefähr 768us
inc r18 ;0-255-0 (1Cy)
brbc 1,main0 ;springe wenn Z=0 (2Cy)
;------------------------
main1: ;+ adc * 6Cyclen (us ~ 256 * 6Cy) ungefähr 1536us
cpse r16,r18 ;skip if R18=adc ? (1Cy)
rjmp main2 ;nein, weiterzählen (2Cy)
cbi portb,1 ;ja, Pulsende (1Cy) nur einmal
main2: ;zählen
inc r18 ;0-255-0 (1Cy)
brbc 1,main1 ;springe wenn Z=0 (2Cy)
;------------------------
ldi r25,79 ;pausenlänge (256-79)*256/8 (1Cy) nur einmal
main3: ;17,7 ms (us ~ (256-79) * 100) ungefähr 17700us
adiw r24,8 ;step 8 (2Cy)
brbc 1,main3 ;springe wenn Z=0 (2Cy)
rjmp main ;nochmal (2Cy) nur einmal
;end


Servotester II



"Kannst du mir die PWM-Routine geben?", "Ja, warum? Aber die hat nur 8 Stufen.", "Das reicht, aber ich brauche die Zeit im Hauptprogramm und kann mir die Warteschleifen nicht erlauben."  Die Routine besteht nur aus Init_pwm. Die gesamte CPU-Zeit ist frei verfügbar. Die Pulsbreite wird durch den Wert in OCR0b bestimmt (n*121us) und kann bei Bedarf (in Main) neu geladen werden. Das Oszillogramm zeigt ocr0b = 12 ~ 1,5ms. Falls der Tiny13 mit 4,8MHz laufen soll, muss der Prescaler auf /256 gesetzt werden. Ggf. sind Anpassungen für 50Hz notwendig. Für 9,6MHz passt kein Prescaler.

Download: servo-tester2-asm-hex-lst.zip

; 2013-Oster-Contest, Servo-Tester2 in Stufen von 121us 
;
; PWM-Modul für 1,2MHz (für 4,8MHz prescaler auf 256 erhöhen)
;--------------------------------
; ocr0a ~ 193 ~ 1,2MHz / 64prescaler / 2phase / 50 Hz (= 188)
; ocr0b ~ 121us * n
;--------------------------------
; Fuse 0b0110_1010
; devide=^ ^^^^=9,6MHz
;--------------------------------
.DEVICE ATtiny13 ; für gavrasm
.cseg ; codesegment
.org 0 ; adr 0
;--------------------------------
init: ; Vorbereitungen
sbi ddrb,1 ; Ausgang definieren
;--------------------------------
init_pwm: ; Mode 5
ldi r16,0b00100001 ; 0 0 1 0 - - 0 1
Out Tccr0a , R16 ; A-^-^ ^-^-B ^+^=PWM clear OC0B on compare
ldi r16,0b00001011 ; 0 0 - - 1 0 1 1
Out Tccr0b , R16 ; PWM-^ ^+^+^-prescale
ldi r16,193 ; 193 => 50Hz
out ocr0a,r16 ;
; neue Werte müssen nur einmal im Hauptprogramm geladen werden
ldi r16,12 ; n = t / 121us
Out Ocr0b,R16 ; lade OCR0B = 12 => 1,5ms
;--------------------------------
main: ; Hauptprogramm
rjmp main ;
;--------------------------------
;end


Voltmeter für Schwersichtige



IN JEDEM FALL SIND DIE DIN-VORSCHRIFTEN ZU BEACHTEN!

Ein Voltmeter, das man aus großer Entfernung ablesen kann wollte ich immer schon haben. Die Software entspricht im wesentlichen Servo-Tester 1, nur die Uref wurde auf die interne 1,1V Referenz umgestellt und der Anzeigebereich auf 165° erweitert. Gegebenenfalls muss hier je nach verwendetem Servo nachgearbeitet werden. Außerdem wurde eine Clipping-Anzeige hinzugefügt.


]

Der Gesamtwinkel (0V-11V) kann durch entfernen/hinzufügen eines NOP (#) um je ~15° verändert werden, das ist sehr grob. Versuchen Sie etwa 165° einzustellen, ohne die Anschläge zu erreichen. Der rechte Ausschlag (~600ms) kann in MAIN0 sehr fein eingestellt werden. Am Rechtsausschlag sollte der größte Abstand zum mechanischen Anschlag eingestellt werden, weil manche Servos zum Übersteuern neigen. Der linke Ausschlag (0V ~ 2,5ms) kann nahe am mechanischen Anschlag sein.

;===============================================================================================
;
; Oster-Contest: Servo (-Tester) 3 oder Voltmeter für Schwersichtige
;
;===============================================================================================
;
; ATtiny13
; _____ _____
; | |_| | 1N4148 /
; |Res Vcc|-------+---|<|---+-o o-o +4,5V-6V
; | | | |
; | | --- C1 |
; | sck| --- 1u |
; +-----|PB3 PB2|-----+ | |
; | | | | | |
; | | | | | |
; | | miso| | | |
; | +---|ADC2 PB1|---+ | | |
; | | | | | | | |
; | | | | | | | |
; | | | mosi| | | | |
; | | +-|Gnd PB0|-+ | | | |
; | | | |_____________| | | | | |
; | | o--o--o--o--o--o--|-|-|-+ schwarz |
; | | o--o--o--o--o--o--|-|-|-----------+ rot
; | +-o o o o o-----+ | | gelb
; +------+ | +----------+ |
; +---------------+
; B4 B3 B2 B1 B0 Batt
;
;
; ALLE GND-Anschlüsse MÜSSEN (sternförmig) auf kürzestem Weg am Pin 4 zusammenlaufen,
; um keine Spannungsabfälle auf ADC(2) zu übertragen.
;
; Die Skala wird mit einem DVM geeicht
;===============================================================================================
; ADC(2)=PB.4 wird per Interrupt in r16 geholt. Uref auf 1,1V eingestellt
; ist ADC=255 wird die Clipping-LED=PB.2 eingeschaltet
;
; Zuerst wird r18 mit dem Startwert für Rechtsanschlag geladen und bis 0 herunter gezählt (main0) ~ 600us
;
; dann wird r18 herunter gezählt (255-0) und mit r16(adc) verglichen,
; bei Übereinstimmung wird PB.1 auf 0 gesetzt, Pausenanfang (main1+2) ~ 2000us
; # durch hinzufügen/entfernen eines NOP wird der Gesamtwinkel (165°) bestimmt.
;
; nun sind ~ 2,6ms vergangen und die Rest-Pause beginnt. (main3) ~ 17400us
; nur in main3 wird der ADC-Int erlaubt, um das zappeln zu verringern.
; ggf. kann ein 100nF am ADC gegen GND das zappeln weiter verringern.
;===============================================================================================
; das Ganze funktioniert nur bei 1,2MHz
; Fuse 0b0110_1010
; devide=^ ^^^^=9,6MHz
;===============================================================================================
.DEVICE ATtiny13 ; für gavrasm
.cseg ; codesegment
.org 0 ; adr 0
rjmp init ; Reset vector
reti ; Int0 interrupt vector
reti ; PCINT0 vector
reti ; TC0 overflow vector
reti ; Eeprom ready vector
reti ; Analog comparator int vector
reti ; TC0 CompA vector
reti ; TC0 CompB vector
reti ; WDT vector
rjmp int_adc ; ADC conversion complete vector
;--------------------------------
Int_adc: ; Aufruf NUR, wenn neuer Wert verfügbar
in r16,ADCh ; Lese ADC-Wert, obere 8Bit
sbi portb,3 ; Clip on
cpse r16,r17 ; skip if adc=r17 ? (1Cy)
cbi portb,3 ; Clip off
reti ; zurück ins Hauptprogramm
;--------------------------------
init: ldi r16,0b00001010 ; Ausgaang definieren
out ddrb,r16 ;
ldi r17,255 ; clipping-Wert
init_adc: ;
ldi r16,0b01100010 ; - 1 1 - - - 1 0
Out Admux , R16 ; ref-^ ^adlar ^+^-adc2
ldi r16,0b00000000 ; - - - - - 0 0 0
Out Adcsrb , R16 ; ^+^+^-Free Run
ldi r16,0b11101110 ; 1 1 1 0 1 1 1 1
Out Adcsra , R16 ; ena-^ ^-start ^+^+^-prescale
;--------------------------------
main: cli ; verbiete Interrupts (1Cy) nur einmal
sbi portb,1 ; Pulsanfang (1Cy) nur einmal
ldi r18,208 ; offset k (rechts) (1Cy) nur einmal
main0: dec r18 ; 0->255->0 (1Cy)
brbc 1,main0 ; springe wenn Z=0 (2Cy) us ~ k * 3 Cy
;--------------------------------
main1: dec r18 ; fang mit 255 an ->0 (1Cy)
cpse r16,r18 ; skip if R18=adc ? (1Cy)
rjmp main2 ; nein, weiterzählen (2Cy)
cbi portb,1 ; ja, Pulsende (2Cy) nur einmal
main2: nop ; # 165°-Anpassung # (1Cy)
nop ; # Winkel # (1Cy)
brbc 1,main1 ; Puls+Pause (2Cy) us ~ 256 * 8Cy
;--------------------------------
sei ; erlaube adc-Int (1Cy) nur einmal
ldi r25,17 ; pause k (1Cy) nur einmal
main3: sbiw r24,1 ; dec (2Cy)
brbc 1,main3 ; springe wenn Z=0 (2Cy) us ~ 256 * k * 4Cy
rjmp main ; nochmal (2Cy) nur einmal
;===============================================================================================
;end

Die Skala ist in 11 Teile auf 165° (= 15°/1V, 12 Teile/180°) verteilt. Die Teilstriche können einfach durch Vergleich mit einem DVM angebracht werden. Schwersichtige können die Skala mit Braille-Zeichen ergänzen. Das Instrument ist robust genug, um es mit den Fingern abzulesen.




Vom vorgeschlagenen Spannungteiler wurde nur die '10V' Anzapfung auf die Buchse gelegt. Zum Einschalten dient eine Taste, um  Strom zu sparen und gleichzeitig eine HOLD-Funktion zu haben. Das Instrument ist nur für positive Gleichspanng gedacht. Wechselspannungen verursachen wilde Ausschläge.



Im Vollausbau haben Sie ein Vielfach-Instrument mit 100kOhm/Volt. Die obere Reihe wird auf Buchsen geführt, die unteren Anschlüsse sind am Tiny13 angeschlossen. Falls Sie für 1R keinen Hochlastwiderstand haben, sollten Sie den 1A-Messbereich weglassen, jedoch NICHT den 1R Widerstand !!!

Falls Ihr Servo wild zappelt, sollten Sie den GND-Sternpunkt überprüfen und wörtlich nehmen: selbst kleinste Spannungsabfälle (von LED, Servo) dürfen nicht auf den ADC-Eingang gelangen. Falls Ihr Servo dauernd an die mechanischen Anschläge fährt, sollten Sie die NOP's entfernen und mit einem kleineren Ausschlag die Skale eichen. Es genügt das Eichen in einem 10V/32V-Bereich










Die 5 Ports sind 'Servo-Kompatibel' beschaltet. Das hat den Vorteil, das bei verpolter LED, Ein-, Ausgänge, usw. einfach umgesteckt wird. Hier wird auch die Stromversorgung angeschlossen. Der Zeiger ist von (m)einer Küchenuhr. Das Messgerät ist bis zu 4-fach gefahrlos überlastbar. Dann sind jedoch in den Strombereichen die Widerstände in Gefahr zu verbrennen. Falls die Clipinganzeige leuchtet, sollten Sie sofort die Messkabel abklemmen und den Fehler suchen.

Das Messgerät ist durchaus Kindgerecht. Man sollte jedoch einen Ersatzzeiger haben, weil es unwiderstehlich ist, den zappelnden Zeiger festzuhalten. Da nutzt auch die Erklärung nicht, das der Servo den Zeiger mühelos abbricht.

Downlaod:  servo3-asm-hex-lst.zip



Elektronik-Labor  Projekte   AVR   T13-Contest