- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 5 von 8 ErsteErste ... 34567 ... LetzteLetzte
Ergebnis 41 bis 50 von 75

Thema: Mehrere RC Signale einlesen und mehrere Servos ausgeben

  1. #41
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Anzeige

    E-Bike
    Zitat Zitat von R2D2 Bastler Beitrag anzeigen
    Ich glaub das Ding geht, es geeeeeehhhhhhhhhhht
    Mist ...

    .... läuft das Teil nun besser als erwartet.
    ... sieht wirklich so aus, als müßte man noch was deichseln


    Mit herzlichen Glückwünschen
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  2. #42
    So, hier nochmal der Code für ein einzelnes Servo auf dem kleineren Attiny45. Die Berechnung der Servogeschwindigkeit musste nochmals komplett überarbeitet werden, da beim Attiny45 nur 8-Bit Timer zur Verfügung stehen. Da sich der Kleine nicht mit mehreren RC Signalen rumschlagen muss, war es (fast) kein Problem, die entsprechende Berechnung umzugestalten.

    mfg
    Robert

    Code:
    '===============================================================================
    'Single Baggerarmsteuerung V3
    '
    'RC Eingang 1 an Pin 7 (PB2, INT0)
    'Poti 1a an Pin 2 (PB3, ADC3)
    'Poti 1b an Pin 3 (PB4, ADC2)
    'Servo 1 an Pin 6 (PB1)  Baggerarmservo
    
    '===============================================================================
    
    $regfile = "attiny45.dat"
    $crystal = 8000000                                          'FuseBit CKDIV8 deaktivieren
    
    $hwstack = 40
    $swstack = 40
    $framesize = 50
    
    
    '-------------------------------------------------------------------------------------------------
    'Timer konfigurieren
    '-------------------------------------------------------------------------------------------------
    
    Tccr1 = &B00000111                                          'Timer1 für RC-Signal Einlesung wird gestartet (Prescale 64) (geht beim Attiny45 nicht mit "Config"!)
    
    Config Timer0 = Timer , Prescale = 64                       'Timer0 für Servoausgabe, Wert 125 entspricht 1ms, Wert 250 entspricht 2ms
    On Timer0 Servoausgabe Nosave                               'Register werden manuel in der ISR gesichert
    Enable Timer0
    
    
    '-------------------------------------------------------------------------------------------------
    'Interrupt-Service-Routinen konfigurieren und freigeben
    '-------------------------------------------------------------------------------------------------
    
    Config Int0 = Change                                        'beim Flankenwechsel an PB2/INT0 (RC Eingang) Int0 auslösen und in die Subroutine springen
    Enable Int0
    On Int0 Rc_eingang_1 Nosave                                 'Register werden manuel in der ISR gesichert
    Enable Interrupts
    
    
    '-------------------------------------------------------------------------------------------------
    'Poti-Eingänge konfigurieren
    '-------------------------------------------------------------------------------------------------
    
    Config Adc = Single , Prescaler = Auto
    Start Adc
    
    
    
    '-------------------------------------------------------------------------------------------------------------
    'Konstanten definieren
    '-------------------------------------------------------------------------------------------------------------
    Const Jitterausgleich = 2                                   'Wert in µs um den sich gemessene Impulslaenge aendern darf/muss, bevor Servo gestellt wird
    
    Const Rc_min = 122                                          'Minimaler RC-Wert für die Berechnungen (Werte zwischen 120 - 125 sinvoll)
    Const Rc_max = 253                                          'Maximaler RC-Wert für die Berechnungen (Werte zwischen 250 - 255 sinvoll)
    
    
    '-------------------------------------------------------------------------------------------------------------
    'Variablen definieren
    '-------------------------------------------------------------------------------------------------------------
    Dim Rc_signal_1_start As Byte
    Dim Rc_signal_1_stop As Byte
    Dim Rc_signal_1_stop_flag As Byte
    Dim Impulslaenge_1 As Byte
    Dim Impulslaenge_1_alt As Byte
    Dim Impulslaengenaenderung As Integer                       'wird nur einmal gebraucht, da nur Hilfswariable
    
    
    
    'Variablen für Servowegsbegrenzung
    Dim Poti_1a As Word
    Dim Poti_1b As Word
    
    Dim Limit_1a As Byte
    Dim Limit_1b As Byte
    
    'Variablen für Berechnungen
    Dim Berechnung_1 As Byte
    Dim Berechnung_1a As Byte
    
    
    Dim Servospeed As Byte
    Dim Zeit_1 As Byte
    Dim Zeit_2 As Word
    
    'Variablen für Servoausgabe
    
    Dim Kanal As Byte
    Dim Servoausgabe_1 As Byte
    
    
    
    '-------------------------------------------------------------------------------------------------
    'Einigen Variablen Werte zuweisen
    '-------------------------------------------------------------------------------------------------
    
    Kanal = 1
    Berechnung_1a = 187                                         'Servo erst mal auf Mittelstellung
    
    
    '-------------------------------------------------------------------------------------------------------------
    'Ein- und Ausgang festlegen
    '-------------------------------------------------------------------------------------------------------------
    
    Ddrb = &B00000010                                           'PB1 wird Ausgang, restlicher PortB bleibt Eingang
    
    
    '======================================================
    'Hauptprogramm
    '======================================================
    
    Do
    
    'RC Impulslänge berechnen und Grenzwerte festlegen
    
    
    If Rc_signal_1_stop_flag = 1 Then                           'Bearbeitung nur, wenn ISR Pulsende gefunden hat
          Disable Int0                                          'Mögliche Korruption durch ISR vorbeugen
          Impulslaenge_1 = Rc_signal_1_stop - Rc_signal_1_start
          Enable Int0
          Rc_signal_1_stop_flag = 0
          Impulslaengenaenderung = Impulslaenge_1_alt - Impulslaenge_1       'SW-Hysterese
          If Abs(impulslaengenaenderung) >= Jitterausgleich Then
             Impulslaenge_1_alt = Impulslaenge_1
    
             Berechnung_1 = Impulslaenge_1
    
             If Berechnung_1 > Rc_max Then Berechnung_1 = Rc_max
             If Berechnung_1 < Rc_min Then Berechnung_1 = Rc_min
          End If
      End If
    
    
    
    
    
    'Berechnung der Servogeschwindigkeit und Servostellung
    
    If Berechnung_1 < 182 And Berechnung_1a > Rc_min Then
    
        Servospeed = Berechnung_1 - Rc_min                      'ergibt Werte zwischen 0 (schnell) und 61 (langsam)
    
        Zeit_1 = 61 - Servospeed                                'inventieren (0=langsam, 61=schnell)
        Zeit_2 = Zeit_2 + Zeit_1
    
        If Zeit_2 > 200 Then
          Decr Berechnung_1a
          Zeit_2 = 0
        End If
    
    
    End If
    
    If Berechnung_1 > 193 And Berechnung_1a < Rc_max Then
    
        Servospeed = Rc_max - Berechnung_1
    
        Zeit_1 = 61 - Servospeed                                'inventieren
        Zeit_2 = Zeit_2 + Zeit_1
    
        If Zeit_2 > 200 Then
          Incr Berechnung_1a
          Zeit_2 = 0
        End If
    End If
    
    
    'Potis abfragen und Werte für Servolimits berechnen
    
    Poti_1a = Getadc(3)
    Poti_1a = Poti_1a / 25                                      '1024 / 25 = 41, ergibt ca 30% Wegbegrenzung
    Limit_1a = 255 - Poti_1a
    
    Poti_1b = Getadc(2)
    Poti_1b = Poti_1b / 25
    Limit_1b = 120 + Poti_1b
    
    
    'RC Signal auf Limitwerte begrenzen
    
    If Berechnung_1a > Limit_1a Then                            'zu hohe Werte abfangen
       Berechnung_1a = Limit_1a
    End If
    If Berechnung_1a < Limit_1b Then                            'zu kleine Werte abfangen
       Berechnung_1a = Limit_1b
    End If
    
    
    'Finale Berechnungen an Servoausgabe übergeben, Servoausgabe_x zum direkten Laden in TCNT0 vorbereiten (Cmd Load umgangen)
    
    Servoausgabe_1 = 256 - Berechnung_1a                        'Baggerarmservo
    
    Loop
    
    
    
    
    '======================================================
    'ISR
    '======================================================
    
    
    Rc_eingang_1:
     $asm
       push r17                                                 'Register auf Stack sichern
       sbis pinb , 2                                            'Skip next Instr if PINBx = 1
       rjmp Puls_ende1                                          'Springe Puls_ende
       in r17 , tcnt1                                           'Timer1 Wert holen
       sts {Rc_signal_1_start} , r17                            'Speichere Timer1 nach Rc_signal_1_start
    
       rjmp ende1                                               'Springe zum Ende
      Puls_ende1:
       in r17 , tcnt1                                           'Timer1 Wert holen
       sts {Rc_signal_1_stop} , r17                             'Speichere Timer1 nach Rc_signal_1_stop
    
       ldi r17 , 1
       sts {Rc_signal_1_stop_flag} , r17                        'Setze Flag zur Bearbeitung von Impulslaenge in Hauptschleife
      Ende1:
       pop r17                                                  'Register vom Stack zurückholen
     $end Asm
    Return
    
    
    Servoausgabe:
    
     $asm
       push r16                                                 'Register auf Stack sichern
       in r16,sreg                                              'Statusregister holen und halten
       push r17                                                 'Register auf Stack sichern
       lds r17 , {kanal}                                        'hole Kanalnummer
    
       cpi r17 , 1                                              'check Kanal und ...
       brne LABEL_KANAL_2                                       '... "wenn nicht gleich" verzweige zum nächsten Kanal
       sbic portB , 1                                           'Skip next instr. wenn PORTA.0 = 0 ist
       rjmp label_1                                             'Springe zum LOW-setzen des Servosignals
       sts {kanal} , r17                                        'Sichere Kanalnummer
       lds r17 , {Servoausgabe_1}                               'Hole aufbereiteten Pulslängenwert für Timer0
       Out Tcnt0 , R17                                          'Setze Timer0 mit Pulslängenwert
       sbi portB , 1                                            'Setze Servosignal HIGH
       rjmp Ende_isr                                            'Springe zum Ende der ISR
      Label_1:
       cbi portB , 1                                            'Setze Servosignal nach LOW
       inc r17                                                  'Erhöhe Kanalnummer
    
    'Pausenauffüllung
    
       'Pausenanfang
    
       sts {kanal} , r17                                        'Sichere Kanalnummer
       ldi r17 , &B00000101                                     'CS00 und CS02 für prescaler 1024 in Timer0 vorbereiten
       Out Tccr0b , R17                                         'Timer0 läuft mit 128µs Auflösung
       ldi r17 , 162                                            'Wert für ca 12ms bis zum nächsten OVF (162=256-94) bei prescaler 1024
       Out Tcnt0 , R17
       rjmp Ende_isr                                            'Springe zum Ende der ISR
    
      'Pausenende
      Label_kanal_2:                                            'Bearbeitung von Kanal 2 (Pausenende)
       ldi r17 , &B00000011                                     'CS00 und CS01 für prescaler 64 in Timer0 vorbereiten
       Out Tccr0b , R17                                         'Timer0 läuft wieder mit 8µs Auflösung
       ldi r17 , 1                                              'Kanalnummer auf 1 setzen
       sts {kanal} , r17                                        'Sichere Kanalnummer
      Ende_isr:
       pop r17                                                  'Register vom Stack zurückholen
       Out Sreg , R16                                           'Statusregister zurückspeichern
       pop r16                                                  'Register vom Stack zurückholen
     $end Asm
    Return

  3. #43
    Neuer Benutzer Öfters hier
    Registriert seit
    04.04.2015
    Beiträge
    10
    Hallo zusammen,

    ich habe mit großer Aufmerksamkeit diesen Thread gelesen und wollte das Forum bitte mir bei meinem Vorhaben zu unterstützen diesen Code für einen Arduino Nano (ATME328p) umzuschreiben.

    Ich habe schon mal begonnen, komme aber nicht wirklich weiter.
    Im Anhang meine ersten Versuche den Code von R2D2 Bastler umzuschreiben.

    Ich denke, das nicht soviele Änderungen notwendig wären?

    Vielen Dank
    VG
    Tom
    Angehängte Dateien Angehängte Dateien

  4. #44
    Unregistriert
    Gast
    na wirklich niemand Zeit sich den Code mal anzusehen?
    komme wirklich nicht weiter...

  5. #45
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Zitat Zitat von Tony DesWegeles Beitrag anzeigen
    Ich habe mit großer Aufmerksamkeit diesen Thread gelesen und wollte das Forum bitte mir bei meinem Vorhaben zu unterstützen diesen Code für einen Arduino Nano (ATME328p) umzuschreiben.

    Ich habe schon mal begonnen, komme aber nicht wirklich weiter.
    Im Anhang meine ersten Versuche den Code von R2D2 Bastler umzuschreiben.
    Läßt sich doch kompilieren. Wo sind denn die Probleme?

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  6. #46
    Unregistriert
    Gast
    Hallo Seacher,

    danke für deine Antwort.
    Ja Kompilieren lässt sich der Code, nur wenn ich diesen auf den Arduino spiele, funktioniert nur der Teil, wo die Servos auf die Mittelstellung fahren.
    Die Steuerung reagiert nicht auf die Empfängereingangssignale.

    Ich hab auf D4 ein Empfängersignal und auf D8 einen Servo. Die Potis habe ich nicht angeschlossen, kannes daran liegen?

    Anbei nochmal der Code, hier habe ich nochmal die Eingangs und Ausgangsports angepasst.

    VG
    Tom

  7. #47
    Neuer Benutzer Öfters hier
    Registriert seit
    04.04.2015
    Beiträge
    10
    Nochmals der Code
    Angehängte Dateien Angehängte Dateien

  8. #48
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo Tony,
    Ich hab auf D4 ein Empfängersignal und auf D8 einen Servo. Die Potis habe ich nicht angeschlossen, kannes daran liegen?
    ich kann nicht so genau überblicken welchen Einfluß die Potis haben. Ich habe damals praktisch nur die ASM Routinen gemacht und R2D2 hat das dann auf seinen Bagger angewendet. Wenn du keine Potis angeschlossen hast, würde ich statt des Getadc() Konstanten verwenden, die am Programmanfang zum Testen mit Werten zwischen 0 und 1023 belegt werden.

    D4 bzw D8 sagt mir nichts. Das sind Arduino Bezeichnungen und ich vertraue Dir, das du die Servos schon richtig angeschlossen hast? Mittelstellung funktioniert ja.

    Sehr wichtig sind jedoch die Timereinstellungen. Dein ATMega328p läuft mit 16MHz. Das Programm war aber für 8MHz ausgelegt. Auf den ersten Blick erscheint mir das nicht angepaßt, da die Timer mit den gleichen Prescalern wie für 8MHz laufen? Hab im Augenblick nicht die Ruhe, das im einzelnen jetzt durchzugehen. Da müßtest Du nochmal schauen.

    Möchtest Du da auch einen Bagger o.ä. betreiben oder zu was brauchst Du das. Die Potis waren, glaub ich, nur zur Wegbegrenzung um keinen Knoten in den Baggerarm zu bekommen ... oder so Die Variablen sollten aber mit irgendwas initialisiert werden oder die Limitberechnung komplett rausgenommen werden.

    Gruß
    Searcher
    Geändert von Searcher (04.04.2015 um 20:35 Uhr) Grund: 1024 gegen 1023 getauscht
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  9. #49
    Neuer Benutzer Öfters hier
    Registriert seit
    04.04.2015
    Beiträge
    10
    Hallo Searcher,

    danke für die Antwort. Ja ich würde gerne ebenfalls einen Bagger betreiben damit, da mir das ständige Halten der Steuerknüppel auf den Zeiger geht
    Okay das mit den Timern habe ich nicht bedacht, werde mich dahinter klemmen. Ich versuche mal deine gesamten Ratschläge durch.
    D4 und D8 sind in der Tat die Belegung für den Arduino. Anbei ein Pin Mapping des Arduino.
    http://christianto.tjahyadi.com/wp-c...14/11/nano.jpg

    Nach diesem Pin Mapping bin ich vorgegangen.

    VG
    Tom

    - - - Aktualisiert - - -

    Hallo Searcher,

    also wirklich weiter bin ich nicht bekommen, also wenn du mal ne ruhige Minute hättest
    VG

  10. #50
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo Tom,
    das Programm auf 16MHz umzuschreiben ist nicht so einfach, weil der Timer0 nicht den passenden Prescaler bietet. Er sollte mit 8µs Auflösung laufen. Wird der µC mit 16MHz getaktet, läuft Timer0 mit 4µs und schafft dann als 8Bit Timer (256*4µs=1024µs) nicht den Servoimpulsbereich von 1000µs bis 2000µs. EDIT: ODER DOCH ??? Einfacher den µC mit 8MHz laufen zu lassen Der nächste Prescaler wäre 256. Dann würde der Timer bei 16MHz mit 16µs Auflösung laufen, was mir zu grob erscheint. Es wäre wermutlich eine leicht ruckelige Bewegung die Folge.

    Man kann aber den µC fürs erste ohne HW Eingriff verlangsamen. Das sollte im Register CLkPR zu machen sein.
    Gleich nach dem Header im Bascomprogramm nach Framesize und vor Timerkonfiguration diese beiden Zeilen einfügen:
    Code:
    Clkpr = &B1000_0000                                         'CLKPCE Bit hight zum clock devision bit change enable
    Clkpr = &B1000_0001                                         'clock devision bit für division by 2
    Dann sollte der ATMega328 nur noch mit 8MHz laufen und keine weiteren Eingriffe im Programm fürs Timing nötig sein. Falls möglich die Taktfrequenz mal überprüfen. Ich habe das selbst noch nicht in der Praxis durchgeführt. Laut Simulator sollte es aber hinhauen (Der zweite Registerzugriff muß innerhalb von 4 Taktzyklen nach Setzen des CLKPCE Bits abgeschlossen sein.)

    Gruß
    Searcher
    Geändert von Searcher (04.04.2015 um 22:04 Uhr) Grund: Blauen Text hinzugefügt
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

Seite 5 von 8 ErsteErste ... 34567 ... LetzteLetzte

Ähnliche Themen

  1. Mehrere analoge Werte über ein ADC einlesen möglich?
    Von HeXPloreR im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 07.08.2012, 18:18
  2. Schaltkreis für mehrere Servos
    Von Sebbokalypse im Forum Elektronik
    Antworten: 9
    Letzter Beitrag: 12.11.2009, 19:46
  3. Mehrere Signale umschalten
    Von flexxo im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 25.02.2007, 14:56
  4. Antworten: 9
    Letzter Beitrag: 02.04.2006, 18:53
  5. Mehrere Signale über einen Interrupt erkennen
    Von Minifriese im Forum Elektronik
    Antworten: 22
    Letzter Beitrag: 04.06.2004, 09:31

Berechtigungen

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

Labornetzteil AliExpress