PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Software PWM



Feratu
01.11.2007, 14:51
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

Feratu
05.11.2007, 14:38
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