- Akku Tests und Balkonkraftwerk Speicher         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: ASURO ADC für Taster direkt auslesen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    13.06.2005
    Beiträge
    5

    ASURO ADC für Taster direkt auslesen

    Anzeige

    Praxistest und DIY Projekte
    Hallo Leute,

    das die Widerstände an den sechs Tastern mit ihren Toleranzen Probleme machen, ist hier im Forum mehrmals erwähnt worden. Ich wollte die Sache mal optimieren, sprich die Formel in asuro.c verbessern, doch bräuchte ich dazu die einzelnen Werte, die pro Taster konvertiert werden.

    Meine Idee: die Werte per IR (serwrite) beim Drücken eines Tasters ausgebe.

    Hat das schon jemand probiert? Ich bin erst dabei mich in c einzuarbeiten und krieg das auch irgend wann hin - aber warum das Rad immer wieder selbst erfinden?

    So long - I2C

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    ASURO ist ja ganz normal in C programmiert, wenn ich mich nicht verrechnet habe, dann sind das die folgenden Werte
    AD-Werte - Wert in Pollswitch()
    678-682 -> 32
    812-821 -> 16
    903-915 -> 8
    956-970 -> 4
    985-1000 -> 2
    1001-1015 -> 1

    So siehts laut Formel aus. Wenn du die Werte anpassen willst, dann geht das natürlich nur individuell für deinen ASURO. Welcher Taster bei dir stimmt denn nciht und welcher Wert ist das in Pollswitch, der eigentlich kommen müsste.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    13.06.2005
    Beiträge
    5

    ADC-Ausgabe an serwrite

    Ich will ja gerade die genauen Werte - d.h. die zu meinen Widerständen gehörigen - zurückgemeldet bekommen. Mein Problem ist, dass Kombinationen von Tastern den Motor mit anlaufen lassen. Ich habe den Wert in der Formel auf 62 verringert, wodurch beim ersten Taster der Motor nicht mehr mit anspringt.

    Also - wie komm ich an den Wert vor der Umrechnung dran bzw. wie gebe ich in an serwrite weiter?

    Gruß, I2C

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.05.2005
    Beiträge
    734
    Er meinte wohl wie er Werte über die IR-Schnittstelle an den PC senden kann.

    Probier mal folgendes:
    char text[6]=" ";

    itoa(wert,text,10);
    SerWrite(text,6); SerWrite("\n\r",2);

    Hier noch die Erklärung:
    char text[6] deklariert ein Feld für deinen Text
    itoa wandelt integer to ascii, wobei wert in text gewandelt wird, 10 bedeutet zur Basis 10 also dezimal
    mit SerWrite wird gesendet, "\n\r" ist Neue Zeile + Rücklauf, "\t" wäre Tabulator

    Hoffe das hilft weiter.

    Gruß waste

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.05.2005
    Beiträge
    734
    Ich sehe gerade, das Board hat mir die Leerzeichen in den Anführungszeichen weggemacht. Also hier nochmal mit Code und etwas erweitert zur Anschauung.

    Code:
    char text[6]="      ";
    
    itoa(wert,text,10);
    SerWrite("Wert = ",7);SerWrite(text,6); SerWrite("\n\r",2);

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo,
    wie ich sehe arbeitet Ihr daran, was ich jetzt auch erreicht habe.
    Ich habe mir ein kleines Programm geschrieben,
    daß mir die gemessenen Spanunngswerte im Terminal ausgibt.
    Alles schön und gut, es gibt leider gaanz kleine Abweichungen zwischen den Messungen.
    Meine Überlegung dazu...
    Da man meistens nur wissen will, ob der Asuro mit der rechten oder linken Seite hängenbleibt
    und die Werte auf den rechten 3 Tastern alle über 0,950 V und auf den linken alle darunter liegen könnte man ja die ganze rumrechnerei mit float usw. weglassen und nur ein if else Konstrukt verwenden um festzustellen, ob links oder rechts ein Taster betätigt wurde...
    Ich hoffe ich habe mich klar ausgedrückt.
    Im Anhang ist mein Programm.
    Bei Interesse sende ich noch den Code, der ist aber in Assembler

    Gruß Sebastian
    Angehängte Dateien Angehängte Dateien

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    13.06.2005
    Beiträge
    5
    Hallo auch wieder in dieser Runde!

    Erst mal Dank an Waste - wie gesagt lerne ich dazu, was c angeht und der Aufruf von itoa() war genau das was mir gefehlt hat.
    Dazu noch ne kleine Frage: Ich bekomme vom Compiler eine Meldung wie etwa "implizit deklariert", weil ich keinen besonderen Header eingebunden habe. In welcher lib steht denn itoa() und gibt's da vielleicht noch mehr so interessante Routinen?

    Meine Bemühungen zu den Schaltern ergaben auch wechselnde Werte bei Belastungen (LED, Motor etc.), weshalb ich die Selbsttestroutine um die Reaktionen gekürzt habe. Ich lass also nur noch die Werte auf serwrite raus. Programmschnipsel werden bei Gelegenheit nachgereicht.

    Schön wäre es schon, wenn man die Tasten konkret zuordnen könnte - der Ansatz im ASURO auf die Art Leitungen einzusparen ist jedenfalls interessant. Wenn ich die Werte (ev. mit Streuung) protokolliert habe, schau ich mal, wie man das möglichst elegant umrechnen kann.

    Hat sich jemand mit dem ADC näher auseinandergesetzt? Vielleicht kann man die Abfrage mit einer weiteren Z-Diode o.ä. optimieren. Die Referenzsspannung hat wohl schon Einfluss auf den Ausgabewert.

    Gruß, I2C

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    13.06.2005
    Beiträge
    5
    Hallo Sebastian,

    kannst Du die sources posten? Das hexfile ist ja ganz nett, aber Assembler könnte doch etwas aussagekräftiger sein ...

    Danke, I2C

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.05.2005
    Beiträge
    734
    Für itoa() mußt du <stdlib.h> einbinden.
    Weitere Funktionen kannst du im avr-lib Manual nachlesen. Da müsste ein Symbol auf deinem Desktop sein.

    Das Auslesen von Werten mittels SerWrite() verändert das Timing, weil eben die serielle Ausgabe mit 2400 Baud etwas dauert. Das mußt du berücksichtigen. Ich hab nämlich auch noch ein kleines Problem mit der Tasterabfrage. Aber immer wenn ich mir die Werte ausgeben lasse, ist es in Ordnung. Ich hab's vorerst so gelassen, werd es später mal genauer untersuchen.

    Gruß waste

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo,
    hier ist mein Programm:

    Code:
    .include "m8def.inc"
    
    ;UBRR = Taktfrequenz / 16 * Baudrate -1
    .def rBin1L = R1	;Wird gebraucht um bin -> ascii zu rechnen
    .def rbin1H = R2	;Wird gebraucht um bin -> ascii zu rechnen
    .def rbin2H = R3	;Wird gebraucht um bin -> ascii zu rechnen
    .def rbin2L = R4	;Wird gebraucht um bin -> ascii zu rechnen
    
    .def tmp = R16 ;universalregister
    .def statusreg = R17 ;Statusregister um die Interrupts zu signalisieren
    .def rmp = R18 ;universalregister für die Umrechnung
    .equ sramanfang = 0x0060
    .equ bumper = 7 ;Bit 7 von statusreg signalisiert INT1 Interrupt
    .equ CLOCK = 8000000
    .equ BAUD = 2400
    .equ UBRRVAL = CLOCK / (BAUD*16)-1
    
    .org 0x000
    	rjmp reset
    .org INT1addr
    	rjmp kolision	;Ext Interrupt Vector Address
    reset:
    ;Stackpointer
    	ldi tmp,LOW(RAMEND)
    	out SPL,tmp
    	ldi tmp,HIGH(RAMEND)
    	out SPH,tmp
    ;sram pointer
    	ldi ZH,HIGH(sramanfang)
    	ldi ZL,LOW(sramanfang)
    ;Baudrate einstellen
    	ldi tmp,UBRRVAL
    	out UBRRL,tmp
    			;di tmp,HIGH(UBRRVAL)
    			;ut UBRRL,tmp
    ;Frameformat 8Bit
    	ldi tmp,(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) 
    	out UCSRC,tmp
    	
    	sbi UCSRB,TXEN	;TX aktivieren
    	
    ;AD converter Init
    	ldi tmp,(1<< ADEN) | (1<<ADPS1) | (1<<ADPS2)
    	out ADCSRA,tmp
    	ldi tmp,(1<<REFS0) | (1<<MUX2)
    	out ADMUX,tmp  
    	;Einstellen Low Level Interrupt für Tastenabfrage
    	ldi tmp,(1<<INT1)
    	out GICR,tmp
    	sei
    loop_:
    	;sram pointer
    	ldi ZH,HIGH(sramanfang)
    	ldi ZL,LOW(sramanfang)
    loop:
    	sbrs statusreg,bumper ;prüfe statusregister ob bit 7 -> bumper gesetzt ist wenn ja dann springe
    	rjmp loop
    	in tmp,GICR	;Schalte INT1 interrupt ab
    	andi tmp,0x7f
    	out GICR,tmp
    	ldi statusreg,0	;lösche statusregister bumper
    	cli		;Interrupts allgemein ausschalten
    	sbi DDRD,PD3	;schalte pin PD3 als Ausgang
    	sbi PORTD,PD3	;und setze es auf HIGH
    	ldi R16, $85    ; 10 ms abwarten
    L1:        ldi R18, $C7     
    L2:        dec R18        
    	brne L2        
    	dec R16        
    	brne L1        
    	sbi ADCSRA,ADSC	;Starte ADC
    warte:
    	sbis ADCSRA,ADIF
    	rjmp warte
    	;fertig und lese Ergebnis ein 
    	in rBin1L,ADCL
    	in rBin1H,ADCH
    	cbi PORTD,PD3	;Pin PD3 wieder LOW
    	cbi DDRD,PD3	;und wieder als Eingang
    	sei	;Interrups wieder an
    	rcall berechne	;Rechne Ergebnis in ascii um und schreibe 
    	;es in sram
    			
    	
    	rcall serout	;gib das Ergebnis über UART aus
    	in tmp,GICR	;Schalte Interrupts auf INT1 wieder ein
    	ori tmp,0x80
    	out GICR,tmp
    	rjmp loop_	;wenn fertig wieder von vorne anfangen
    
    serout:
    	ldi tmp,0x00	;Zähler für Anzahl der CHAR
    serout_:
    	cpi tmp,0x05	;Vergleiche Zähler mit 0x05 	
    	breq rausuart	;Wenn gleich springe
    	ld R0,Z		;Hole ASCII kodierte Zahl aus den SRAM 
    serout__:	
    	sbis UCSRA,UDRE ;Springe wenn UDR gesetzt ist
    	rjmp serout__
    	out UDR,R0	;schiebe R0 in UDR 
    	adiw ZL,1	;Z++
    	inc tmp		;Zähler ++
    	rjmp serout_
    rausuart:
    	sbis UCSRA,UDRE ;Springe wenn UDR gesetzt ist
    	rjmp rausuart
    	ldi tmp,10	;sende Zeilenvorschub
    	out UDR,tmp
    rausuart_:	
    	sbis UCSRA,UDRE
    	rjmp rausuart_
    	ldi tmp,13	;sende Wagerücklauf
    	out UDR,tmp
    	ret
    
    ;Diese Routine stammt von Gerd Schmidt http://www.avr-asm-tutorial.net/avr_de/index.html
    ;Danke dafür
    berechne:
    	rcall Bin2ToBcd5 ; wandle Binärzahl in BCD um
    	ldi rmp,4 ; Zähler auf 4
    	mov rBin2L,rmp
    Bin2ToAsc5a:
    	ld rmp,z ; Lese eine BCD-Ziffer
    	tst rmp ; prüfe ob Null
    	brne Bin2ToAsc5b ; Nein, erste Ziffer ungleich 0 gefunden
    	ldi rmp,' ' ; mit Leerzeichen überschreiben
    	st z+,rmp ; und ablegen
    	dec rBin2L ; Zähler um eins senken
    	brne Bin2ToAsc5a ; weitere führende Leerzeichen
    	ld rmp,z ; Lese das letzte Zeichen
    Bin2ToAsc5b:
    	inc rBin2L ; Ein Zeichen mehr
    Bin2ToAsc5c:
    	subi rmp,-'0' ; Addiere ASCII-0
    	st z+,rmp ; und speichere ab, erhöhe Zeiger
    	ld rmp,z ; nächstes Zeichen lesen
    	dec rBin2L ; noch Zeichen behandeln?
    	brne Bin2ToAsc5c ; ja, weitermachen
    	sbiw ZL,5 ; Zeiger an Anfang
    	ret ; fertig
    
    Bin2ToBcd5:
    	push rBin1H ; Rette Inhalt der Register rBin1H:L
    	push rBin1L
    	ldi rmp,HIGH(10000) ; Lade 10.000 in rBin2H:L
    	mov rBin2H,rmp
    	ldi rmp,LOW(10000)
    	mov rBin2L,rmp
    	rcall Bin2ToDigit ; Ermittle 5.Stelle durch Abziehen
    	ldi rmp,HIGH(1000) ; Lade 1.000 in rBin2H:L
    	mov rBin2H,rmp
    	ldi rmp,LOW(1000)
    	mov rBin2L,rmp
    	rcall Bin2ToDigit ; Ermittle 4.Stelle durch Abziehen
    	ldi rmp,HIGH(100) ; Lade 100 in rBin2H:L
    	mov rBin2H,rmp
    	ldi rmp,LOW(100)
    	mov rBin2L,rmp
    	rcall Bin2ToDigit ; Ermittle 3.Stelle durch Abziehen
    	ldi rmp,HIGH(10) ; Lade 10 in rBin2H:L
    	mov rBin2H,rmp
    	ldi rmp,LOW(10)
    	mov rBin2L,rmp
    	rcall Bin2ToDigit ; Ermittle 2.Stelle durch Abziehen
    	st z,rBin1L ; Rest sind Einer
    	sbiw ZL,4 ; Setze Zeiger Z auf 5.Stelle (erste Ziffer)
    	pop rBin1L ; Stelle den Originalwert wieder her
    	pop rBin1H
    	ret ; und kehre zurück
    Bin2ToDigit:
    	clr rmp ; Zähler auf Null
    Bin2ToDigita:
    	cp rBin1H,rBin2H ; Vergleiche MSBs miteinander
    	brcs Bin2ToDigitc ; MSB Binärzahl kleiner, fertig
    	brne Bin2ToDigitb ; MSB Binärzahl größer, subtrahiere
    	cp rBin1L,rBin2L ; MSB gleich, vergleiche LSBs
    	brcs Bin2ToDigitc ; LSB Binärzahl kleiner, fertig
    Bin2ToDigitb:
    	sub rBin1L,rBin2L ; Subtrahiere LSB Dezimalzahl
    	sbc rBin1H,rBin2H ; Subtrahiere Carry und MSB
    	inc rmp ; Erhöhe den Zähler
    	rjmp Bin2ToDigita ; Weiter vergleichen/subtrahieren
    Bin2ToDigitc:
    	st z+,rmp ; Speichere das Ergebnis und erhöhe Zeiger
    	ret ; zurück
    kolision:
    	ori statusreg,0x80
    	reti
    2/3 Davon belegt die Umrechnungsroutine von bin nach ascii , aber es ist ja nicht
    die relevante Routine...



    Gruß Sebastian

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen