Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMega8 und PWM-In/-Out für RC-Komponenten
stardust19322
01.11.2013, 16:34
Hallo.
Ich möchte gern mit dem ATMega8 PWM-Signale auswerten und auch ausgeben. Bei der Ausgabe bin ich grad am Tüfteln, nutze dazu den Timer1 und einen Prescaler von 8, um auf ein gutes Ausgangssignal zu kommen. Jedoch zittert das Servo stark um die Endlage, bis ich ihn von Hand etwas zurück drehe, sodass er noch einmal die Endlage erreichen muss - dann ist es auch mucksmäußchenstill.
Eine Idee, woran das liegen kann?
LG - Maik
HeXPloreR
01.11.2013, 17:06
Hallo Maik,
..dort aufgrund meiner Lernschwäche auf diesem Gebiet auf starke Bloßstellung, Verspottung und sogar massive Beleidigung... ... ich hoffe, und bin der Meinung, das können wir hier besser machen.
Schau mal in der Bascom Hilfe unter "Pulsein" und "Pulseout". Damit kann man recht einfach schon einen RC-Kanal einlesen.
Ob ein Signal anliegt oder nicht ist eine reine Softwareabfrage des Pins und daraufhin kann man entscheiden ob ein Demomodus eingeleitet wird oder dieser wiedre verlassen werden soll.
Der ATmega kann dabei auf 1MHz eingestellt bleiben. Nur wenn man eine höhere Auflösung benötigt könnte man auf mindestens 4MHz erhöhen, dann muss man aber die Schwellwerte im Programm wieder anpassen - ich würde empfehle also gleich damit zu arbeiten Um änderung zu vermeiden.
Du brauchst nicht zwangsläufig für jeden Kanal auf der Frnbedienung auch eine Eingangspin - man kann auf einem Kanal ganz gut mit PWM-Schwellwerten arbeiten. Mir ist das allerdings immer zu aufwendig, mir zu merken ab welcher Hebelstellung welche Aktion (zusätzlich) ausgelöst wird.
stardust19322
01.11.2013, 17:19
Hallo hexplore.
Habe das Ursprungsthema noch mal stark eingekürzt und werde die Themen nacheinander abarbeiten.
Nun kann ich bereits ein Ausgangssignal erzeugen, mit dem Timer1 und einem Prescaler von 8, jedoch ändert sich an der Ausgangsfrequenz nichts, wenn ich den Quartz auf eine andere Frequenz programmiere. Zudem zittert eben das Servo um die erreichte Endlage, bis ich ihn von Hand weit von dieser wegbewege und er diese erneut anfahren muss - dann klappts, so soll es aber nicht sein.
Eine Idee, woran es liegen kann?
Ich schaue mir die Seite mit deinem Ratschlag gleich an, jedoch ist mein Englisch sehr schlecht, sofern es sich um eine englischsprachige Seite handelt.
LG - Maik
HeXPloreR
01.11.2013, 17:38
Als erstes musst Du die Neutralstellung vom Servo finden. Das zittern kommt entweder von einer einbrechenden Spannung oder auch vom anschlagen am Endanschlag des Servos (was unbedingt vermieden werden sollte), daher langsam an die Endwerte herantasten. Das Ausgangssignal wird vermutlich immer noch zu schnell ausgegeben. Wenn ich richtig gerechent habe, was nicht immer so ist, dann hast Du 1000000Hz / 8 / 256 = ca 488Hz. Das sit etwas zu schnell.
Den Quarz programmierst Du im Programm. Und auch in den Fuses des µC?
Ohne Timer zu programmieren geht es mit dem "Pulseout" Befehl - das sollte für Deine Zwecke erstmal ausreichend sein.
stardust19322
01.11.2013, 18:17
Hallo Hexplore.
Ich bin ja sowas von erleichtert:
Hab mit dem Pulseout-Befehl gerade ein wenig experimentiert und mit folgendem Programm nun endlich ein Servo steuern können:
$regfile = "m8def.dat"
$crystal = 1000000
Dim A As Long
Config Portb = Output
Config Portd = Input
Portb = 0
Portd = 0
Do
If Pind.1 = 1 Then
Gosub Servo_umstellen
Elseif Pind.1 = 0 Then
For A = 0 To 100
Pulseout Portb , A , 500
Next
End If
Loop
Servo_umstellen:
For A = 0 To 100
Pulseout Portb , A , 250
Next
Ist im Groben vorgefertigt, musste es nur auf meine Grundbedürfnisse anpassen.
Nun arbeitet das Servo - aber auch viel zu schnell. Ich möchte, dass das Servo langsam von einer Endlage in die andere fährt. Dazu ist (denke ich) ein Timer und ein Zähler notwendig, u.U. sogar 2. Da ich aber noch nie mit Timern und Zählern gearbeitet habe - komplettes Neuland.
Ich versuche mich zwar in die Materie einzuarbeiten, aber das ist nun wirklich sehr schwierig, denn die Informationen kommen nur sperrlich.
LG - Maik
HeXPloreR
01.11.2013, 18:34
Das ist doch schon mal ganz gut ;)
Du kannst die "250" mal zu einen Zähler machen, den kannst Du dann in jedem Schleifendurchlauf "bearbeiten". Das ist der Wert der das PWM darstellt.
Das "A" im Beispiel steht übrigens für den PORT an dem das Signal herauskommen soll. Wenn Du also nicht wirklich zufällig 101 PORT's hast, würde ich den nicht als Variable an der stelle hinter Pulseout benutzen. Direkt reinschreiben welches der Ausgebe Pin ist. Und für die Zahl 101 benötigt man keinen Long, da reicht ein Byte. Spart schon mal Platz. Falls Bascom das überhaupt intern so lässt.
Der "pulsein" Befehl macht auch was schönes, der zählt nämlich wieviel Pulse über Deinen Empfänger rein kommen. Nützlich, um eine proporzionale Steuerung zu erhalten. Denn benutzt Du hier allerdings leider noch nicht.
$regfile = "m328pdef.dat" 'mege328
'$crystal = 8000000 'Quarzfrequenz
$crystal = 20000000 'Quarzfrequenz
$hwstack = 32
$framesize = 64
$swstack = 32
'$baud = 19200
Ddrd.2 = 1 '1 = Output
'Config Portd.2 = Output
Portd.2 = 0 '0 = 0V
'
Ddrd.4 = 1 '1 = Output
'Config Portd.1 = Output
Portd.4 = 0 '0 = 0V
Ddrd.1 = 1
Portd.3 = 0
Ddrd.0 = 1
Portd.0 = 0
Config Portc.1 = Input
'PullUp's für Input's aktivieren (= 1) / deaktivieren (= 0):
Portc.1 = 1
'Variablen:
Dim Rc_1 As Byte
Dim F1 As Word
'Enable Interrupts
Do
Pulsein Rc_1 , Pinc , 1 , 1
'Print "Channel 1 = " ; Rc_1 ;
'Print " ";
If Rc_1 > 156 And Rc_1 < 160 Then 'F1 = 7000
Ddrd.1 = 0
Portd.1 = 1
Else
Ddrd.1 = 1
Portd.1 = 0
End If
If Rc_1 <= 156 And Rc_1 >= 111 Then
F1 = 158 - Rc_1
F1 = 51 * F1
F1 = 7000 - F1
'Print "F1 = " ; F1
End If
If Rc_1 >= 160 And Rc_1 <= 204 Then
F1 = Rc_1 - 158
F1 = 57 * F1
F1 = 7000 + F1
'Print "F1 = " ; F1
End If
'Pulseout Portd , 1 , F3 '7500 zu 158 bei 20MHz
Pulseout Portd , 1 , 7500
Loop
End
Der code ist nicht ganz sauber im Bereich der Config der Ausgänge weil ich es für Dich mal eben schnell gekürzt habe, damit Du siehst was ich meine.
stardust19322
01.11.2013, 19:26
Hi und hallo.
Danke dir - das kann man nicht oft genug sagen :D.
Ich schaue mir dein File sofort durch, vorher aber noch die Variable "A" als direkten Port definieren.
Bei Problemen poste ich sofort.
Hatte gerade sehr viel zeit damit verbracht, den Zähler selbst einzuarbeiten, aber bei einer kleinen Änderung im Ablauf meckert BASCOM sofort - ich geb aber net auf.
LG _ Maik
- - - Aktualisiert - - -
Aaah - das ist zum Einlesen des PWM-Signals, richtig? Hat ein Weilchen gedauert, bis ich das gecheckt hatte ^^
Hast du vielleicht eine Ahnung, wie ich den Timer in das Programm implementieren kann? Ich kann dem Proggi irgendwie nicht sagen, dass der Ausgangswert 250 ist, von dem er dann hochzählen soll...
Rechne mit 8MHZ Taktfrequenz, daher die 250 als untersten Schwellwert, 500 sind das Maximum. Endanschläge sind dann noch lange nicht erreicht.
LG - Maik
HeXPloreR
01.11.2013, 19:41
Meine Empfehlung ist: lass den Timer erstmal weg, den brauchst Du nicht unbedingt.
Eine neue Variable erstellen, den Wert 250 zuweisen und incr(ementieren) bis maximal Wert 500 erreicht ist.
'(
If variable >= 500 then
variable = 500
else
variable + 1 '(oder auch "incr Variable") der Additionschritt kann bei "+ " auch 2, 5 oder so sein. INCR addiert immer nur 1
end if
')
Würde ich aber erstmal in Abhängigkeit mit der Fernbedienung testen um ein Gefühl zu bekommen was hier passiert.
Die 158 in meinem Codebeispiel ist die Mittelstellung eines gefederten Steuerknüppel, hier wird "genullt" - den Rest macht die dazu gehörige Bedingung.
stardust19322
01.11.2013, 20:14
Ok, versuche ich morgen - für heut ist Endstation und Abendessenszeit ;).
Meine Ergebnisse beim letzten Versuch:
Hatte versucht, den Timer einzubauen. Ich kam dann immerhin schon einmal soweit, dass ich einen Timer damit beauftragen konnte, ab 250 aufwärts zu zählen. Jedoch hörte er auch nicht mehr damit auf und ließ das Servo überlaufen. Habs hier leider nicht weiter hinbekommen = Sackgasse.
Probiere das wie gesagt morgen mit dem von dir genannten Beispiel - vielleicht ist das ja des Rätsels Lösung.
BASCOM und die AVR-Programmierung: Ich denke immer, dass ich soweit bin, und dabei kratze ich gerade mal erst an der Oberfläche.
LG - Maik
stardust19322
03.11.2013, 13:52
Hallo.
Ich habe mir nun die letzten beiden Tage mit dem Thema den Kopf zerbrochen. Vorrangig stieß ich auf einen Artikel von Gerold Penz, welcher so einfach ausgeführt und ausgedrückt noch mehr Verwirrung stiftet.
http://halvar.at/elektronik/servo_mit_bascom_avr/
Es geht dabei um das Problem, dass dieser Befehl anscheinend nicht wirklich ausführbar ist. Sobald ich diesen, so wie er im Programmablauf auf der Homepage abgedruckt ist, eingebe, spielt das Servo quasi verrückt. Es zuckt nur in dem mittel Reload-Wert und Taktfrequenz des Controllers festgelegten Takt in eine Richtung. In dem hier dargestellten Beispiel ca. alle 0,3s. Das Servohorn wird für diese Zeit in nur eine Richtung angestoßen und dann endet der Takt vollständig, sodass das Servohorn wieder kurzzeitig frei drehbar ist. Bedeutet also, dass für diesen Zeitraum gar kein Ausgangssignal anliegt, oder dieses zumindest für das Servo nicht lesbar ist. Werde mich damit heut noch einmal auseinander setzen und mit meinem Mini-Oszi das Signal analysieren.
Weiterhin dreht das Servo mit diesen Takten bis auf den Endanschlag.
Es besteht die Möglichkeit, dass das Problem mit meinem STK500-Board zu tun hat, welches die Masse auf Plus zieht statt umgekehrt, kann ich nicht genau sagen. Ich muss selbst die Ausgänge beim normalen Schalten auf Low setzen, damit die LED am Ausgang leuchtet. Setze ich den Controller stattdessen auf mein Experimentierboard, so ist alles so, wie es sein soll und ich muss die Augänge quasi einmal "togglen".
Woran liegt es also? Ich bin da ein wenig ratlos. Liegt es am Board oder am Programm?
Die besten Erfahrungen und Ergebnisansätze machte ich bislang mit dem Grundablauf, den ich voran schon einmal gepostet hatte. Ich denke, dass ich hier mit den richtigen Befehlen, nem Timer und Zähler, doch noch ein paar Ergebnisse erzielen kann.
Bis dahin bleibt aber alles Weitere ungewiss.
LG - Maik
- - - Aktualisiert - - -
Hab mir gerade noch mal deine Empfehlung genaue angeschaut, Hexplorer. Mit "Incr" konnte ich Erfolge erziehlen, jedoch stieg der Wert stetig an und wurde bei einem Tastendruck nicht wieder auf den Ausgangswert zurück gesetzt.
Ideen?
LG - Maik
stardust19322
03.11.2013, 17:19
Update:
Den von dir geposteten Programmpfad konnte ich erfolgreich einbauen. Zunächst lief das Servo so langsam in eine Richtung und blieb dort stehen.
Mit der nächsten Änderung erreichte ich schon einmal, dass das Servo in eine Richtung fuhr und dann wieder in die Ausgangslage zurück, allerdings auch nur, solange der Taster gedrückt bleibt.
Nun konnte ich noch die dafür passende Selbsthaltung einbauen, welche ich später auch für den DEMO-Modus brauche. Werde das vermutlich komplett als eigenständige Schleife durchlaufen lassen, solange ein Pin aktiv ist (also nicht über einen Taster, sondern über einen Schalter).
Einziges Problem:
Das Servo läuft zu stockend, also keinesfalls flüssig. Ich kann die Auflösung auf 1 runtersetzen, dann fährt es aber auch nur dementsprechend langsam. Mir fehlt also eine Geschwindigkeitskontrolle.
Hier komme ich aber nicht mehr weiter.
LG - Maik
HeXPloreR
03.11.2013, 17:45
Wenn der Sevo nur fährt wenn der Taster gedrückt ist dann würde ich darauf tippen das unter anderem die Bedingung für die Servofahrt nicht stimmt.
Aber ohne den Code kann man da nur raten... ;)
Hast Du die STK500 am Terminal oder LCD angeschlossen?
["code"] 'das hier ersetzt Du mit deinem Programmcode ["/code"] '<----- Kopiere diese Zeile in Deinen Beitrag; die roten " musst Du aus den eckigen Klammern herausnehmen; kein Leerzeichen setzen. Damit erzeugst Du ein Codefenster im Beitrag. Auch bei den erweiterten Beitragsfunktionen, das Code einfügen symbol "#"
stardust19322
03.11.2013, 22:12
Hallo.
Gut, werde ich demnächst so machen, Hexplorer.
Das Problem mit dem SERVO-Befehl und dem nervösen Zucken bestand nun anscheinend einzig und allein in der Tatsache, dass die FUSES falsch gebrannt waren. Sie waren auf einen Systemtakt von 1MHz gestellt - und das ist viel zu wenig. Hab sie nun auf 8MHZ gebrannt und nun klapperts auch wunderbarstens. Sogar besser als erwartet - ich kann nun die Servofahrt so auf meine Bedürfnisse anpassen, wie ich das wollte:
Sehr langsames Öffnen bis zu 20%, danach etwas schneller. Beim Verschließen dasselbe, nur umgekehrt. Ich denke, den restlichen Weg finde ich für dieses Problem allein ;). Schon komisch, dass ein solch verstecktes Detail einem so dermaßen den Kopf zerbrechen kann.
Nun muss ich nur noch ein PWM-Signal auswerten können. Das soll dann aber später ein anderer Controller übernehmen. In meinem Modell werden später 2 arbeiten.
LG - Maik
HeXPloreR
04.11.2013, 22:26
Also wenn es unbedingt jetzt schon für dich mit Timer sein muss, dann könntest du dir das hier (http://www.rn-wissen.de/index.php/Servoansteuerung) mal ansehen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.