-         

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

Thema: Komisches Drehgeberverhalten!

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360

    Komisches Drehgeberverhalten!

    Anzeige

    Ich habe folgenden Code um einen Drehgeber auszuwerten (Wird bei jedem Change des Channels A ausgelöst.):

    Code:
    Isr_incremental_encoder:
      If Phase_b <> Phase_a Then
        Decr Ist
      Else
        Incr Ist
      End If
    
      If Dira = 1 Then
       If Ist => 1000 Then
        Dira = 0
        Dirb = 1
       End If
      End If
    
      If Dirb = 1 Then
       If Ist =< 0 Then
        Dira = 1
        Dirb = 0
       End If
      End If
    
      Print Ist
    Return
    das ganze geht auch ne weile gut aber plötzlich springt er auf >10000 Ink hoch und macht nur noch misst.

    Auszug aus Protokoll:

    508
    509
    510
    511
    512
    12846
    12846
    12846
    12847
    ...

    an was kann das liegen und wie kann man das Problem am besten beseitigen?


    tobi


    edit1: ich hab das ganze auch mal ohne die Motoransteuerung getestet sondern den Motor direkt ans netzteil gehängt. Bringt nix - gleiches Problem

    edit2: könnte es vllt an der PWM im hintergrund auf timer0 liegen?

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    If Phase_b <> Phase_a Then
    Decr Ist
    Else
    Incr Ist
    End If
    Versteh' ich nicht ganz. Meist macht man ISR bei einer bestimmte Flanke von channel-A, und je nachdem ob channel B dann oben oder unten ist, gehts rauf oder runter.

    Andere Frage; wie sind die variablen definiert ? mit vorzeichen ? ohne ?

    Edit1 Natürlich kann ein wilder Funkenflug stören. Glaub ich aber erstmal eher nicht.
    Edit2 Den Zusammenhang seh ich so nicht.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360
    der code vergleicht bei jeder flanke von Channel A die Channels und operiert dann. Dies funktioniert auch im großen und ganzen. Ich häng morgen mal den oszi dazu und mal schaun.

    Was mich wundert: der selbe algorythmus ist schon mal bei einer anderne Platine verwendet worden die nur zählen musste - also nix arbeiten musste außer plus und minus. und da hat er 1a funktioniert.

    da ich mit Bascom arbeite und Bascom den timer0 gern missbraucht und ich die PWM durch registersetzen auf timer0 gelegt hab frage ich mich ob das das Problem sein könnte?

    funkenflug schließ ich mal aus, da er von 512 auf 12846 hochgeflogen ist.

    tobi

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    30
    Beiträge
    563
    Erklär mir bitte den Zusammenhang zwischen Timer0, PWM, und Zähler, daran könnte es liegen. Zb wenn du die Timerintterupts auswertest, kann es da eine Kollision geben. Hast du bei den Interrupts vorher die Arbeitsregister auch alle brav in den Stack hinterlegt, und alle brav -in umgekehrter Reihenfolge- zurückgeladen?

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360
    ich hab hier mal ein bisschen code:

    Code:
    '--- [ Inizialize compiler ] ---------------------------------------------------
    $regfile = "m168def.dat"
    $crystal = 16000000
    $baud = 9600
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    
    '--- [ Config devices and timers ] ---------------------------------------------
    
    Config Pind.6 = Output
    Pwm_out Alias Pind.6
    
    Config Portc.0 = Output
    Dira Alias Portc.0
    
    Config Portc.1 = Output
    Dirb Alias Portc.1
    
    Audio Alias Portd.5
    
    Config Scl = Portc.5
    Config Sda = Portc.4
    
    Config Pinc.3 = Input
    Inp_start Alias Pinc.3
    
    Config Pinc.2 = Input
    Inp_libelle Alias Pinc.2
    
    Config Portb.0 = Output
    Led_red Alias Portb.0
    
    Config Portb.1 = Output
    Led_yellow Alias Portb.1
    
    Config Portb.2 = Output
    Led_green Alias Portb.2
    
    Inp_stop Alias Pind.2
    
    Phase_a Alias Pind.3
    Phase_b Alias Pind.4
    
    'Timer0 as PWM
    Tccr0a = &B11000001
    Tccr0b = &B00000001
    Tcnt0 = &B00000000
    Timsk0 = &B00000000
    Tifr0 = &B00000000
    Ocr0a = 255
    
    'Timer1 as clock
    Config Timer1 = Timer , Prescale = 256
    Const Clock = 3036
    
    '--- [ Declare SUBs ] ----------------------------------------------------------
    
    Declare Sub Direction(byval Var As Byte)
    Declare Sub Speed(byval Var As Byte)
    Declare Sub Engine(byval Var As Integer)
    Declare Sub Snd(byval Freq As Integer)
    
    '--- [ Declare variables ] -----------------------------------------------------
    
    Dim Daten(30) As String * 19                                'Messdaten
    
    Dim Soll As Integer                                         'Sollwert
    Dim Nextsoll As Integer                                     'Nächster Sollwert
    Dim Ist As Integer                                          'Ist Position
    Dim Hits As Byte                                            'Anschläge
    Dim Libelle As Bit                                          'Libelle
    Dim Result As Bit                                           'Messungsergebnis
    
    Dim Action As Byte                                          'Aktuelle Aktion
    Dim Adminmode As Bit                                        'Administrationsmodus
    
    Dim Buffer As String * 5                                    'RS232 Buffer
    
    Dim Year As Integer                                         'Jahr
    Dim Month As Integer                                        'Monat
    Dim Day As Integer                                          'Tag
    Dim Hour As Integer                                         'Stunde
    Dim Minute As Integer                                       'Minute
    Dim Second As Integer                                       'Sekunde
    Dim Tresult As String * 5                                   'Zeitstring
    Dim Dresult As String * 8                                   'Datumstring
    
    Dim B1 As Byte                                              'HV
    Dim I1 As Integer                                           'HV
    Dim I2 As Integer                                           'HV
    Dim S1 As String * 1                                        'HV
    Dim S2 As String * 1                                        'HV
    
    Dim Start_setted As Bit                                     'S_HV
    
    '--- [ Inizialize variables and constants ] ------------------------------------
    
    Const Fwd = 1
    Const Bwd = 0
    
    Const Limit = 9900
    Const Cm_ink = 44
    
    Const Volhigh = 500
    Const Volmiddle = 800
    Const Vollow = 1500
    
    Start_setted = 0
    
    Soll = 0
    Nextsoll = 0
    Ist = 0
    Hits = 0
    Libelle = 0
    Result = 0
    
    Action = 0
    Adminmode = 0
    
    Buffer = ""
    
    Year = 2000
    Month = 1
    Day = 1
    Hour = 0
    Minute = 0
    Second = 0
    Tresult = ""
    Dresult = ""
    
    '--- [ Inizialize Interrupts ] -------------------------------------------------
    
    Sreg.7 = 0
    
    On Int0 Isr_stop                                            'On Rising Edge
    On Int1 Isr_incremental_encoder                             'On Pinchange
    On Pcint1 Isr_pc1
    On Timer1 Isr_clock                                         'On Timer1
    On Urxc Isr_data                                            'On Urxc
    
    Eicra = &B00000111
    Eimsk = &B00000011
    Eifr = &B00000011
    
    Pcicr = &B00000010
    Pcifr = &B00000010
    Pcmsk2 = &B00000000
    Pcmsk1 = &B00001100
    Pcmsk0 = &B00000000
    
    Enable Timer1
    Enable Urxc
    
    Sreg.7 = 1
    
    '--- [ Start secuence ] --------------------------------------------------------
    
    Echo Off
    
    Gosub Clrdata
    
    Ist = 0
    
    Dira = 1
    Dirb = 0
    Call Speed(0)
    '--- [ Main loop ] -------------------------------------------------------------
    
    Do
     nop
    Loop
    End
    
    '--- [ Interrupt service routine ] ---------------------------------------------
    
    Isr_incremental_encoder:
      If Phase_b <> Phase_a Then
        Decr Ist
      Else
        Incr Ist
      End If
    
      If Dira = 1 Then
       If Ist => 1000 Then
        Dira = 0
        Dirb = 1
       End If
      End If
    
      If Dirb = 1 Then
       If Ist =< 0 Then
        Dira = 1
        Dirb = 0
       End If
      End If
    
      Print Ist
    Return
    schaut bitte mal drüber

    wegen meinem vorredner
    da Bascom ja allenmöglichen schrott mit timer0 anstellt und dann der chip intern crasht? ka? ich kenn das Problem nicht, aber ich muss es finden......

    tobi

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    30
    Beiträge
    563
    Leider kenn ich mich mit Bascom nicht aus, da ich kleinere uC-s (AtMega in Assembly größere in C progge.... Ich seh aber da keine Hinterlegung im Stack bei der Interruproutine.... Ausserdem müssen bei zugriffen auf die Timer-Register vorher die Interrupts gesperrt werden, auch bei den OCRx Registern für dei PWM Grenze

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360
    ah, ok...
    also bevor ich das ocr register ändre muss ich das sreg.7 auf 0 setzen. aber ich schätze das das nicht die ursache für den crash ist.

    gibt es noch andere mögliche ursachen?

    tobi

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360
    Also, ich hab mal alles auf ne RNControl 1.4 ausgelagert (16 MHz) die nur für das Zählen zuständig ist.
    Das Drehgeberrad benötig 3 sekunden für 1 umdrehung (eine Umdrehung hat laut datenblatt 512 ink)
    (das Rad dreht sich nicht konstant sondern "wackelt")

    ich hab mal den Oszi drangehängt und auf 10 µS eingestellt.
    In dieser Auflösung bekomme ich 14 Flanken die der Chip verwalten muss.
    Ich weiss leider nicht wie das bei nem oszi ist? ist dann die ganze breite 10 µS oder ein Rasterkästchen? WIe ist das in der regel.
    Denn wenn 10µS eine Breite sind dann:
    14 flanken = 10 µS
    14 flanken = 0,000001 S
    1 S = 1400000 flanken!!!!!!!!!!
    wenn meine befürchtung stimmt bekomme ich 1,4 MHz impulse.

    ich habe noch eine logs gemacht. also das springen auf 12000 ist nun weg. leider bekomme ich eben bei der Geschwindigkeit eine zu große differenz. Statt 0 eben -100 oder so in meinem fall ist das zu viel.

    der basic code steht ja oben.

    wäre es möglich das ganze in assembler zu schreiben das es schneller ist und es wieder in das basic zu implementieren?

    wäre echt nett wenn ihr mir helft!

    mfg
    tobi

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360
    Ich habe jetzt meine Hex Datei decompiliert. Im Anhang habe ich meine Basic und Assembler Datei.
    Die Basic datei hat ca. 30 effektive zeilen
    die assembler datei >200!

    kann einer der assemblerprofies die datei mal schnauen?

    tausend dank!

    Mfg
    tobi
    Angehängte Dateien Angehängte Dateien

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    30
    Beiträge
    563
    Wenn dein Rad wackelt, kann es ja sein, dass es einmal kurz "zurückwackelt" nicht? Und daher können ja so grosse Zahlen kommen. Wenn dein Rad aber in 3 Sek 360° macht, und du 512 Positionen hast, bekommst du jede 3/512=0.005856s also 58.56ms einen Interrupt. Das ist für ein uC mit 16MHz eine Ewigkeit. In dieser Zeit macht es fast 100.000 Zyklen, also sprich 100.000 Befehle werden verarbeitet.... Ich verstehe also ehrlich gesagt nicht, was du mit dem Oszi gemacht hast. Ausserdem wir von den Flanken meistens nur eine verarbeitet (steigend oder fallend), aber es stimmt auch so nicht.
    Assemby hat selbstverständlich mehr Zeilen, das ist ja fast reine Computercode. Leider hab ich jetzt keine Zeit, dir das durchzuschauen.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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