Werbung
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Alles frisch? Ich hab das Pech, daß ich mich immer verbeißen muß und habe heute noch mal ein bißchen simuliert (im Bascom Simulator)
Ausgehend von Deinem Programm vom 28.10., 1:52h habe ich das Zucken zunächst eliminiert - hoffe ich. Verantwortlich war das "Portd.5 = 0" kurz vor Ende der Hauptschleife.
Dann noch ein paar Änderungen nach meinem Gutdünken eingebracht. Siehe Remarks im Programm.
Die Tastensteuerung und auch die Drehzahlsteuerung ist ungut, da sie immer haupsächlich auf die Richtungswechsel warten muß. Die Richtungswechsel würd ich als erstes wieder rausnehmen, da ich mir kaum vorstellen kann, daß man das gut steuern kann. Soll nur eine Demo sein.
Hoffe, daß endlich das Zucken weg ist. Bin auf Erfahrungbericht gespannt und bitte gerne Nachfragen.
GrußCode:' BASCOM-Programm ' Stefan Hoffmann 2009 ' Drehimpulsgeber/Encoder mit ENCODER-Befehl ' ' In: Drehimpulsgeber an d.0 und d.1 sowie Taster ' Testprogramm für A3967 Platine mit Dir Step und Enable ' Modifiziert von Searcher $regfile = "attiny2313.dat" $framesize = 32 $swstack = 32 $hwstack = 34 '1. 32 nach 43 geändert $crystal = 8000000 'Interner Osz. 8 MHz $baud = 9600 ' Inputs: Drehimpulsgeber an d.0 und d.1 sowie Taster an d.3 '-----Deklarationen fuer Drehimpulsgeber: Config Pind.0 = Input Encoder_a Alias Pind.0 'Encoder Signal B an Pin 2 Config Pind.1 = Input Encoder_b Alias Pind.1 'Encoder Signal A an Pin 3 Config Pind.3 = Input Taster1 Alias Pind.3 'Taster Portd.0 = 1 'Pullups für den Drehencoder Portd.1 = 1 '2. pind nach portd geändert Portd.3 = 1 'LED-Outputs stellvertretend für Step, Dir, Enable ' In der endgültigen Hardware liegen: Step/Takt auf PD.2 / Taster auf PD.3 / Enable auf PD4 / Richtung auf PD5 / Config Portd.2 = Output Portd.2 = 0 'das ist Step/Takt - Pin 6 - alles mit Pulldown + LEd_gelb Config Portd.5 = Output Portd.5 = 0 ' Pin 9 - Dir - Richtungssignal Config Portd.4 = Output Portd.4 = 0 ' Pin 16 - Enable - generelles Ein-Ausschaltsignal Config Portb.0 = Output Portb.0 = 0 'Pin 9 - LED_DE - am Drehencoder Anzeige Motor_step Alias Portd.2 Chip_dir Alias Portd.5 Chip_enable Alias Portd.4 Dim Wert As Word Wert = 2 'experimentell ermittelter Startwert für den Drehencoder Dim Zustand As Byte '*****************Deklarationen für den Taster - am DE - für die Lang-kurz- und Doppelklickroutine Dim Zaehler As Byte Const Langzaehler = 100 'Danach gilt die Taste als lange gedrueckt Const Doppelzaehler = 20 'Innerhalb dessen muss zweiter Klick erfolgen Dim Gedrueckt As Byte 'Art des Drueckens (Kurz/Lang/Doppel) Const Kurz = 1 Const Lang = 2 Const Doppel = 3 Dim I As Byte Chip_enable = 1 'Motor aus 'Enable ein raus aus der Hauptschleife Chip_dir = 1 'Dir raus aus der Hauptschleife 'Timer und ISR erst loslaufen lassen, wenn mit Chip_enable Motor aus ist Config Timer0 = Timer , Prescale = 1024 'Timer1 Deklarationen für den Takt des Steppers Dim Timer0_reload As Word 'Portd.4 = 1 'Pullup Widerstand ein für Enable - ****Enable =0 bedeutet Motor On!!!! **** On Timer0 Isr_timer0 'Deklaration der Timerroutine Enable Timer0 'Enable Timer0 nach "On Timer0 Isr..." Enable Interrupts '***********Hauptschleife:********** Do Zustand = Encoder(pind.0 , Pind.1 , Linksroutine , Rechtsroutine , 0) Debounce Taster1 , 0 , Tastenauswertung , Sub Select Case Gedrueckt 'Hier koennen beliebige Anweisungen erfolgen Case Kurz: 'Es wurde einmal kurz gedrueckt Chip_enable = 0 'Motor ein bei einmal kurz gedrückt Waitms 100 Case Lang: 'Die Taste wurde lange gedrueckt For I = 1 To 6 Toggle Chip_dir Wait 6 'Wenn lang gedrückt, wechselt Motor alle 6 Sekunden die Laufrichtung Next I Case Doppel: 'Die Taste wurde doppelt gedrueckt Chip_enable = 1 'Motor aus wenn doppelt gedrückt Waitms 500 End Select ' Portd.2 = 0 'das ist Motorstep ' Portd.5 = 0 'das ist Chip_dir, Verursacher vom Zappeln !!! ' Portb.4 = 0 'das ist ??? Loop End '**********************Interrupt-Routine Timer0 ************************************ Isr_timer0: Timer0_reload = 4 'Vorgabe für 38 / sec Timer0 = Timer0_reload + Wert Toggle Motor_step '= Stepper_takt Return '***********************Sub-Routinen Drehencoder *********************************** Linksroutine: Decr Wert If Wert < 1 Then Wert = 1 End If Return Rechtsroutine: Incr Wert If Wert > 230 Then Wert = 230 End If Return '*****************Subroutine Tasterauswertung ***************************** Tastenauswertung: Zaehler = 0 Do Incr Zaehler Waitms 10 Loop Until Taster1 = 1 Or Zaehler = Langzaehler If Zaehler = Langzaehler Then 'lange gedrueckt Gedrueckt = Lang Else 'einmal kurz gedrueckt Zaehler = 0 Do Incr Zaehler Waitms 10 Loop Until Taster1 = 0 Or Zaehler = Doppelzaehler If Zaehler = Doppelzaehler Then 'bleibt bei einmal kurz Gedrueckt = Kurz Else Gedrueckt = Doppel 'zweites Mal kurz gedrueckt End If End If Return
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Hallo Searcher,
Du bist genial!!! In der Tat war es wohl dieses Setzen von Chip_dir und Chip_enable in der Hauptschleife das diese Zuckungen verursacht. Ich hab jetzt nur mal Deinen letzten Code reingeschossen und damit läuft der Schritti jetzt wunderbar weich und regelmäßig und wird genau nach meinen Vorstellungen gestoppt, hin und her gedreht und wieder gestartet - einfach klasse!
Allerdings ist jetzt die Geschwindigkeitsregelung abhanden gekommen, ich schau mir das noch mal an, komme heute abend wieder rein.
Das genial überhöre ich malaber trotzdem Danke. Nach den ganzen Versuchen kann ich das gar nicht glauben.
Sollte gehen, wenn der Stepper nicht in dem Laufrichtungswechselmodus ist
Nochmal was zum reinschießen. Die Zeiten und Anzahl der Laufrichtungsumschaltungen wird nun in einer neuen ISR von Timer1 gemacht. Vorteil soll sein, daß die Hauptschleife nicht von "wait" aufgehalten wird und die Taster-/Encoderabfragen öfter dran kommen. Das Grüne ist neu gegenüber der letzten Version. Kann ich leider kaum testen, da ich keine HW dafür hab.
GrußCode:' BASCOM-Programm ' Stefan Hoffmann 2009 ' Drehimpulsgeber/Encoder mit ENCODER-Befehl ' ' In: Drehimpulsgeber an d.0 und d.1 sowie Taster ' Testprogramm für A3967 Platine mit Dir Step und Enable ' Modifiziert von Searcher die zweite mit zusätzlichem Timer1 $regfile = "attiny2313.dat" $framesize = 32 $swstack = 32 $hwstack = 34 '1. 32 nach 34 geändert $crystal = 8000000 'Interner Osz. 8 MHz $baud = 9600 ' Inputs: Drehimpulsgeber an d.0 und d.1 sowie Taster an d.3 '-----Deklarationen fuer Drehimpulsgeber: Config Pind.0 = Input Encoder_a Alias Pind.0 'Encoder Signal B an Pin 2 Config Pind.1 = Input Encoder_b Alias Pind.1 'Encoder Signal A an Pin 3 Config Pind.3 = Input Taster1 Alias Pind.3 'Taster Portd.0 = 1 'Pullups für den Drehencoder Portd.1 = 1 '2. pind nach portd geändert Portd.3 = 1 'LED-Outputs stellvertretend für Step, Dir, Enable ' In der endgültigen Hardware liegen: Step/Takt auf PD.2 / Taster auf PD.3 / Enable auf PD4 / Richtung auf PD5 / Config Portd.2 = Output Portd.2 = 0 'das ist Step/Takt - Pin 6 - alles mit Pulldown + LEd_gelb Config Portd.5 = Output Portd.5 = 0 ' Pin 9 - Dir - Richtungssignal Config Portd.4 = Output Portd.4 = 0 ' Pin 16 - Enable - generelles Ein-Ausschaltsignal Config Portb.0 = Output Portb.0 = 0 'Pin 9 - LED_DE - am Drehencoder Anzeige Motor_step Alias Portd.2 Chip_dir Alias Portd.5 Chip_enable Alias Portd.4 Dim Wert As Word Wert = 2 'experimentell ermittelter Startwert für den Drehencoder Dim Zustand As Byte '*****************Deklarationen für den Taster - am DE - für die Lang-kurz- und Doppelklickroutine Dim Zaehler As Byte Const Langzaehler = 100 'Danach gilt die Taste als lange gedrueckt Const Doppelzaehler = 20 'Innerhalb dessen muss zweiter Klick erfolgen Dim Gedrueckt As Byte 'Art des Drueckens (Kurz/Lang/Doppel) Const Kurz = 1 Const Lang = 2 Const Doppel = 3 Dim I As Byte Chip_enable = 1 'Motor aus 'Enable ein raus aus der Hauptschleife Chip_dir = 1 'Dir raus aus der Hauptschleife 'Timer und ISR erst loslaufen lassen, wenn mit Chip_enable Motor aus ist Config Timer0 = Timer , Prescale = 1024 'Timer1 Deklarationen für den Takt des Steppers Dim Timer0_reload As Word On Timer0 Isr_timer0 'Deklaration der Timerroutine Enable Timer0 'Enable Timer0 nach "On Timer0 Isr..." Const Anz_umschaltungen = 6 'Hier Anzahl der Laufrichtungsumschaltungen festlegen, mindestens 2 Dim Umschaltungen As Byte 'Zählt Laufrichtungsumschaltungen Umschaltungen = 0 'initialiesieren (ist aber an dieser Programmstelle sowieso = 0) Dim Sekunden As Byte 'Dient zum Abzählen von Sekunden in der Isr_Sekunden_takt Sekunden = 1 'initialisieren Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1 'Clear Timer on Compare Match Compare1a = 31249 'Wert für eine Sekunde, Timer fängt nach einer Sekunde wieder bei 0 an On Compare1a Isr_sekunden_takt 'Compare1a Interrupt wird erst in der Haupschleife enabled Enable Interrupts '***********Hauptschleife:********** Do Zustand = Encoder(pind.0 , Pind.1 , Linksroutine , Rechtsroutine , 0) Debounce Taster1 , 0 , Tastenauswertung , Sub Select Case Gedrueckt 'Hier koennen beliebige Anweisungen erfolgen Case Kurz: 'Es wurde einmal kurz gedrueckt Chip_enable = 0 'Motor ein bei einmal kurz gedrückt Case Lang: 'Die Taste wurde lange gedrueckt If Timsk.ocie1a = 0 Then 'Wenn Comparematchinterrupt nicht enabled, dann.. Toggle Chip_dir 'Sofort Laufrichtung umschalten Incr Umschaltungen 'Zähler für Laufrichtungsumschaltungen erhöhen Timer1 = 0 'Timercounter von Beginn an laufen lassen set Tifr.Ocf1a 'vorsorglich interruptflag löschen Enable Compare1a 'ISR für Sekundenzählen und Chip_dir Toggle einschalten Else If Umschaltungen = Anz_umschaltungen Then 'Wenn genug Umschaltungen, dann aufhören Disable Compare1a 'Isr für Chip_dir toggle abschalten Sekunden = 1 'Für nächsten Gebrauch initialisieren Umschaltungen = 0 'Für nächsten Gebrauch initialisieren Gedrueckt = Kurz 'Flicken wg. vermuteter Macke End If End If Case Doppel: 'Die Taste wurde doppelt gedrueckt Chip_enable = 1 'Motor aus wenn doppelt gedrückt Disable Compare1a 'Isr für Chip_dir toggle abschalten Sekunden = 1 'Für nächsten Gebrauch initialisieren Umschaltungen = 0 'Für nächsten Gebrauch initialisieren End Select Loop End '**********************Interrupt-Routine Timer1 Sekundentakt *********************** Isr_sekunden_takt: 'ISR toggelt alle 6 Sekunden den Chip_dir If Sekunden < 6 Then 'solange noch keine 6 Mal durchlaufen ... Incr Sekunden '...nur inkrementieren Else 'sonst ... Sekunden = 1 'Sekundenzähler zurücksetzten und ... Toggle Chip_dir '... Laufrichtung umschalten Incr Umschaltungen 'Zähler für Laufrichtungsumschaltungen erhöhen End If Return '**********************Interrupt-Routine Timer0 ************************************ Isr_timer0: Timer0_reload = 4 'Vorgabe für 38 / sec Timer0 = Timer0_reload + Wert Toggle Motor_step '= Stepper_takt Return '***********************Sub-Routinen Drehencoder *********************************** Linksroutine: Decr Wert If Wert < 1 Then Wert = 1 End If Return Rechtsroutine: Incr Wert If Wert > 230 Then Wert = 230 End If Return '*****************Subroutine Tasterauswertung ***************************** Tastenauswertung: Zaehler = 0 Do Incr Zaehler Waitms 10 Loop Until Taster1 = 1 Or Zaehler = Langzaehler If Zaehler = Langzaehler Then 'lange gedrueckt Gedrueckt = Lang Else 'einmal kurz gedrueckt Zaehler = 0 Do Incr Zaehler Waitms 10 Loop Until Taster1 = 0 Or Zaehler = Doppelzaehler If Zaehler = Doppelzaehler Then 'bleibt bei einmal kurz Gedrueckt = Kurz Else Gedrueckt = Doppel 'zweites Mal kurz gedrueckt End If End If Return
Searcher
Geändert von Searcher (29.10.2012 um 14:28 Uhr) Grund: Ergänzung: set Tifr.Ocf1a, Flicken
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Hallo searcher,
doch genial!
Diese neue Kombination macht jetzt haargenau was ich mir ausgedacht hatte. Abgesehen von ein paar Verschluckern, wenn man ihn hochregelt, das scheint aber mit Resonanzfrequenzen des verwendeten Motors zu tun zu haben, ein anderer Motor macht das nicht.
Ich werde noch mit den Timerwerten für die Umschaltung experimentieren, aber im Prinzip bin ich gerade wunschlos glücklich! Vielen, vielen Dank für Dein "Durchbeißen" mit diesem Stück Programm, das hätte ich nie zum Laufen gebracht!
Man lernt allerdings daraus auch, dass man nicht alles verstehen muss (warum im vorletzten Stück Code das Regeln der Geschwindigkeit weg ist...), vielleicht knie ich mich da auch noch mal rein. Für den Moment ist es jedenfalls mal gut.
Dir einen schönen Sonntag noch, Searcher, und bis dann mal wieder!
LG MM
Freut mich, daß es für Dich paßt. Im Programm kann man aber noch viele Verbesserungen und Optimierungen vornehmen.
- Man könnte zB versuchen den Takt für den Stepper HW-mäßig auszugeben.
Dazu den zB den OC0A Pin als Ausgang zum Stepper nutzen. Da ließe sich die Isr_Timer0 sparen- Mit erstem kurzen Tastendruck den Motor einschalten, wie jetzt und mit anderem kurzem Druck den Laufrichtungswechselmodus wieder ausschalten, wenn dieser eingeschaltet ist. Motor läuft weiter nur in eine Richtung.
- Programmlesbarkeit/-übersichtlichkeit verbessern
- usw.
- aber siehe auch meine Signatur
![]()
Theorie zur verloren gegangenen Geschwindigkeitsregelung in den alten Versionen:
Debounce und Encoder werden pro Hauptschleifendurchlauf einmal aufgerufen.
Gerade wenn der Laufrichtungswechselmodus läuft, hat der Hauptschleifendurchlauf eine sehr lange Verzögerung in dem entsprechenden Case.
Der Alps liefert an seinen beiden Ausgängen vier verschiedene Zustände.
Die Encoder Funktion vergleicht den Zustand in einem Durchlauf mit dem folgenden Zustand im nächsten Durchlauf.
Vergeht dazwischen viel Zeit, kriegt die Encoder Funktion Zustandswechsel nicht mit, weil von einem Aufruf zum anderen 4 Wechsel stattgefunden haben und könnte dann keine Betätigung erkennen.
Es könnte auch zu falschen Auswertungen kommen; Rechtsdrehung statt Linksdrehung, wenn die Zustände zu weiteren ungünstigen Zeitpunkten erfaßt werden.
Ich bin doch auch nur ein Hobbyprogrammierer und fand in Deinem Problem eine dankbare Aufgabe. Also eigentlich müßte ich Dir danken![]()
PS. Noch eine vermutliche Macke entdeckt und Änderung im letzten Code rot markiert.
Grund: Gedrueckt speichert immer den letzten Zustand und ändert sich erst, wenn
Taste neu betätigt wird. Ohne Änderung wird immer ein neuer Richtungswechselmodus eingeschaltet.
Gutes Gelingen bei Deinem Projekt und
Gruß
Searcher
Geändert von Searcher (29.10.2012 um 14:42 Uhr) Grund: Rechtschreibung
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Hallo Searcher, ich komme doch noch mal rein. ICh habe jetzt noch Deinen zuletzt geänderten Code benutzt und dabei stelle ich fest dass es zwei Frequenzen gibt, wo der Steppermotor wieder zuckt, und zwar kurz vor der schnellsten Drehzahl. Die Code Variante wo es sauber lief, habe ich leider nicht mehr, so dass ich auch nicht rauskriege wo es da klemmt. Ich stelle noch mal ein Video rein:
Link zu Youtube.com
Deine Idee mit dem Hardware- Out am 2313 ist interessant, da wird die ISR überflüssig, aber der Timer wird ja trotzdem gebraucht oder? Läuft der dann per Output Compare Modus? Da muss ich mich noch mal reinlesen.
Hast Du zu dem Zappeln im Aktuellen Code noch eine Idee?
Danke wieder für alle Hinweise!
LG MM
(Verflixt, jetzt ist mir heute beim Testen meine Hardware abgeraucht, muss erstmal wieder löten....)
- - - Aktualisiert - - -
Noch mal zurück auf Null:
Das Zappeln scheint an meiner Hardware zu liegen - ich habe mal testweise mein Ansteuerboard mit dem Pololu breakout Board angestöpselt und siehe da: An diesem treiber läuft der erste Stepper und auch der andere den ich daran betreibe wie ne Eins!
Jetzt muss ich mal auf die Suche gehen.
Die Hardware-Ausgabe wird mich noch beschäftigen, das ist in der Tat eine gute Idee.
Schönen Abend noch!
Lesezeichen