-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 28

Thema: PWM und SOFTUART gleichzeitig

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544

    [Geändert] PID-Regler für Tricopter mit Wii Motion Plus

    Anzeige

    Hallo,

    für mein momentanes Projekt benötige ich einen AVR, der über 1 Pin Daten empfängt (SOFTUART), diese dann zerlegt und anschließend mittels PWM ausgibt. Beispiel:

    Der ATMEGA8 sendet "120*90*100*200"
    Jetzt soll mein zweiter AVR (ein ATTINY45) diesen String empfangen und in 4 Teile zerlegen:
    1. "120"
    2. "90"
    3. "100"
    4. "200"

    Diese 4 Strings soll er nun auf 4 verschiedene PWM-Ausgänge geben. Der PWM-Teil läuft soweit, jedoch nur, solange ich meinen Split-Befehl auskommentiere.
    Hier mal mein Programm:
    Code:
    $regfile = "attiny45.dat"
    $crystal = 8000000
    $framesize = 60
    $hwstack = 60
    $swstack = 60
    
    
    Open "COMB.0:19200,8,N,2,INVERTED" For Input As #1
    
    Config Pinb.0 = Input
    
    
    
    Config Servos = 3 , Servo1 = Portb.3 , Servo2 = Portb.2 , Servo3 = Portb.4 , Servo4 = Portb.1 , Reload = 4 , Intervall = 10
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portb.3 = Output
    Config Portb.4 = Output
    
    
    Dim _input As String * 15
    Dim _data(4) As String * 5
    Dim _lenght As Byte
    Dim _bl(4) As Byte
    Dim _blold(4) As Byte
    Dim I As Byte
    
    
    Const Min_servo = 11
    Const Max_servo = 70
    
    
    'STARTUP###########
    _input = ""
    _lenght = 0
    For I = 1 To 4
     _bl(i) = Min_servo
     _blold(i) = _bl(i)
     Servo(i) = _bl(i)
    Next I
    I = 0
    '##################
    
    
    Enable Interrupts
    
    
    
    Do
    
    
    Input #1 , _input Noecho
    _lenght = Split(_input , _data(1) , "*")
    If _lenght > 0 Then
    For I = 1 To 4
    _bl(i) = Val(_data(i))
    Servo(i) = _bl(i)
    Next I
    _input = ""
    _lenght = 0
    End If
    
    
    Loop
    
    End
    Sobald der Split-Befehl im Programm steht, wird die PWM-ISR teilweise blockiert und meine Signale stimmen nicht mehr.
    Was kann ich nun dagegen tun? Den Split-Befehl rausnehmen und das Ganze irgendwie anders lösen?
    Meine Hardware sieht so aus:
    Ein Atmega8 lest ein WM+ und einen 4CH-Empfänger (über Summensignal) ein und errechnet daraus 4 versch. Werte für 3 BLM und 1 Servo.
    Diese 4 Werte muss ich nun an den ATTINY45 (als "PWM-Controller") senden (habe nur 1 Pin). Dieser soll dann seinen 4 PWM-Ausgängen diese 4 Werte zuweisen. Die PWM-Frequenz liegt bei 50Hz.

    Über ein paar konstruktive Ideen würde ich mich sehr freuen.
    Gruß
    Chris
    Geändert von Che Guevara (16.05.2011 um 17:54 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Sobald der Split-Befehl im Programm steht, wird die PWM-ISR teilweise blockiert und meine Signale stimmen nicht mehr.
    Wo ist denn die PWM-ISR? Ich sehe nur einen Servo Befehl in der Hauptschleife. Wann der dran kommt, hängt natürlich von der Bearbeitungszeit aller anderen Befehle der Hauptschleife ab.

    Warum überträgst du die Werte als Strings? Wenn es keine größeren Werte werden können, als in ein Byte passen, dann würde ich mit Printbin das Byte mit Wert 200 übertragen und nicht den String "200". Denn dies wären dann mindestens 3 Byte.
    Und dann könntest du auch ohne weiteres auf die Funktionen Split() und Val() verzichten, die ziemlich viel Zeit benötigen.

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Das ging ja schnell
    Mit der PWM-ISR ist der Servo-Befehl gemeint.
    Wenn ich die Werte (4 mal 1Byte) mit Printbin übertrage, woher weiß ich dann, welcher empfangene Wert für welchen Servo / BL Motor zuständig ist?

    Gruß
    Chris

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Zum Zuordnen der Motoren kann eine Wert (z.B. 0 oder 255 ) nutzen der der PWM Wert nicht vor kommt. Der Wert markiert dann den Anfang der Daten. Mann muss dann halt 5 Bytes statt 4 übertragen. Die UART kann dann langsamer laufen.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Ich habs gerade ausprobiert mit Printbin und Inputbin, allerdings habe ich jetzt ein neueres, größeres Problem. Hier mein Code auf dem ATTINY45:
    Code:
    $regfile = "attiny45.dat"
    $crystal = 8000000
    $framesize = 30
    $hwstack = 30
    $swstack = 30
    
    
    
    Open "COMB.0:38400,8,N,1" For Input As #1
    Config Pinb.0 = Input
    
    
    Config Servos = 4 , Servo1 = Portb.3 , Servo2 = Portb.2 , Servo3 = Portb.4 , Servo4 = Portb.1 , Reload = 4 , Intervall = 10
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portb.3 = Output
    Config Portb.4 = Output
    
    
    
    Dim _bl(4) As Byte
    Dim _blold(4) As Byte
    Dim I As Byte
    
    
    Const Min_servo = 78                                        '900µs
    Const Max_servo = 170                                       '2000µs
    
    
    For I = 1 To 4
    _bl(i) = Min_servo
    _blold(i) = _bl(i)
    Servo(i) = _bl(i)
    Next I
    
    
    Enable Interrupts
    
    
    Do
    
    
    Servo(1) = 78
    Wait 1
    Servo(1) = 100
    Wait 1
    
    '(
    Inputbin #1 , _bl(1) , _bl(2) , _bl(3) , _bl(4)
    
    For I = 1 To 4
    If _bl(i) <> 0 And _bl(i) <> 255 Then
    If _bl(i) >= Min_servo And _bl(i) <= Max_servo Then
    Servo(i) = _bl(i)
    End If
    End If
    Next I
    ')
    
    Loop
    
    End
    Mit dem Oszi überprüfe ich den Ausgang des Servo(1)-Signals. Die Werte (78 und 100) stimmen zwar, jedoch ändert sich das Signal nicht jede Sekunde (wait 1), sondern nur ca. alle 5 bis 6 Sekunden. Clockdiv/8 ist deaktiviert, Clock output ist deaktiviert,
    100010:Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value,
    und bod ist deaktiviert.
    Warum braucht mein AVR so lange? Liegts am TINY? Hab in der BASCOM-Hilfe was von $tiny gelesen, allerdings gehen damit 90% meiner Instructions nicht mehr

    Gruß
    Chris

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Wenn ich die Werte (4 mal 1Byte) mit Printbin übertrage, woher weiß ich dann, welcher empfangene Wert für welchen Servo / BL Motor zuständig ist?
    Woher weißt du es bei deiner Version?
    Du kannst natürlich auch ein komplizierteres Protokoll nehmen anstelle von 1.Wert ist 1. Servo, 2. Wert ist 2.Servo usw. Aber wofür, wenn du immer 4 Werte sendest. Anders sieht es aus, wenn du z.B. nur die Werte sendest, die sich ändern. Aber das macht bei 4 Byte keinen Sinn, weil dann der Overhead zum Auswerten dann viel zu groß wird.
    Womit du eher ein Problem bekommen könntest ist die Synchronisierung, falls dir mal aus irgendeinem Grund ein Wert verlorengeht.

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Liegts am TINY?
    Das glaube ich eher nicht.
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Hab in der BASCOM-Hilfe was von $tiny gelesen, ...
    Das ist nur für die Tinys, die kein SRAM haben. Deiner dagegen ist doch ziemlich gut bestückt.

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Ok, aber warum ist dann das Timing so grottenschlecht?

    EDIT: Habs gerade probiert, wenn ich die Servo-Funktion auskommentiere und nur einen Pin im Sekundentakt toggln lasse, dann funzts wunderbar. Mit der Servo-Funktion dauerts jedoch ca. 6sek bis die neuen Werte übernommen werden?!

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Config Servos = 4 , Servo1 = Portb.3 , Servo2 = Portb.2 , Servo3 = Portb.4 , Servo4 = Portb.1 , Reload = 4 , Intervall = 10
    Hast du mal die Hilfe zu Config Servo unter Alternative Servocode gelesen?

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Ja, habs grad ausprobiert, bei mir kommen zwar die korrekten High-impluse raus, die Pausezeit (normal 20ms) dauert bei mir jedoch 200ms. Habs mit reload 100 und intervall = 100 gemacht, genau wie im Hilfe-Dokument.

    EDIT: Mir ist gerade aufgefallen, dass ich "Interval" mit 2 statt einem l geschrieben habe. Das erzeugt zwar keinen Fehler, jedoch stimmt dann das Timing nicht mehr! Jetzt, richtig geschrieben, funktioniert es perfekt!

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. 2 ISR gleichzeitig?
    Von DerSchatten im Forum C - Programmierung (GCC u.a.)
    Antworten: 15
    Letzter Beitrag: 26.01.2010, 10:48
  2. Problem ISP und USI als i2c gleichzeitig
    Von vklaffehn im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 16.08.2007, 15:46
  3. 8 Aufgaben gleichzeitig?
    Von Athlonxp2000 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 7
    Letzter Beitrag: 28.12.2006, 15:15
  4. 2 Interrupts gleichzeitig???
    Von x8r im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 23.01.2006, 19:49
  5. 16 IOs und LCD (quasi-gleichzeitig)
    Von lanzelot im Forum C-Control II
    Antworten: 13
    Letzter Beitrag: 01.02.2005, 05:21

Berechtigungen

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