- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 7 von 7

Thema: Wertebereich in eine Byte- Variable legen

  1. #1

    Wertebereich in eine Byte- Variable legen

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    ich habe ein Problem mit Variablen bei dem ich nicht weiterkomme. Ich lese mit einem ATmega48 Signale einer RC- Fernbedienung aus, dazu habe ich folgenden Code abgeändernt:
    http://<br /> <a href="http://www.r...sid=</a><br />
    Der Code gibt Werte im Bereich von ca. 16300 (Steuerknüppel linke Pos.) bis 8590 (Steuerknüppel rechte Pos.) aus. Um Servos anzusteuern wird von der Lib. Servo in Bascom eine Byte- Variable verlangt (Das ganze soll ein Empf. seitiger Mischer werden). Wie kann ich den Bereich von 7710 Schritten Linear in eine Byte- Variable von 50- 200 legen. Ich habe mir bereits folgenden Thread hier im Forum angeschaut werde aber nicht richtig schlau bez. des Index beim Lookup- Befehl.
    http://<br /> <a href="https://www....0832</a><br />

    hier noch mein Code:
    Code:
    'Konfiguration des Timer1
    Config Timer2 = Timer , Prescale = 1
    Config Timer1 = Timer , Prescale = 1
    Config Timer0 = Timer , Prescale = 1
    'Konfiguration des INT0
    'Interrupt bei jedem Flankenwechsel (0->1 und 1->0)
    Config Int0 = Change
    
    Config Servos = 2 , Servo1 = Portb.0 , Servo2 = Portb.1 , Reload = 10
    Config Portb = Output
    
    Dim Temp As Byte
    Dim Reading As Bit
    Dim Rc_value As Word
    Dim I As Byte
    Dim Error As Bit
    '======================================================
    'Initialisierungen
    '======================================================
    
    'Zuweisung der Interrupt-Service-Routinen
    On Int0 Rc_read
    On Timer1 Rc_error
    
    
    'Timer-Freigabe
    Enable Timer1
    Stop Timer1
    
    
    'Freigabe der Interrupt-Routinen
    Enable Int0
    Enable Interrupts
    
    '======================================================
    'Hauptprogramm-Schleife
    '======================================================
    Do
    Temp = 0
    If Reading = 0 Then
    
    Print "Kanal1: " ; Rc_value
    End If
    Loop
    End
    
    '======================================================
    'ISR für INT0 - R/C-Kanal lesen
    '======================================================
    Rc_read:
    'Den Timer starten mit steigender Flanke
    If Reading = 0 Then
    
       Start Timer1
       Reading = 1
    
    'Den Timer stoppen mit fallender Flanke
    Else
       Stop Timer1
       Rc_value = Timer1
    
       Timer1 = 0
       Reading = 0
    
    End If
    'Error-Bit rücksetzen
    Error = 0
    Return
    
    
    
    '======================================================
    'ISR für Timer1 - Fehlerhandling
    '======================================================
    Rc_error:
    'Error-Bit setzen
    Error = 1
    Reading = 0
    Stop Timer1
    Rc_value = 6300
    Return
    besten Dank

    Torsten[/url]

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.11.2004
    Beiträge
    1.693
    Im Code habe ich Index oder sonstetwas anderes entdeckt, das dein Problem versucht in den Griff zu bekommen.

    Wäre es nicht auch einfacher, das ganze per Dreisatz zu lösen?
    Ein paar Rechenschritte und du hast den Wert in einer Bytevariable. Allerdings kann es sein, das die Programmlaufzeit sich dafür erhöht.

  3. #3
    Hallo Marco,

    Im Code habe ich Index oder sonstetwas anderes entdeckt, das dein Problem versucht in den Griff zu bekommen.
    ich hatte meine erfolglosen Versuche mit Lookup zu dem Zeitpunkt schon aus dem Quelltext gelöscht.

    Wäre es nicht auch einfacher, das ganze per Dreisatz zu lösen?
    Ein paar Rechenschritte und du hast den Wert in einer Bytevariable. Allerdings kann es sein, das die Programmlaufzeit sich dafür erhöht.
    Wenn ich mit den Zahlen rechne bekomme ich heillosen Datenmüll, keine echten Werte. Liegt ja Wahrscheinlich an den zwangsläufig auftretenden Nachkommastellen, welchen Befehl muss ich verwenden um nur mit ganzzahlen zu rechnen?

    Gruss Torsten

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.11.2004
    Beiträge
    1.693
    Wenn ich mit den Zahlen rechne bekomme ich heillosen Datenmüll, keine echten Werte. Liegt ja Wahrscheinlich an den zwangsläufig auftretenden Nachkommastellen
    heillosen Datenmüll kann ich mir garnicht vorstellen?!?
    Wie sieht denn deine Rechnung aus? Oder wie der Code dafür? Dann sieht man gleich welche Variable du welchem Typ zugewiesen hast.

  5. #5
    Hallo,

    habe es mittlerweile wieder mit berechnen versucht, diesmal klappt das! Ich teile den wert durch 40 und schiebe das Low- Byte mit LOW() in ein Byte. Ich weiss nicht warum das vorher schief ging

    Danke für den "Ruck" in die richtige Richtung

    Torsten

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.11.2004
    Beiträge
    1.693
    Durch 40 teilen?

    7710/150 ergibt ungefähr 51.

    7710 ist der differenzielle Wert den du bekommst, 150 ist die Differenz zwischen 50 und 200, die du haben möchtest.

    Wenn Y der gemessene Wert ist, würde ich den - 8590 nehmen und das Ergebnis X nennen.
    Dann hat man den Wert quasi von 0 an gezählt und erhält als meximalen Wert die 7710.
    Dann X/51+50
    Alle 51 Schritte bewirken eine Erhöhung um 1 deiner Bytevariable.
    +50, weil der minimale Wert deines Bytes 50 sein soll.

    Aber wenn es mit LOW() auch geht ist es ja gut.

    Wen du es doch anders machen solltest, kann ich dir den Tipp geben, die Werte des Senders mit CONST festzulegen.

    Wenn sich linker und rechter Anschlag mal ändern, ändert sich auch der Wert pro Schritt. (Z.Zt. die 51). Und schon würde die Rechnung nicht mehr passen.
    Ein neuer Sender und schon passt das ganze nicht mehr. Oder das Poti wird etwas verstellt...

    Wenn die Werte ganz zu Anfang im Listing stehen und als Konstante festgelegt sind, müssten sie dann nur einmal geändert werden und nicht mühsellig im ganzen Programm nach gesucht werden. Das ist dann auch eine beliebte Fehlerquelle. Ich spreche da aus eigener Erfahrung!

    Noch komfortabler wäre es ja (und damit auch für andere Personen geeignet) wenn der linke und rechte Anschlag selbstlernend sind.

    Immer wenn man meinte es wäre mal wieder so weit, die Kalibrierung per externen Taster starten und dann 5 mal nach links und rechts schalten, das Programm erkennt automatisch welcher Wert wahrscheinlicher für links oder rechts war. Oder die Reihenfolge wird festgelegt und dann wird ein Mittelwert errechnet. Die Werte werden dann im EEPROM abgelegt und sind auch nach Stromausfall noch verhanden. Beim Neustart müssen die Werte dann nur noch ausgelesen werden.
    Im Prinzip muss auch nur der Umrechnungsfaktor Senderwert/Byte gespeichert werden.

    Das ganze erspart dir ein neues flashen des AVR wenn du dir n neuen Sender kaufst und ermöglich eine hohe Kompatiblität wenn jemand deine Schaltung nachbauen will.

  7. #7
    Hallo Marco,

    ich habe inzwischen den Prescaler des Timers von 1 auf jetzt 64 erhöht, das ergibt schon einmal kleinere Werte, anschließend habe ich mit AND die letzten zwei Bits des Wortes "ausgeblendet". Danach reicht ein x-110 aus und das ganze passt mit der Steuerung überein. Das Problem das ich jetzt habe ist das die Servos ständig zucken, das hat mit der Einstellung des Prescalers scheinbar nichts zu tun, da das Zucken der Servos auch mit der Einstellung auf eins vorhanden war. Das ist insofern ärgerlich da die Werte ( x ) zur Berechnung der eigentlichen Servostellung dienen sollen ( Servos sollen gemischt werden). Es könnten während einer Berechnung beide Werte falsch sein und das Ergebnis wäre völlig falsch. Auf dem Oszilloskop sieht das Signal des Empfängers sauber aus. Deine Idee mit dem Kalibrieren ist garnicht so schlecht, wenn ich die Servos sauber ansteuern kann werd ich mal darüber her machen

    werde morgen mal weitersehen

    Gruss
    Torsten

Berechtigungen

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

Labornetzteil AliExpress