-         

Ergebnis 1 bis 2 von 2

Thema: Software PWM

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269

    Software PWM

    Anzeige

    HI
    Da ich nicht genau wusste wo ich dieses thema reinstellen sollte kommt es enfach mal unter allgemein ^^

    Ich habe eine Problem mit einer Software PWM die ich in Bascom geschrieben und auf einen Atmel ATMega 8535 übertragen habe.

    Sinn der PWM ist es mehrere Servo Motoren mit möglichst vielen anfahrbaren Positionen zu steuern.
    Ich weis das dieser Chip nicht gerade geeignet dafür ist da er nur 3 Hardware PWM's besitzt welche wesentlich besser dafür geeignet wären.
    Aber ich hab momentan nunmal nur den ^^

    Zum aufbau der Schaltung:
    - 5V versorgungsspannung
    - 8MHz Quarz
    - Angeschlossener MAX232N um Texte am PC ausgeben zu können
    - Der angeschlossene Test Servo ist ein "Top Line ES-05" für 5€ vom Conrad ^^

    Ich habe diesen schon über die Hardware PWM angesteuert was eigentlich sehr gut funktioniert hat. (Portd.5 OCA)
    Diese lief mit dem errechneten Wert von 244Hz
    Dummerweise besitze ich kein Oszilloskop deswegen muss ich rumrechnen


    1. Frage: Wie kann es sein das ein Servo der eigentlich nur alle 20mS (50Hz) die Perioden Länge überprüft aufeinmal mit 244 Hz läuft (4mS)

    Da es ja seltsamerweise funktioniert hat sollte meine Software PWM mit 250Hz laufen also genau 4mS.
    Was aber auch nicht funktionierte.
    Aktuell läuft die PWM mit ca. 2kHz.
    Aber es funktioniert -_-
    Wie gesagt ich habe kein Oszi also kann ich nur vermuten.

    Hier ist mein Bascom Programm vielleicht kennt jemand einene beseren Weg als ich ihn jetzt habe.

    Bekannte Probleme:
    1.Es Funktioniert Zwar eigentlich ganz zufriedenstellend nur bei dem Wert von 40 aufwärts fängt der Servo an zu vibrieren und wird ziemlich laut.
    Vermutlich kommt das Signal nicht richtig rüber.
    2. Die hauptschleife ist Stark in mitleidenschaft gezogen worden da diese nun sehr langsam läuft.
    Auch wenn ich die "Print" befehle weglasse die sehr lange dauern, rechnet er immernoch sehr langsam.
    Weil der Chip nahezu immer im Interupt des Timers rumeiert.
    3. Ich habe um den Winkel einzustellen gerademal 35 Schritte und das ist nicht gerade viel. Es wäre toll mehr zu haben muss aber nicht sein da es im grunde für meine Zwecke ausreichen würde^^

    Der Timer läuft im Normalmodus also sozusagen in einer art Sägezahnspannung^^
    Der Wert A verhält sich somit genauso wie der Timer und ergibt als Diagramm gesehn auch eine "Sägezahnspannung"

    Neija vieleicht kann mir einer da weiterhelfen
    Ich bedanke mich schoneinmal im vorraus.


    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '----------------------------- Software PWM --------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '------- Voreinstellungen
    '-------------------------------------------------------------------------------
    $regfile = "m8535.dat" 'ATMega8535
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 8000000 'Quarz: 8.0000 MHz
    $baud = 9600
    '-------------------------------------------------------------------------------
    '------- Timer 0
    '-------------------------------------------------------------------------------
    Print "Programm Start"
    Config Timer0 = Timer , Prescale = 1 'Konfiguriere Timer1 Der timer läuft mit einer Frequenz von 1MHz
    Enable Timer0 'schalte den Timer1 ein
    On Timer0 Isr_von_timer1 'verzweige bei Timer1 überlauf zu Isr_von_Timer1

    Enable Interrupts
    Load Timer0 231 'Timer0 Zählwert ergibt 320kHz
    Dim A As Long
    Dim B As Bit 'aktuell nicht verwendet
    Dim C As Integer 'Servo 1
    Dim D As Integer 'servo 2
    Dim E As Integer 'servo 3
    Dim F As Integer 'servo 4
    Dim G As Integer 'servo 5
    Dim H As Integer 'servo 6
    Dim I As Integer 'servo 7
    Dim J As Integer 'servo 8 aktuell zum Test
    Dim K As Integer
    Config Portc.3 = Output 'LED
    Config Portc.4 = Output 'Led
    Config Portc.5 = Output 'LED
    Config Porta.0 = Output 'Servo 1 Var C
    Config Porta.1 = Output 'Servo 2 Var D
    Config Porta.2 = Output 'Servo 3 Var E
    Config Porta.3 = Output 'Servo 4 Var F
    Config Porta.4 = Output 'Servo 5 Var G
    Config Porta.5 = Output 'Servo 6 Var H
    Config Porta.6 = Output 'Servo 7 Var I
    Config Porta.7 = Output 'Servo 8 Var J

    '-------------------------------------------------------------------------------
    '------- Hauptprogramm
    '-------------------------------------------------------------------------------

    J = 10
    I = 10

    Do 'Hauptschleife
    Do
    J = J + 1
    I = I + 1

    'Waitms 100
    Print J
    Loop Until J = 43 'Zähle bis 9
    Waitms 10 'Warte 600 mS
    Do
    J = J - 1
    I = I - 1

    'Waitms 100
    Print J
    Loop Until J = 8 'Zähle runter bis 2
    Waitms 10 'Warte 600 mS
    Toggle Portc.5 'Anzeige LED
    Loop 'Hauptschleife


    '-------------------------------------------------------------------------------
    '------- ISR von Timer 0
    '-------------------------------------------------------------------------------
    Isr_von_timer1: 'ISR von Timer0
    Load Timer0 231 'Timer0 soll wieder von 231 wegzählen bis 256
    A = A + 1 'Zähler Wert erhöhen
    If A = 160 Then 'Rücksetzen des Wertes und starten einer neuen Periode
    A = 0
    Porta.0 = 1 'Ports Wieder Anschalten
    Porta.1 = 1
    Porta.2 = 1
    Porta.3 = 1
    Porta.4 = 1
    Porta.5 = 1
    Porta.6 = 1
    Porta.7 = 1
    End If
    If A = C Then Porta.0 = 0 'Servo 1
    If A = D Then Porta.1 = 0 'Servo 2
    If A = E Then Porta.2 = 0 'Servo 3
    If A = F Then Porta.3 = 0 'Servo 4
    If A = G Then Porta.4 = 0 'Servo 5
    If A = H Then Porta.5 = 0 'Servo 6
    If A = I Then Porta.6 = 0 'Servo 7
    If A = J Then Porta.7 = 0 'Servo 8
    Return 'gehe zur Hauptschleife zurück
    '-------------------------------------------------------------------------------
    '------- ENDE
    '-------------------------------------------------------------------------------
    End

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269
    So meine PWM ist jez wesentlich besser und läuft auch stabil
    Musste allerdings den Quarz von 8 auf 16 MHz erhöhen

    HIer ist sie mit einem angeschlossenen Servo Roboter Bein
    Bin grad dabei (neben dem El-Kart^^) ein paar Roboter zu bauen
    Der erste ist sehr einfach und kann nur sachen ausweichen mit einer art Radar drauf (Motor, Poti, Abstandsmesser ^^)
    Der nächste soll einer mit Beinen sein
    Wobei ich einfach mal versuche dies mit 2 Beinen zu realisieren.
    Japp sehr schwierig aber probiern kann mans mal ;P


    So hier ist die PWM:


    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '----------------------------- Software PWM ------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '------- Voreinstellungen
    '-------------------------------------------------------------------------------
    $regfile = "m8535.dat" 'ATMega8535
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000 ' 16MHz
    $baud = 9600
    '-------------------------------------------------------------------------------
    '------- Timer 0
    '-------------------------------------------------------------------------------
    Print "Programm Start"
    Config Timer0 = Timer , Prescale = 1 'Konfiguriere Timer1 Der timer läuft mit einer Frequenz von 1MHz
    Enable Timer0 'schalte den Timer1 ein
    On Timer0 Isr_von_timer1 'verzweige bei Timer1 überlauf zu Isr_von_Timer1
    Restart:
    Enable Interrupts
    Load Timer0 240 'Timer0 Zählwert ergibt 1MHz
    Dim A As Word
    Dim C As Integer 'Servo 1
    Dim D As Integer 'servo 2
    Dim E As Integer 'servo 3
    Dim F As Integer 'servo 4
    Dim G As Integer 'servo 5
    Dim H As Integer 'servo 6
    Dim Var(2) As Word 'verzögerung
    Dim Vars(6) As Byte 'Variablen
    Dim Bid As Bit 'Schleifen ende
    Dim Universal As Byte 'abschnitte
    Var(1) = 1
    Var(2) = 350
    H = 50
    Vars(6) = 50
    Config Portc.3 = Output 'LED
    Config Portc.4 = Output 'Led
    Config Portc.5 = Output 'LED
    Config Porta.0 = Output 'Servo 1 Var C
    Config Porta.1 = Output 'Servo 2 Var D
    Config Porta.2 = Output 'Servo 3 Var E
    Config Porta.3 = Output 'Servo 4 Var F
    Config Porta.4 = Output 'Servo 5 Var G
    Config Porta.5 = Output 'Servo 6 Var H
    Config Pinc.7 = Input
    '-------------------------------------------------------------------------------
    '------- Hauptprogramm
    '-------------------------------------------------------------------------------
    Portc.5 = 1 'Anzeige LED
    Vars(1) = C 'C
    Vars(2) = D 'D
    Vars(3) = E 'C
    Vars(4) = F 'D
    Vars(5) = G 'C
    Vars(6) = H 'C

    'min 9 max 43
    C = 80 'mitte
    D = 89 'mitte
    E = 90 'mitte
    F = 87 'mitte
    G = 76 'mitte
    'H = 10 'nicht vorhanden
    Print "Grunstellung"
    C = 80 'mitte
    D = 55 'mitte
    E = 60 'mitte
    F = 87 'mitte
    G = 109 'mitte
    'H = 10 'nicht vorhanden
    Waitms 1
    Print "Bein hoch"
    Vars(1) = 80 'C
    Vars(2) = 36 'D
    Vars(3) = 40 'C
    Vars(4) = 87 'D
    Vars(5) = 112 'C
    Gosub Langsam
    'Waitms 10

    Print "Bein Vor"
    Var(2) = 150
    Vars(1) = 80 'C
    Vars(2) = 90 'D
    Vars(3) = 45 'C
    Vars(4) = 87 'D
    Vars(5) = 112 'C
    Gosub Langsam
    Var(2) = 150
    Vars(1) = 80 'C
    Vars(2) = 105 'D
    Vars(3) = 90 'C
    Vars(4) = 87 'D
    Vars(5) = 130 'C
    Gosub Langsam
    Var(2) = 250
    Vars(1) = 80 'C
    Vars(2) = 115 'D
    Vars(3) = 113 'C
    Vars(4) = 87 'D
    Vars(5) = 122 'C
    Gosub Langsam
    Print "Bein aufgesetzt"
    Print "Bein auf grunstellung bewegen"
    Var(2) = 250
    Vars(1) = 80 'C
    Vars(2) = 115 'D
    Vars(3) = 113 'C
    Vars(4) = 87 'D
    Vars(5) = 122 'C
    Gosub Langsam
    Var(2) = 250
    Vars(1) = 80 'C
    Vars(2) = 113 'D
    Vars(3) = 110 'C
    Vars(4) = 87 'D
    Vars(5) = 123 'C
    Gosub Langsam
    Vars(1) = 80 'C
    Vars(2) = 105 'D
    Vars(3) = 100 'C
    Vars(4) = 87 'D
    Vars(5) = 125 'C
    Gosub Langsam
    Vars(1) = 80 'C
    Vars(2) = 98 'D
    Vars(3) = 90 'C
    Vars(4) = 87 'D
    Vars(5) = 127 'C
    Gosub Langsam
    Vars(1) = 80 'C
    Vars(2) = 89 'D
    Vars(3) = 78 'C
    Vars(4) = 87 'D
    Vars(5) = 128 'C
    Gosub Langsam
    Vars(1) = 80 'C
    Vars(2) = 75 'D
    Vars(3) = 70 'C
    Vars(4) = 87 'D
    Vars(5) = 124 'C
    Gosub Langsam
    Vars(1) = 80 'C
    Vars(2) = 68 'D
    Vars(3) = 64 'C
    Vars(4) = 87 'D
    Vars(5) = 122 'C
    Gosub Langsam
    Var(2) = 350
    Vars(1) = 80 'C
    Vars(2) = 55 'D
    Vars(3) = 60 'C
    Vars(4) = 87 'D
    Vars(5) = 109 'C
    Gosub Langsam
    Print "Ende Script gehe in Warteschleife"
    Do
    If Pinc.7 = 1 Then
    Var(2) = 350
    Vars(1) = 80 'C
    Vars(2) = 36 'D
    Vars(3) = 40 'C
    Vars(4) = 87 'D
    Vars(5) = 112 'C
    Vars(1) = 80 'C
    Vars(2) = 36 'D
    Vars(3) = 40 'C
    Vars(4) = 87 'D
    Vars(5) = 112 'C
    Goto Restart

    End If
    Loop
    End

    '-------------------------------------------------------------------------------
    '------- ISR von Timer 0
    '------- Theoretische geschwindigkeit an den Port's 2083,333 Hz
    '-------------------------------------------------------------------------------
    Isr_von_timer1: 'ISR von Timer0
    Load Timer0 240 'Timer0 soll wieder von 240 wegzählen bis 256
    A = A + 1 'Zähler Wert erhöhen
    If A = 480 Then 'Rücksetzen des Wertes und starten einer neuen Periode
    A = 0
    Porta.0 = 1 'Ports Wieder Anschalten
    Porta.1 = 1
    Porta.2 = 1
    Porta.3 = 1
    Porta.4 = 1
    Porta.5 = 1
    End If
    If A = C Then Porta.0 = 0 'Servo 1
    If A = D Then Porta.1 = 0 'Servo 2
    If A = E Then Porta.2 = 0 'Servo 3
    If A = F Then Porta.3 = 0 'Servo 4
    If A = G Then Porta.4 = 0 'Servo 5
    If A = H Then Porta.5 = 0 'Servo 6
    Return 'gehe zur Hauptschleife zurück








    '-------------------------------------------------------------------------------
    '------- Langsam Lauf
    '-------------------------------------------------------------------------------
    Langsam:
    Do
    For Var(1) = 1 To Var(2) : Next Var(1)
    If G > Vars(5) Then G = G - 1
    If G < Vars(5) Then G = G + 1

    If E > Vars(3) Then E = E - 1
    If E < Vars(3) Then E = E + 1

    If D > Vars(2) Then D = D - 1
    If D < Vars(2) Then D = D + 1


    If C > Vars(1) Then C = C - 1
    If C < Vars(1) Then C = C + 1


    If F > Vars(4) Then F = F - 1
    If F < Vars(4) Then F = F + 1


    If H > Vars(6) Then H = H - 1
    If H < Vars(6) Then H = H + 1

    If C = Vars(1) And D = Vars(2) And E = Vars(3) And F = Vars(4) And G = Vars(5) And H = Vars(6) Then Bid = 1
    Loop Until Bid = 1
    Bid = 0
    Return
    '-------------------------------------------------------------------------------
    '------- ENDE
    '-------------------------------------------------------------------------------
    End

Berechtigungen

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