-         

Ergebnis 1 bis 8 von 8

Thema: Kleine Unstimmigkeit beim Auslesen eines RC-Signals

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317

    Kleine Unstimmigkeit beim Auslesen eines RC-Signals

    Anzeige

    Hallo,

    ich bin seit einigen Tagen dabei eine Schaltung für ein RC-Modell zu programmieren. Dabei soll ein Empfängerkanal ausgewertet werden um Funktionen vom Sender aus zu schalten.
    Soweit klappt das auch ganz gut, nur die gemessenen Zeiten hauen nicht ganz hin.
    Der Impuls ist ja von 1ms bis 2ms lang (Mittelstellung also 1,5ms)

    Mit diesem Programm habe ich mir eine kleine Test Schaltung erstellt wo die Werte auf dem LCD angezeigt werden:
    Code:
    $regfile = "m16def.dat"
    $crystal = 8000000
    
    
    Config PORTB.0 = Output
    Config portb.1 = Output
    Config portb.2 = Output
    Config portB.3 = Output
    Config portB.4 = Output
    Config portB.5 = Output
    Config PORTD.2 = Input
    
    
    Config Timer0 = TIMER , PRESCALE = 8                        'Timer0 zur auswertung des Empfängerimpulses
    
    Config Lcdpin = Pin , Db4 = PortC.0 , Db5 = PortC.1 , Db6 = PortC.2 , Db7 = PortC.3 , E = Portc.5 , Rs = Portc.4
    Config LCD = 20 * 4
    
    Config INT0 = FALLING
    
    On OvF0 Tim0_isr                                            'Routine beim Überlauf Timer0
    On Int0 Int0_isr                                            'Routine für externen Interrupt an Int0 (Empfängerimpuls)
    
    Enable Interrupts
    Enable Timer0
    Stop Timer0
    Enable INT0
    
    Dim imp_memory1 as Bit
    Dim imp_memory2 as Bit
    Dim Imp_Flag as Byte
    Dim Impulszeit as Byte
    Dim Impuls as Byte
    Const Timerwert0 = 245
    
    
    PortD.2 = 1                                                 'PullUp einschalten
    
    Timer0 = Timerwert0
    
    'Vergabe von Aliasnamen
    Pos_Re_Li Alias PortB.0
    ACL_WS_Re Alias PortB.1
    ACL_WS_Li Alias PortB.2
    ACL_RT_Seitenruder Alias PortB.3
    ACL_RT_Rumpf Alias PortB.4
    Scheinwerfer Alias PortB.5
    
    
    'Voreinstellen von Variablen
    Imp_Flag = 0
    LCD_Flag = 0
    Impulszeit = 0
    
    InitLCD
    CLS
    Locate 1 , 1
    LCD "  Servoimpulstest"
    
    Do
    
    'Auswertung des Servoimpulses zum schalten Kanal 1
     If Impulszeit >= 95 and Impulszeit <= 119 and imp_memory1 = 0 then
    
      If Scheinwerfer = 0 then
       Scheinwerfer = 1
      else
       Scheinwerfer = 0
      end IF
      Imp_memory1 = 1
     End If
    
    'Auswertung des Servoimpulses zum schalten Kanal 2
     If Impulszeit >= 50 and Impulszeit <= 70 and imp_memory2 = 0 then
    
      If ACL_RT_Rumpf = 0 then
       ACL_RT_Rumpf = 1
      else
       ACL_RT_Rumpf = 0
      end IF
      Imp_memory2 = 1
     End If
    
    'Auswertung des Servoimpulses zum rücksetzen des Memory Flags
     If Impulszeit >= 85 and Impulszeit <= 90 then
      imp_memory1 = 0
      imp_memory2 = 0
     End If
    
    
    
     Locate 2 , 1
     LCD "Impuls:"
     Locate 2 , 9 : LCD Impulszeit ; "   "
    
    
    Loop
    
    'Interruptrotiene Timer0 Overflow
    Tim0_isr:
     Timer0 = Timerwert0                                        'Timerregister voreinstellen
     incr Impuls
    Return
    
    
    'Interruptrotine Int0
    Int0_isr:
     If imp_flag = 0 then
      Impuls = 0
      imp_flag = 1
      Start TIMER0
      Config Int0 = Rising
     else
      Stop TIMER0
      Impulszeit = Impuls
      imp_flag = 0
      Config Int0 = Falling
     end IF
    
    Return
    
    End
    Die angezeigten angezeigten Werte sind
    Pos. 1 = 52
    Mitte = 82
    Pos.2 = 110

    Mit meiner gewählten Timerkonfiguration sollte rechnerisch ein Wertebereich von 100 - 200 erreicht werden.

    Wenn ich den Prescale des Timers von 8 auf 1 verringere, dann sollten sich die Werte ja eigentlich verachtfachen, das tun sie leider aber nicht.

    Meine Frage ist nun:
    Ist mein Code in den Interruptroutinen so Zeitintensiv das dieser Messfehler zustande kommt? Denn wir unterhalten uns ja über einen Bereich von 0,XX ms
    Oder mache ich einen anderen Fehler (Denkfehler)

    Ich würde mich freuen wenn mir da jemand einen Tipp geben kann.
    Danke schon einmal im Voraus
    mfG Henry

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hi Henry,

    deine Timer0 Einstellung (Prescaler 8, Startwert 245) bringt eine Frequenz von ca. 56737 Hz.
    Damit kann der Zähler bei 1,5 ms Impulsdauer einen Wert von 85 anzeigen, das deckt sich gut mit deinem Ergebnis 82.

    Also: Dein Programm macht das, was du ihm beigebracht hast.

    Gruß Dirk

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Hm, dann rechne ich da wohl falsch.
    Bin schon einmal froh das der Controller wenigstens das macht was ich ihm sage

    Mein Lösungsweg war:
    bei 8MHz und einem Prescale von 8 wird das Timerregister mit 1MHz hochgezählt. Das währen dann 0,000001 Sec.

    Dann habe ich den Startwert meinen Startwert von 245 , wären dann 11 bis zum Überlauf (stelle beim Schreiben fest das es 246 sein sollten).
    Wenn dann also der Timer alle 0,000001 Sec. erhöht wird, dann würde ein Überlauf alle 0,00001 Sec. stattfinden.

    So bin ich auf meine Werte gekommen.

    Kannst Du mir bitte sagen wo ich da den Fehler habe? Wie kann ich mir meinen Startwert mit einer vorgegebenen Frequenz (in meinem Fall 100KHz) ausrechnen?

    Danke
    mfG Henry

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    @Henry:
    Kannst Du mir bitte sagen wo ich da den Fehler habe?
    Du hast da gar keinen Fehler. Das Problem bei Bascom ist, dass in jeder ISR haufenweise mit Push Befehlen Register gesichert werden. Insgesamt dauert das 53 Takte, die sich bei den Timer-Einstellungen bemerkbar machen.

    Genau kann man 100 kHz mit dem 8-Bit Timer nicht treffen. Rechnerisch müßtest du 252 (94117 Hz) oder 253 (103896 Hz) als Startwert nehmen.

    Gruß Dirk

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Hallo Dirk,

    ich danke dir erst einmal für die Hilfe.
    Da kommt das zweite beschriebene Problem, die Änderungen beim Startwert und des Prescale wertes haben irgendwie keine so deutlichen Auswirkungen wie sie haben sollten.
    Bin auch noch nicht ganz dahinter gekommen wie du die Frequenzen ausrechnest. Könntest du mir das bitte auch noch beschreiben?

    Da muss ich wohl noch ein wenig experimentieren.
    evt. muss ich dann doch noch versuchen das Projekt in C umzusetzen.

    Danke
    mfG Henry

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo Henry,
    ich denke, dein Ansatz mit der Timer ISR wird nicht zum Ziel führen.
    Was du mit dem INT0 und dem Timer0 praktisch machst ist eine Nachbildung der Input Capture Funktion.
    Die kannst du mit dem Timer1 auch direkt benutzen. Dabei wird dann der Timer auomatisch gestartet, wenn der Impuls kommt. Schau mal in die Hilfe von Config Timer1.
    Du kannst es auch mit INT0 und Timer hinbekommen. Allerdings musst du den Timer dann frei laufen lassen, also keine Timer Overflow ISR benutzen.
    Bei der Start Flanke des Impulses startest du den Timer und setzt ihn auch 0 (ich glaube dass das beim Starten nicht automatisch passiert). Bei der Stopp Flanke des Impulses liest du den Timer Wert aus und stoppst den Timer.
    Timer0 ist mit 8-bit, also 256 Werten aber etwas knapp für deine Anwendung. Daher würde ich eher Timer1 nehmen und ihn mit Prescale = 8 laufen lassen. Dann zählt er alle 1µs um eins hoch. Da er 16-bit hat, läuft er erst nach 65ms über

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    @Henry:
    ... wie du die Frequenzen ausrechnest. Könntest du mir das bitte auch noch beschreiben?
    Formel:
    Code:
    Timerstartwert = 256 - (Fosc / Prescaler) * (1 / Frequenz - 53 / Fosc)
    Fosc -> Quarzfrequenz
    Frequenz -> Gewünschte Frequenz

    Gruß Dirk

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    @for_ro:
    Das werde ich mir mal anschauen und probieren.

    @Dirk: Danke für die Formel
    mfG Henry

Berechtigungen

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