-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Roboter Linienverfolgung

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    30.04.2010
    Beiträge
    35

    Roboter Linienverfolgung

    Anzeige

    die Logik habe ich zuerst in Basic geschrieben und dann in Assembler, ich habe im Folgenden auch den Basic Code gepostet, damit man die Logik selbst rauslesen kann und ich sie nicht in einen Text irgendwie verschlüsseln muss.
    Der Hauptalgorithmus [Hauptprogramm ... JMP Hauptprogramm] funktioniert, aber scheinbar hat es noch Probleme mit der Messung der Schwellwerte auf sich, nur weis ich nicht was, bitte um Hilfe.

    basic code
    Code:
    'Erstellungsdatum: 21.Feb 2010
    'Ein Roboter, der einer 1,5cm breiten Linie nachfährt
    '
    'Initialisierungen*************************************************************
    $regfile = "m8def.dat"
    $crystal = 16000000
    $hwstack = 64
    $swstack = 64
    $framesize = 64
    
    'ADC-init
    Config Adc = Single , Prescaler = Auto , Reference = Avcc   'Konfiguriere ADC
    
    '--> Deklarationen von HP*******************
    Dim Messergebnisleft As Word                                'Miss Spannung am linken LDR
    Dim Messergebnismiddle As Word                              'Miss Spannung am mittleren LDR
    Dim Messergebnisright As Word                               'Miss Spannung am rechten LDR
    
    Dim Summe As Word
    
    Dim Schwellwertgespeichertmiddle As Eram Word
    Dim Speichermitteaus As Eram Word
    Dim Schwellwertmiddle As Word
    Dim Mitteaus As Word
    
    Dim Schwellwertgespeichertleft As Eram Word
    Dim Speicherlinksaus As Eram Word
    Dim Schwellwertleft As Word
    Dim Linksaus As Word
    
    Dim Schwellwertgespeichertright As Eram Word
    Dim Speicherrechtsaus As Eram Word
    Dim Schwellwertright As Word
    Dim Rechtsaus As Word
    
    Dim Weisslinks As Word
    Dim Weissmitte As Word
    Dim Weissrechts As Word
    
    Dim Zustand As Byte                                         'Hier wird der Aktuelle Stand der Sensren reingeschrieben
    
    Dim Letzterzustand As String * 10
    
    Config Debounce = 30                                        'Debaonce verzögerungszeit 30ms
    
    
    Schwellwertleft = Schwellwertgespeichertleft
    Schwellwertmiddle = Schwellwertgespeichertmiddle
    Schwellwertright = Schwellwertgespeichertright
    
    Linksaus = Speicherlinksaus
    Mitteaus = Speichermitteaus
    Rechtsaus = Speicherrechtsaus
    
    'EIN-AUSgänge******************************************************************
    Config Portb.1 = Output                                     'oc1a
    Config Portb.2 = Output                                     'oc1b
    Config Portc.3 = Output
    
    Config Pind.2 = Input
    
    'Hauptprogramm*****************************************************************
    Do
        Start Adc
    
        Messergebnisleft = Getadc(0)
        If Messergebnisleft > Schwellwertleft Then Zustand.0 = 1       'Else Zustand = 0
        If Messergebnisleft < Linksaus Then Zustand.0 = 0       'schreibe Information von sensor rechts in Byte Zustand
    
        Messergebnismiddle = Getadc(1)
        If Messergebnismiddle > Schwellwertmiddle Then Zustand.1 = 1       'Else Zustand = 0
        If Messergebnismiddle < Mitteaus Then Zustand.1 = 0     'schreibe Information von sensor mitte in Byte Zustand
    
        Messergebnisright = Getadc(2)
        If Messergebnisright > Schwellwertright Then Zustand.2 = 1       'Else Zustand = 0
        If Messergebnisright < Rechtsaus Then Zustand.2 = 0     'schreibe Information von sensor links in Byte Zustand
    
        Select Case Zustand
    
            Case &B00000001 :
                Portb = &B00000100
                Letzterzustand = "Links"                        'Merke dir den letzten Zustand
    
            Case &B00000100 :
                Portb = &B00000010
                Letzterzustand = "Rechts"
    
            Case &B00000010 :
                Portb = &B00000110
                Letzterzustand = "Mitte"
    
            Case &B00000000                                     'Falls undefinierter Zustand dann behalte letzten Zustand
                If Letzterzustand = "Links" Then
                    Portb = &B00000100
                End If
    
                If Letzterzustand = "Rechts" Then
                    Portb = &B00000010
                End If
    
        End Select
    
        Debounce Pind.2 , 0 , Messeschwellwert                  'Gehe zu Messeschwellwert wenn PinD2= 1
    
    Loop
    
    '*****************************InterruptRoutinen*******************************
    Messeschwellwert:
    
        Start Adc
    
        Weisslinks = Getadc(0)                                  'Zuerst alle 3 auf weißen Untergrund ausmessen
        Weissmitte = Getadc(1)                                  'Zuerst alle 3 auf weißen Untergrund ausmessen
        Weissrechts = Getadc(2)                                 'Zuerst alle 3 auf weißen Untergrund ausmessen
    
        Wait 1
    
        Portb = &B00000010
        Wait 3
    
        Portb = 0
        'Linker Schwellwert--------------
        Messergebnisleft = Getadc(0)                            'Schwarzer Untergrund wird ausgemessen
    
        Summe = Messergebnisleft + Weisslinks
        Schwellwertleft = Summe / 2                             'Bilde Mittelwert(Einschaltschwelle)
        Linksaus = Schwellwertleft - 20                         'Ausschaltschwelle
        Speicherlinksaus = Linksaus                             'Speichere in Eprom
        Schwellwertgespeichertleft = Schwellwertleft            'Speichere diesen im Eprom
        Wait 1
        '--------------------------------
    
        Portb = &B00000110                                      'Vorbereitung auf mittleren Schwellwert
        Wait 3
    
        Portb = 0
    
        'Mittlerer Schwellwert-----------
        Messergebnismiddle = Getadc(1)
    
        Summe = Messergebnismiddle + Weissmitte                 'Bilde Summe
        Schwellwertmiddle = Summe / 2                           'Bilde Mittelwert
        Mitteaus = Schwellwertmiddle - 20                       'Ausschaltschwelle
        Speichermitteaus = Mitteaus                             'Speichere in Eprom
        Schwellwertgespeichertmiddle = Schwellwertmiddle        'Speichere diesen im Eprom
        Wait 1
        '--------------------------------
    
        Portb = &B00000100                                      'Vorbereitung auf rechten Schwellwert
        Wait 3
    
        Portb = 0
    
        'Rechter Schwellwert-------------
        Messergebnisright = Getadc(2)
    
        Summe = Messergebnisright + Weissrechts
        Schwellwertright = Summe / 2
        Rechtsaus = Schwellwertright - 20                       'Ausschaltschwelle
        Speicherrechtsaus = Rechtsaus                           'Speichere in Eprom
        Schwellwertgespeichertright = Schwellwertright          'Schreibe Wert in EPROM
        Wait 1
        '--------------------------------
    
        Portb = &B00000100
        Waitms 500
        Portb = &B00000010
        Waitms 500
        Portb = &B00000100
        Waitms 500
        Portb = &B00000010
        Waitms 500
    
    Return
    assembler code
    Code:
    ;**********************************Header**************************************
    ;* Projektname:    Roboter-Linienverfolgung                                      *
    ;* Name des Erstellers:                                           *
    ;* Zuletzt aktualisiert: 7.4.2010                                              *
    ;* Beschreibung: Ein ROboter, der einer ca1,5-2cm breiten Linie nachfaährt      *                                                                          
    ;******************************************************************************
    
    
    ;*****************************Initialisierungen********************************
    .include "m8def.inc" ;Definitionsdatei des Mega8
    
    ;Stackpointer-init***********
        ldi r16, High(Ramend)
        out SPH, r16
    
        ldi r16, Low(Ramend)
        out SPL, r16
    
    ;ADC-init***********
        sbi ADCSRA, ADEN    ;ADC erlauben
        cbi ADCSRA, ADPS0    
        sbi ADCSRA, ADPS1    
        sbi ADCSRA, ADPS2    ;PRESCALER 64 
    
    ;*************************Variablendeklarationen*******************************
    .def Messergebnisleft = r16
    .def Messergebnisright = r17
    .def Messergebnismiddle = r18
    
    .def Schwellwertleft = r19
    .def Schwellwertmiddle = r20
    .def Schwellwertright = r21
    
    .def Linksaus = r22
    .def Mitteaus = r23
    .def Rechtsaus = r24
    
    .def Linienerkennung = r29
    
    ;*****************************Ein-Ausgänge*************************************
        sbi DDRB, 1        ;PORTB.1 als Ausgabeport
        sbi DDRB, 2        ;PORTB.2 als Ausgabeport
    
        cbi DDRD, 2        ;PORTD.2 als Eingabeport
        sbi PORTD, 2    ;Pullups aktivieren
    
        
    ;*****************************Hauptprogramm************************************
    Hauptprogramm:
    clr Linienerkennung ;Virbereitung auf neue Messung
            
    ;TEIL1...................START.......................Messe aktuelle Werte der Linie aus
    rcall    StartADConChanel0_8bit            
                in Messergebnisleft, ADCH
    rcall    StartADConChanel1_8bit            
                in Messergebnismiddle, ADCH
    rcall    StartADConChanel2_8bit            
                in Messergebnisright, ADCH        
    
    ;TEIL2...................START.......................Erstelle aktuelle Werte für Linienerkennung
            cp Messergebnisleft, Schwellwertleft    ;Vergleiche LDR links aktuell mit vorher ausgerechnetem
                                                    ;Schwellwert
            brlo FahreFort0                                    
            ldi Linienerkennung, 0b00000100                ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                                                    
    FahreFort0:
    
    
    
            cp Messergebnismiddle, Schwellwertmiddle    ;Vergleiche LDR mitte aktuell mit vorher ausgerechnetem
                                                        ;Schwellwert
            brlo FahreFort1                                    
            ldi Linienerkennung, 0b00000010                ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                                                    
    FahreFort1:                                        ;wenn kleiner dann lass es auf Null
            
    
    
            cp Messergebnisright, Schwellwertright    ;Vergleiche LDR rechts aktuell mit vorher ausgerechnetem
                                                    ;Schwellwert
            brlo FahreFort2                                    
            ldi Linienerkennung, 0b00000001                ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
                                                    
    FahreFort2:                                        ;wenn kleiner dann lass es auf Null    
    
    ;TEIL3...................START.......................Auswertung-->Motorsteuerung
            
            sbrc Linienerkennung, 2    
                ldi r28, 0b00000010        ;Motor = Rechts
                out PORTB, r28
            sbrc Linienerkennung, 1        
                ldi r28, 0b00000110        ;Motor = Beide
                out PORTB, r28
            sbrc Linienerkennung, 0        
                ldi r28, 0b00000100        ;Motor = Links
                out PORTB, r28
    ;TEIL4...................START.......................Falls neie Messung vorgesehen dann mache sie zuerst
            sbis PIND, 2                ;Überprüfe PIND.0
            rcall Messeschwellwert         ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
    rjmp Hauptprogramm                    ;ansosnten wieder von vorne
    ;*********************************************************************************
    
    
    
    ;***********************Unterprogramme/Funktionen******************************
    Messeschwellwert:
    rcall    StartADConChanel0_8bit            ;Messe linken LDR bei weißem Untergrund
                in r25, ADCH
    rcall    StartADConChanel1_8bit            ;Messe mittleren LDR bei weißem Untergrund
                in r26, ADCH
    rcall    StartADConChanel2_8bit            ;Messe rechten LDR bei weißem Untergrund
                in r27, ADCH
    cbi PORTB, 1
    cbi PORTB, 2
    rcall Wait1
    sbi PORTB, 1
    rcall Wait3
    cbi PORTB, 1
    
        ;Linker Schwellwert--------------
        push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
        clr r28    ;lösche registerinhalt in r28 zur neuen Anwendung
        rcall    StartADConChanel0_8bit
                    in Messergebnisleft, ADCH     ;Messe LDRleft bei schwarzem Untergrund
                    add    r25, Messergebnisleft    ;Addiere Weißen Wert mit Schwarzen Wert
                    BRCC RechneWeiter0;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
                    ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
                    ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
                    ;ergibt den richtigen Schwellwert
                    
                    ldi r28, 128    ;wenn Carry 1 dann lade 128 in carry-register
    
        RechneWeiter0:                ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
                    mov r16, r25    ;Den Dividenten ins Register der Division kopieren
                                    ;Diese Register ist als Messergebnisleft definiert
                                    ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
                    ldi r17, 2        ;Den Divisor ins Register der Division laden
                                    ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                                    ;da hier nicht verwendet
                    rcall Division
                                    ;Ergebnis steht jetzt in Register Ergebnis (r30)
    
                    add r28, Ergebnis    ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                                        ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                                        ;dass es kleinere Spannungen auch geben kann, daher muss
                                        ;ein möglicher Überlauf berücksichtigt werden
                    
                    ;Endergebnis steht jetzt in r28
    
                    mov Schwellwertleft, r28    ;Kopiere den Schwellwert in definiertes Register
                                                ;für diesen Wert
        rcall Wait1  
        pop r28      
        ;--------------------------------
    
    sbi PORTB, 1
    sbi PORTB, 2                                      
    rcall Wait3
    cbi PORTB, 1
    cbi PORTB, 2
    
        ;Mittlerer Schwellwert-----------
        push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
        clr r28    ;lösche registerinhalt in r28 zur neuen Anwendung
        rcall    StartADConChanel1_8bit
                    in Messergebnismiddle, ADCH     ;Messe LDRleft bei schwarzem Untergrund
                    add    r26, Messergebnismiddle    ;Addiere Weißen Wert mit Schwarzen Wert
                    BRCC RechneWeiter1;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
                    ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
                    ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
                    ;ergibt den richtigen Schwellwert
                    
                    ldi r28, 128    ;wenn Carry 1 dann lade 128 in carry-register
    
        RechneWeiter1:                ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
                    mov r16, r26    ;Den Dividenten ins Register der Division kopieren
                                    ;Diese Register ist als Messergebnisleft definiert
                                    ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
                    ldi r17, 2        ;Den Divisor ins Register der Division laden
                                    ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                                    ;da hier nicht verwendet
                    rcall Division
                                    ;Ergebnis steht jetzt in Register Ergebnis (r30)
    
                    add r28, Ergebnis    ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                                        ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                                        ;dass es kleinere Spannungen auch geben kann, daher muss
                                        ;ein möglicher Überlauf berücksichtigt werden
                    
                    ;Endergebnis steht jetzt in r28
    
                    mov Schwellwertmiddle, r28    ;Kopiere den Schwellwert in definiertes Register
                                                ;für diesen Wert
        rcall Wait1  
        pop r28      
        ;--------------------------------
    
    sbi PORTB, 2 
    rcall Wait3
    cbi PORTB, 2
    
        ;Rechter Schwellwert-------------
         push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
        clr r28    ;lösche registerinhalt in r28 zur neuen Anwendung
        rcall    StartADConChanel2_8bit
                    in Messergebnisright, ADCH     ;Messe LDRleft bei schwarzem Untergrund
                    add    r27, Messergebnisright    ;Addiere Weißen Wert mit Schwarzen Wert
                    BRCC RechneWeiter2;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
                    ;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür 
                    ;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
                    ;ergibt den richtigen Schwellwert
    
                    ldi r28, 128    ;wenn Carry 1 dann lade 128 in carry-register
    
        RechneWeiter2:                ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
                    mov r16, r27    ;Den Dividenten ins Register der Division kopieren
                                    ;Diese Register ist als Messergebnisleft definiert
                                    ;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
                    ldi r17, 2        ;Den Divisor ins Register der Division laden
                                    ;Dieses Register ist Messergebnismiddle, dass tört aber keinen
                                    ;da hier nicht verwendet
                    rcall Division
                                    ;Ergebnis steht jetzt in Register Ergebnis (r30)
    
                    add r28, Ergebnis    ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
                                        ;bei verschiedenen Linienfarben unterschiedlich, kann es sein
                                        ;dass es kleinere Spannungen auch geben kann, daher muss
                                        ;ein möglicher Überlauf berücksichtigt werden
                    
                    ;Endergebnis steht jetzt in r28
    
                    mov Schwellwertright, r28    ;Kopiere den Schwellwert in definiertes Register
                                                ;für diesen Wert
        rcall Wait1  
        pop r28      
        ;--------------------------------
    
    ret
    ;*************************************
    ;*************************************
    
    
    ;################################################################################
    .include "Division8Bit+Rest.asm"     ;8 Bit division        //call division
    .include "wait1.asm"
    .include "wait3.asm"
    .include "ReadEEPROM.asm"            ;                //call Read_EEPROM
    .include "WriteEEPROM.asm"            ;                //call Write_EEPROM
    .include "StartADConCHANEL0_8bit.asm"
    .include "StartADConCHANEL1_8bit.asm"
    .include "StartADConCHANEL2_8bit.asm"
    ;################################################################################
    In Aufrufe.txt sind die Unterprogramme die ich geschrieben habe
    ich habe auch ausführlichst rauskommentiert

    lg andy
    Angehängte Dateien Angehängte Dateien

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.05.2009
    Ort
    Sinsheim b. Heidelberg
    Alter
    24
    Beiträge
    519
    Hast du eventuell einen Schaltplan?

    Gruß

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    30.04.2010
    Beiträge
    35
    ich habe hier mal ein Prinzipschaltbild reingemacht die Sensoren liefern korrekte Werte und mit dem Basic Programm funktioniert es auch
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken ibhiffo.png  

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.05.2009
    Ort
    Sinsheim b. Heidelberg
    Alter
    24
    Beiträge
    519
    So wie ich das jetzt sehe, hast du das Quarz falsch angeschlossen. Es muss zwischen PB6 unf PB7 angeschlossen sein und noch mit einem 22pf Kondensator gegen GND.
    Ich habe früher in ASM programmiert und mache heute eigentlich nur noch Basic. Der Basic Code sieht in ordnung aus.

    Gruß

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    30.04.2010
    Beiträge
    35
    So wie ich das jetzt sehe, hast du das Quarz falsch angeschlossen. Es muss zwischen PB6 unf PB7 angeschlossen sein und noch mit einem 22pf Kondensator gegen GND.
    ich glaub schon, dass er richtig angeschlossen ist, es ist nämlich ein Quarzoszillator, hast sicher überlesen

    Ich habe früher in ASM programmiert und mache heute eigentlich nur noch Basic. Der Basic Code sieht in ordnung aus.
    Bis jetzt hat mir kein einziges FOrum weiterhelfen können, schön langsam verzweifle ich an dem Assembler

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Andy11jj,

    na, zum Verzweifeln ist's aber noch viel zu früh ! Erkläre doch 'mal näher, warum Du meinst, die Schwellwertmessung funktioniere nicht richtig!

    Ausserdem würde mich interessieren, was diese Zeilen
    Code:
    cbi PORTB, 1
    cbi PORTB, 2
    rcall Wait1
    sbi PORTB, 1
    rcall Wait3
    cbi PORTB, 1
    bedeuten sollen. Die hast Du gar nicht kommentiert. Ist denn an den Pins 1 und 2 von PORTB ausser den Motoren sonst noch was angeschlossen?

    Ciao,

    mare_crisium

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    30.04.2010
    Beiträge
    35
    Erkläre doch 'mal näher, warum Du meinst, die Schwellwertmessung funktioniere nicht richtig!
    Die Messung macht er zwar durch und zurückspringen tut er scheinbar auch, aber wenn den robo dann hin und her über die linie bewege dann haben die motoren immer nur einen Zustand, keine ahnung warum.

    Ausserdem würde mich interessieren, was diese Zeilen
    Code:

    cbi PORTB, 1
    cbi PORTB, 2
    rcall Wait1
    sbi PORTB, 1
    rcall Wait3
    cbi PORTB, 1

    bedeuten sollen. Die hast Du gar nicht kommentiert. Ist denn an den Pins 1 und 2 von PORTB ausser den Motoren sonst noch was angeschlossen?
    naja parallel (und vor der Treiberschaltung) sind noch 2 LEDs mit Rv geschalten, diese sagen mir beim Messen welcher Sensor ausgemessen wird, und wenns die LEDs ausgehen dann hat er die Messung durchgeführt und im nächsten schritt gehen beide auf, dh für mich: Stell den Roboter in die Mitte um den mittleren Sensor auszumessen, ...

    Das Hauptprogramm funktioniert. Das habe ich im AVR Studio simuliert und es haut hin, alle werte natürlich manuell eingetragen usw, aber beim Messeschwellwert geht es iwie nicht, wobei es Softwaremäßig passen sollte

    lg andy

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Andyj11,

    nee, Deine Erklärung für die "cbi"- und "sbi"-Anweisungen verstehe ich nicht. Weiter oben im Programm steuerst Du die Motoren so an

    Code:
    ;TEIL3...................START.......................Auswertung-->Motorsteuerung
           
            sbrc Linienerkennung, 2   
                ldi r28, 0b00000010        ;Motor = Rechts
                out PORTB, r28
            sbrc Linienerkennung, 1       
                ldi r28, 0b00000110        ;Motor = Beide
                out PORTB, r28
            sbrc Linienerkennung, 0       
                ldi r28, 0b00000100        ;Motor = Links
                out PORTB, r28
    Das lese ich so, dass der rechte Motor an Pin1 (r28 = 0b00000010) angeschlossen ist und der linke an Pin2 (r28 = 0b00000100).
    Wenn PORTB aus Ausgang konfiguriert ist, haben die Anweisungen

    Code:
                ldi r28, 0b00000010        ;Motor = Rechts
                out PORTB, r28
    exakt dieselbe Wirkung wie
    Code:
               sbi PORTB,1
    d.h. es sieht so aus, als schaltetest Du mit dem Codestück, mit dem Du die LEDs steuern willst, auch die Motoren ein und aus.

    Ciao,

    mare_crisium

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    30.04.2010
    Beiträge
    35
    d.h. es sieht so aus, als schaltetest Du mit dem Codestück, mit dem Du die LEDs steuern willst, auch die Motoren ein und aus.
    Ja das ist schon richtig, aber nur während der Messung, das hat überhaupt keine Auswirkung auf das Hauptprogramm.

    Nochmal wegen dem sbi und cbi beim Messen:
    Da ich ja jeden der 3 Sensoren einzeln ausmessen will, kann ich den Roboter nicht einfach auf die Linie Stellen und dann messen. Also habe ich mir folgendes überlegt:
    zuerst messe ich alle Werte der Sensoren wenn sie auf Weiß stehen

    dann jeden einzelnen auf Schwarz.

    Da ich aber jetzt jeden einzelnen auf schwarz messen muss, und ich mir schwertuhe Zeiten zu merken, symbolisiere ich das einfach am PORTB (dort wo die Motoren sind (diese sind aber zudem Zeitpunkt von Stromkreis getrennt damit sie sich nicht drehen während der Messung))
    also Schritte:
    -Messe alle auf weiß das geht ja einfach, da ich ihn nur hinstelle und dann den Taster drücke

    -Jetzt nach der Messung leuchtet Portb,1 auf, dh für mich und für das Programm heißt das, dass er nach den 3 Sekunden den linken Sensor ausmessen wird, also stelle ich ihn so auf die Linie, damit der linke Sensor auf der Linie steht

    -Nach dieser Messung leuchten beide auf, dh Mittlerer Sensor ist dran, ich stelle ihn also so auf, damit der mittlere Sensor auf der Linie steht.

    -Und zu allerletzt leuchtet der rechte auf, --> Rechter Sensor auf Linie, weil in 3 Sek der rechte gemessen wird


    ------------------------------------
    Wenn PORTB aus Ausgang konfiguriert ist, haben die Anweisungen

    Code:

    ldi r28, 0b00000010 ;Motor = Rechts
    out PORTB, r28

    exakt dieselbe Wirkung wie
    Code:
    sbi PORTB,1
    Problem ist jetzt halt bei deinem Vorschlag, dass ich das sbrc streichen kann und sich wahrscheinlich der Wert im nächsten Befehl ändert^^

    das ganze kannst du dir auch im Basic Programm anschauen, ist vielleicht übersichtlicher. Im Assembler ist es wirklich unübersichtlich, daher auch vielleicht das Missverständnis von dir

    lg andy

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Andy11jj,

    nee, Assembler ist nur unübersichtlich, wenn man unübersichtlich schreibt ! Guck' mal: Die Neuberechnung der Schwellwerte kannst Du doch locker in je eine Prozedur auslagern. Z.B.

    Code:
    /* 
    PROZEDUR UPDATE_SCHWELLE_LINKS
    
    */
    
    UPDATE_SCHWELLE_LINKS
    	push r25
    	in r25,SREG
    	push xl
    	push xh
    
    ; Messung links signalisieren
    	cbi PORTB, 1 	; LEDs an PORTB.1 und PORTB.2 aussschalten
    	cbi PORTB, 2
    	rcall Wait1		; Pause mit LEDs dunkel
    	sbi PORTB, 1	; LED an PORTB.1 einschalten
    	rcall Wait3		; Pause mit LED hell
    	cbi PORTB, 1	; LED an PORTB.1 ausschalten
    
    ; Messung durchführen. Messwert des linken LDR auf weißem Untergrund steht 
    ; in Register WeissWertLinks 
    	rcall StartADConChanel0_8bit ; 
        in xl, ADCH		; Schwarzmesswert nach xl
    
    ; Mittelwert von Weiss- und Schwarzwert bilden
    	clr xh			; 
    	add xl,WeissWertLinks ; 2-Byte Addition ausführen
    	adc xh,xh		; Übertrag nach xh berücksichtigen
    	lsr xh			; Division durch 2 entspricht Rechtsschieben um ein Bit
    	ror xl			; neuer Schwellwert links steht jetzt in xl
    
    ; neuen Schwellwert nach SchwelleLinks verschieben
    	mov SchwelleLinks,xl
    
    	pop xh
    	pop xl
    	out SREG,r25
    	pop r25
    	ret
    
    ;*************************************
    Analog kannst Du das auch für Mitte und Rechts machen. Weil hier xhl verwendet werden, sparst Du Dir eine Menge Jongliererei mit den Registern (das kommt davon, wenn man .defs arbeitet ). Durch das Auslagern in Prozeduren, bei denen Du die benutzten Register sauber (mit "push" und "pop") sichern kannst, brauchst Du Dir keine Sorgen zu machen, dass Du aus Versehen mal ein mit ".def" belegtes Register überschreibst.

    Die Stelle, die jetzt so unübersichtlich aussieht, wird dann ganz übersichtlich:

    Code:
    ; TEIL4...................START.......................
    ; Falls neue Messung vorgesehen dann mache sie zuerst
    	sbic PIND, 2                ;Überprüfe PIND.0
    	rjmp Hauptprogramm          ; Wenn PIND.0 = 1 (Taster nicht betätigt) -> keine Messung
    	
    ; Taster betätigt -> Messung
    ; zuerst die WeissWerte messen
    	rcall StartADConChanel0_8bit            ;Messe linken LDR bei weißem Untergrund
    	in WeissWertLinks, ADCH
    	rcall StartADConChanel1_8bit            ;Messe mittleren LDR bei weißem Untergrund
    	in WeissWertMitte, ADCH
    	rcall StartADConChanel2_8bit            ;Messe rechten LDR bei weißem Untergrund
    	in WeissWertRechts, ADCH
    ; jetzt die neuen SchwellWerte berechnen
    	rcall UPDATE_SCHWELLE_LINKS				; Schwellwert Links fertig
    	rcall UPDATE_SCHWELLE_MITTE				; Schwellwert Mitte fertig
    	rcall UPDATE_SCHWELLE_RECHTS			; Schwellwert Rechts fertig
    
    rjmp Hauptprogramm                    ; ...und wieder von vorne
    Es kann sein, dass Dein Problem damit zu tun hat, dass Du den Inhalt von SREG nicht sicherst. Nur keine Bange vor "push" und "pop" !

    Ciao,

    mare_crisium

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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