Jens R. schrieb:> Hat jemand soetwas schon einmal programmiert?
Nein, für Schrittmotoren wäre diese Art der Steuerung eher ungewöhnlich.
Wozu soll das Relais gut sein. Ein Schrittmotor läuft nicht einfach los
und fährt dann bis zu einem Endschalter. Ein Schrittmotor muss jeden
einzelnen Schritt gesagt bekommen und die Anzahl der Schritte bestimmt
den Fahrweg. Da braucht man keinen Endschalter. Es reicht eine
Referenzmarke, an der sich der µC orientieren kann. Alles andere ist
Schrittzählerei. Damit er beim Losfahren und Abbremsen keine Fehler
macht, muss die Schrittfrequenz als Rampe ansteigen und zum Anhalten
wieder absinken.
Das Relais schaltet einen Motor an, der erst auf Touren kommen muß,
deshalb die 5 Sek. Wartezeit, ehe der Schrittmotor loslaufen soll. der
treibt einen Schlitten auf einer Linearachse an, der bis zur Endlage
fahren, dort soll der Andere Motor abgeschaltet werden und abtouren,
deshalb wieder 5 Sek. warten und wieder zur Ausgangspos. zurückfahren.
Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus
unterschiedlichen Gründen. Somit würde sich die Position immer mehr
verschieben. Die Endschalter wären sozusagen eine Sicherheit, aber wenn
das mit der einfachen Zählerrei auch gut funktioniert, könnte ich es so
machen. Das vereinfacht das Ganze erheblich, ich habe da glaube ich
schon einen Code in einer Bibliothek gesehen. Das mit der Rampe macht es
wieder komplizierter.
Näheres zum Projekt hier:
Beitrag "Vorschubsteuerung für Gehrungssäge"
Hallo Jens,
mach doch bitte nicht mehrere Threads zu einem Thema auf.
Hier in "Compiler und IDEs" bist Du sowieso völlig falsch.
Jens R. schrieb:> Ich blutiger Anfänger, was das Programmieren angeht.
Mein Tip:
Klein anfangen, dann hat man schneller Erfolgserlebnisse.
Fang damit an, eine LED blinken zu lassen.
Wenn Du am Anfang gleich ein komplexes Projekt angehst,
dann ist die Gefahr gross, dass das Interesse nachlässt,
wenn es nicht funktioniert.
Jens R. schrieb:> Das Relais schaltet einen Motor an
Was für ein Motor?
Es gibt bestimmt bessere, elektronische Möglichkeiten.
Vermeidet dann z.B. den Abreissfunken beim Ausschalten.
Jens R. schrieb:> Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus> unterschiedlichen Gründen.
Das passiert nur Bastlern.
Wenn man das als professioneller Elektronikentwickler angeht, dann
ermittelt man vorab das benötigte Drehmoment.
Dann programmiert man die Fahrt mit Beschleunigungs- und
Bremsrampen.
Jens R. schrieb:> ich habe da glaube ich> schon einen Code in einer Bibliothek gesehen
Das Programm ohne Nutzung fremder Bibliotheken (Libraries) zu
schreiben hat einen viel höheren Lernfaktor ;-)
P.S.: Du scheinst schon etwas älter zu sein, denn ich meine in
einem der anderen Threads "220V" gelesen zu haben. Das war einmal ;-)
Jens R. schrieb:> Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus> unterschiedlichen Gründen.
Dann ist der Antrieb falsch dimensioniert.
Positionssensensorik bei Schrittmotoren ist nur eine Krücke, um das zu
vertuschen.
Ein Schrittmotor, der bei höherer Schrittgeschwindigkeit einem Schritt
des Feldes nicht richtig folgen kann, bleibt rappelnd hängen und folgt
dem Feld erst wieder nach drastischer Reduzierung der Schrittfrequenz.
Es reicht, wenn es irgendwo auf der Fahrstecke eine Referenzmarke gibt
und die Steuerung weiss, in welcher Fahrtrichtung sich die Marke
befindet.
tommy schrieb:> Hallo Jens,> mach doch bitte nicht mehrere Threads zu einem Thema auf.>
Es handelt sich um unterschiedliche Aspekte in meinem Projekt, die in
unterschiedlichen Themengruppen behandelt werden. Ich möchte die
Experten, die sich in den entsprechenden Themengruppen umsehen,
erreichen.
> Hier in "Compiler und IDEs" bist Du sowieso völlig falsch.>
Es geht mir hier nur um die Programmierung, welche Gruppe wäre dann hier
die richtige?
>> Das Relais schaltet einen Motor an>> Was für ein Motor?> Es gibt bestimmt bessere, elektronische Möglichkeiten.> Vermeidet dann z.B. den Abreissfunken beim Ausschalten.
Da geht es um die Elektronik, das in einem anderen Themengebiet
behandelt wird
>> Das Programm ohne Nutzung fremder Bibliotheken (Libraries) zu> schreiben hat einen viel höheren Lernfaktor ;-)
O.K. werde ich versuchen.
> P.S.: Du scheinst schon etwas älter zu sein, denn ich meine in> einem der anderen Threads "220V" gelesen zu haben. Das war einmal ;-)>
Ja Ü50, jetzt sind es wohl 230V die Umstellung ist mir doch glatt
entgangen.
Ich danke für die Belehrungen in Bezug auf Schrittmotoren, aber in einem
anderen Beitrag war jemand der Meinung, dass wenigstens ein Schalter
sein muß. Nun ja so ist das halt.
Ich bin nur ein kleiner Bastler, der eine Idee umzusetzen versucht.
Wenn`s nicht funktioniert bleibe ich bei Handbetrieb.
Wie gesagt, hier geht es nur um`s Programmieren.
Ich fange mal an und bitte euch um eure Meinung.
Jens R. schrieb:> ... aber in einem anderen Beitrag war jemand der Meinung, dass wenigstens> ein Schalter sein muß.
Benötigt wird ein Positionssensor. Das kann z.B. eine Lichtschranke
irgendwo auf dem Weg sein, die dem Contoller mitteilt: "Der Schlitten
ist jetzt beim Sensor".
Wolfgang schrieb:> Jens R. schrieb:>> ... aber in einem anderen Beitrag war jemand der Meinung, dass wenigstens>> ein Schalter sein muß.>> Benötigt wird ein Positionssensor. Das kann z.B. eine Lichtschranke> irgendwo auf dem Weg sein, die dem Contoller mitteilt: "Der Schlitten> ist jetzt beim Sensor".
Warum dann nicht ein Rollenschalter, den habe ich gerade da, am Wegende?
Und wenn da schon einer ist, kann doch am Weganfang auch einer sein, den
habe ich nähmlich auch gerade da.
Ich arbeite an einer CNC-Maschine mit hochgenauen Messsystem, trotzdem
gibt es auch hier noch Endschlter!
Ist das dann auch unnötig? Dann bau ich sie heute noch aus.
Udo K. schrieb:> Und um was geht es genau?>> Oder ist das wieder so ein supergeheimes Ding aus dem> Verteidigungsministerum?
Nein natürlich nicht.
Also ich habe mir eine Gehrungssäge gebaut.
Eine Kreissäge angetrieben von einem Brushlessmotor.
Die Säge sitzt auf einem Schlitten, der hin und her rutscht.
Damit ich das Ganze nicht mehr von Hand betätigen muß und um weit weg
von gefährlichen sich drehenden Teilen zu sein soll die Hin-Herbewegung
automatisch erfolgen.
Also wie folgt:
-Sägenmtor an
-hochtouren lassen
-Vorschub an
-am Ende der Wegstrecke angelangt anhalten
-Sägenmotor abschalte
-abtouren
-Vorschub zurück in Ausgangslage
und aus
Anbei mal ein Bild davon
Ich beginne mal mit einer Trockenübung:
Ich habe mal versucht einen Code zu schreiben, um das Relais am Anfang
einzuschalten und eingeschaltet zu lassen.
Bitte nicht lachen, es sind meine ersten Gehversuche.
void setup() {
pinMode(2,OUTPUT);
pinMode(3,INPUT);
}
void loop() {
if (digitalRead(3)==HIGH;digitalRead(2)==LOW)
{
digitalWrite(2,HIGH)
else digitalWrite(2,HIGH)}
}
Mich verwirrt, die Schleife (void loop) warum kann ich das Relais nicht
einfach einschalten und weiter im Programm?
Jens R. schrieb:> Warum dann nicht ein Rollenschalter,> ...> Ich arbeite an einer CNC-Maschine mit hochgenauen Messsystem, trotzdem> gibt es auch hier noch Endschlter!> Ist das dann auch unnötig? Dann bau ich sie heute noch aus.
Rollenschalter sind eher nicht hochgenau, also nicht zur
Positionsbestimmung geeignet. Du solltest zwischen Maschinensteuerung
und Sicherheitstechnik unterscheiden.
Wolfgang schrieb:> Jens R. schrieb:>> Warum dann nicht ein Rollenschalter,>> ...>> Ich arbeite an einer CNC-Maschine mit hochgenauen Messsystem, trotzdem>> gibt es auch hier noch Endschlter!>> Ist das dann auch unnötig? Dann bau ich sie heute noch aus.>> Rollenschalter sind eher nicht hochgenau, also nicht zur> Positionsbestimmung geeignet. Du solltest zwischen Maschinensteuerung> und Sicherheitstechnik unterscheiden.
Hochgenau positionieren möchte ich nicht, für mich sind die
Rollenschalter sicherheitstechnisch relevant, da sie die Endlage
kontrollieren, sonst kann ich sie auch weglassen. Ich denke eine Abfrage
der Schalter sollte programmtechnisch eher gering im Aufwand sein und da
sie sowieso vorhanden sind kann es ja nicht schaden.
In meiner kleinen Fräse im Keller sind auch diese Dinger verbaut und
funktionieren seit 3 Jahren reibungslos, wie gesagt nur als Endschalter.
Jens R. schrieb:> Per Tasterdruck soll ein Relais geschaltet werden, nach ca. 5 Sek. soll> ein 2 Phasen Schrittmotor losdrehen und bis zur Betätigung eines> Endschalters fahren, dort anhalten,
Warum nimmst Du da nicht einfach einen DC-Motor? Dann funktioniert
die Schaltung ganz ohne Elektronik.
Wolfgang schrieb:> Nein, für Schrittmotoren wäre diese Art der Steuerung eher ungewöhnlich.
Nicht wenn man definierte Drehzahlen bei unterschiedlichen
Lastverhältnissen braucht. Da sind Stepper durchaus eine einfache
Möglichkeit.
@TO:
Du erzeugst doch die Step und Direction Signale für die
Schrittmotortreiber.
Was genau ist jetzt das Problem diese höchst einfache Aufgabe in einen
zeitlichen Programmablauf zu drücken?
Mit zwei Pins für die Stepper wackeln.
delay_ms() verwenden und mit zwei weiteren Pins für die Reails wackeln.
Mir ist ein Licht aufgegangen.
Jens R. schrieb:> Mich verwirrt, die Schleife (void loop) warum kann ich das Relais nicht> einfach einschalten und weiter im Programm?
Ich versuche mir mal selbst zu antworten,
der µC fängt sofort wenn er unter Strom steht das gespeicherte Programm
abzuarbeiten an, ohne Anstoß von außen.
Wäre da nicht dieses dauernde Durchlaufen, könnte man höchstens einen
Code ausführen, Eingaben könnten aber nicht überwacht werden.
Richtig?
Wieder was gelernt!
Sollte ich jetzt für den Code einen neuen Beitrag eröffnen in der
entsprechenden Gruppe?
Die älteren Beiträge könnten geschlossen werden, weil erledigt.
Wie macht man den so etwas.
Jens R. schrieb:> Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus> unterschiedlichen Gründen.
Welche Erfahrung sol das sein ?
Deine Erfahrung ? Ich dachte, du hast keine Erfahrung.
Ein Schrittmotor, der Schritte verliert, wurde falsch eingesetzt.
Jens R. schrieb:> Bitte nicht lachen, es sind meine ersten Gehversuche.>> void setup() {> pinMode(2,OUTPUT);> pinMode(3,INPUT);> }>> void loop() {> if (digitalRead(3)==HIGH;digitalRead(2)==LOW)> {> digitalWrite(2,HIGH)> else digitalWrite(2,HIGH)}> }>> Mich verwirrt, die Schleife (void loop) warum kann ich das Relais nicht> einfach einschalten und weiter im Programm?
Ja, das sind sehr die Anfänge.
Benutze zum Betrieb eines Schrittmotortreibers an einem Arduino eine
Library wie https://www.airspayce.com/mikem/arduino/AccelStepper/
denn die eingebaute https://www.arduino.cc/en/Reference/Stepper
kann keine Schrittmotortreiber mit DIR und STEP Anschlüssen
1
#include<AccelStepper.h>
2
AccelSteppermyStepper(AccelStepper::DRIVER,8,9);// Schrittmotortreiber an Pin 8 und 9
MaWin schrieb:> Jens R. schrieb:>> Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus>> unterschiedlichen Gründen.>> Welche Erfahrung sol das sein ?>> Deine Erfahrung ? Ich dachte, du hast keine Erfahrung.>> Ein Schrittmotor, der Schritte verliert, wurde falsch eingesetzt.
Erfahrungen von meiner CNC Eigenbaufräse im Keller.
Die wird von einer Software betrieben, da habe ich mir noch keine
Gedanken über den Code gemacht, der diese ansteuert.
MaWin schrieb:> Benutze zum Betrieb eines Schrittmotortreibers an einem Arduino eine> Library wie https://www.airspayce.com/mikem/arduino/AccelStepper/> denn die eingebaute https://www.arduino.cc/en/Reference/Stepper> kann keine Schrittmotortreiber mit DIR und STEP Anschlüssen> [c]> #include <AccelStepper.h>> AccelStepper myStepper(AccelStepper::DRIVER , 8, 9); //> Schrittmotortreiber an Pin 8 und 9>> Dein setup nutzt Pin3 für den Taster, Pin2 für das Relais, du brauchst> noch einen Endschalter an Pin4 und einen Anfangsschalter auf Pin5.>> Dein loop sollte auf den Tastendruck warten
Ist klar der Code ist Mist.
Ich habe mich auch schon etwas weiter informiert.
Erstmal Dank für die konstruktive Hilfe!
Ich habe mir auf nem Zettel schon ein bisschen Code zusammengebastelt,
der muß nur noch eigegeben werden.
Die Teile sind unterwegs, so mache ich jetzt Trockenübungen.
Einen Simulator will ich mir auch noch installieren.
Durch den Schrittmotortreiber muß ich, wenn ich richtig verstenden habe,
doch nur ein Dir-Signal auf Dir-Pin (High oder Low) senden und der Takt
wäre dann nur High, Delay, Low, Delay Auf Step-Pin.
Ist das nicht so?
'state machine' wäre ein Stichwort um passendes Futter zu suchen. Damit
wird es etwas übersichtlicher und auch so Sachen wie Schnell/Nothalt
besser zu realisieren.
Johannes S. schrieb:> 'state machine' wäre ein Stichwort um passendes Futter zu suchen. Damit> wird es etwas übersichtlicher und auch so Sachen wie Schnell/Nothalt> besser zu realisieren.
Naja zumindest kein: "Oh Gott, was für ein Müll."
In einer letzten Antwort wurde mir geraten, Bibliotheken zu meiden, um
etwas dazuzulernen. Das habe ich auch vor.
Bevor noch Fragen wie : "Du hast noch nie zuvor programmiert?" kommen,
ja ich habe verschieden Sachen mit Excel ausprobiert und auf der Arbeit
"programmiere" ich Tag täglich, eine CNC-Maschine mit
Heidenhain-Steuerung.
Jaja, von wegen programmieren, aber das Grundverständnis von Schleifen
und Abfragen ist auch dort wichtig und in gewissen Maße kann man da auch
richtig "programmieren".
Jens R. schrieb:> Naja zumindest kein: "Oh Gott, was für ein Müll."
Wenns funktioniert, ist es kein Müll.
Die Delay Kontruktionen haben nur den Nachteil, das die MCU sich dabei
im Kreis dreht und nix anderes währenddessen macht.
Ich schreibe mir für sowas eine Timer ISR die alle xx ms ein flag setzt.
Muss nicht schneller sein als die kürzenste Zeitspanne die Du benötigst.
Mit Statemachine löscht Du das Flag, tackerst Du die verschiedenen
Zustände der Reihe nach durch und zählst im entsprechendne State den
jeweiligen Counter hoch und triffst die Entscheidung ob die Zeit
abgelaufen ist.
Danach gehts zurück ins Hauptprogramm und Du kannst alles andere
erledigen.
Z.B. Nothalt.
So springst Du nur jeweils zu den Timer Abläufen kurz in die Bearbeitung
und blockierst die Kiste nicht.
Jens R. schrieb:> In einer letzten Antwort wurde mir geraten, Bibliotheken zu meiden, um> etwas dazuzulernen. Das habe ich auch vor.
Mit Delay und digitalWrite etc. machst Du aber nix anderes.
Mach Dir mal den Spaß und setze mit digitalWrite einen Pin auf eins und
gleich danach wieder auf null.
Schau Dir auf dem Oszi an wie lange das dauert, da bekommst Du eine
Vorstellung davon wie unglaublich ineffizient das ist.
Ist oft egal, wenn die Kiste nur das tut was Du willst, aber Du willst
ja lernen.
Aha verstehe, den Notaus habe ich noch gar nicht drin, aber während des
Hoch-und Ab-Tourens kann ich drauf rumkloppen wie ich will, es passiert
nichts.
Aber leider verstehe ich "noch" null von flags u.s.w.
Danke für deine Hilfe.
Ich brauche erst noch alle Teile um richtig experimentieren zu können.
Und dann Schritt für Schritt weiter.
Ich finde das alles wirklich toll, wie man mit diesem Arduino als Laie
auch schnell zu einem Ergebnis kommen kann.
Jens R. schrieb:>> Deine Erfahrung ? Ich dachte, du hast keine Erfahrung.>> Ein Schrittmotor, der Schritte verliert, wurde falsch eingesetzt.> Erfahrungen von meiner CNC Eigenbaufräse im Keller.
Örks, meine Erfahrung bisher lautet:
Du hast keine Ahnung vom Aufbau von Mechanik
und der Auslegung und Ansteuerung von Motoren.
Nein, Dinge funktionieren nicht einfach, wenn man sie beliebig falsch
macht.
Jens R. schrieb:> pinMode(4; OUTPUT); //Endschalter> pinMode(5; OUTPUT); //Anfangsschalter
?!?
Jens R. schrieb:> digitalRead(StartPin)//Abfrage Starttaster> if (StartPin == HIGH) { //Wenn Starttaster gedrückt
?!?
Hier auch: Bei so wenig Aufmerksamkeit gegenüber der Lösung wird das
nichts damit, Mikrocontroller damit zu programmieren was sie zu tun
haben.
Ja, danke für den Hinweis,
die Schalter sind ja wohl INPUT.
Doing bei learning habe ich gelesen, wenn hier nur die Fehler aufgezählt
werden, will ich eure wertvolle Zeit nicht weiter verschwenden und mache
weiter, bis der letzte yC sein Leben ausgehaucht hat.
Ich danke für die Hilfe!
Jens R. schrieb:> Aber leider verstehe ich "noch" null von flags u.s.w.
Ein Flag ist nur ein Bit.
Der Timer läuft ab und setzt das Bit.
Das ist das Zeichen, das Zeit xx abgelaufen ist.
Deine Auswertung startet sobald das Flag gesetzt ist und setzt es dabei
zurück, damit wieder Zeitablauf signalisiert werden kann.
ISR bedeutet Interrupt Service Routine.
Der Timer im uC ist ein kleines Stück Hardware, das man über seine
Register so einstellt, das es, unabhängig vom Rest des uC, in
regelmäßigen Zeitabständen dem uC signalisiert, das er all seine
Tätigkeiten unterbrechen und an einen bestimmten Programmbereich
springen soll, an dem es Code abzuarbeiten gilt.
In der ISR macht man im allgemeinen so wenig wie möglich, um den
normalen Programmablauf so wenig wie möglich zu blockieren.
Zieh Dir das Datenblatt des Microcontrollers der auf deinem arduino
verbaut wurde. Da steht alles drin was Du wissen musst.
Die ganze Arduino Umgebung verschleiert ein wenig, das dahinter auch nur
ein kleiner uC läuft, den man auch ohne die ganzen Arduino Libs beackern
kann.
Ich kenne mich mit Arduino zu wenig aus um zu sagen welche Timer bereits
belegt sind um z.B. delay() zu realisieren.
> Danke für deine Hilfe.
Du fragst vernünftig und bist bereit zuzuhören.
Da hilft man gern.
Lass Dich von dem rauen Ton nicht irritieren.
Frag einfach wenn Du was nicht verstehst und bleib freundlich als
Fragesteller, auch wenns mal pampig wird.
Dann wird sich meist schon jemand finden der hilft.
Jens R. schrieb:> will ich eure wertvolle Zeit nicht weiter verschwenden
Die verschwenden wir hier ja ganz freiwillig.
Ich habe mir den Simulator for Arduino von Virtronics geladen und meinen
Code simuliert.
Die Fehler habe ich beseitigt, weiß jemand zufällig, wie man einen
Tastendruck (input) da simuliert?
Oder gibt es da bessere Simulatoren?
M. K. schrieb:> Ein Flag ist nur ein Bit.> Der Timer läuft ab und setzt das Bit.> Das ist das Zeichen, das Zeit xx abgelaufen ist.> Deine Auswertung startet sobald das Flag gesetzt ist und setzt es dabei> zurück, damit wieder Zeitablauf signalisiert werden kann.>> ISR bedeutet Interrupt Service Routine.> Der Timer im uC ist ein kleines Stück Hardware, das man über seine> Register so einstellt, das es, unabhängig vom Rest des uC, in> regelmäßigen Zeitabständen dem uC signalisiert, das er all seine> Tätigkeiten unterbrechen und an einen bestimmten Programmbereich> springen soll, an dem es Code abzuarbeiten gilt.> In der ISR macht man im allgemeinen so wenig wie möglich, um den> normalen Programmablauf so wenig wie möglich zu blockieren.> Zieh Dir das Datenblatt des Microcontrollers der auf deinem arduino> verbaut wurde. Da steht alles drin was Du wissen musst.
Ich ahne ungefähr, worauf du hinaus willst.
In so tiefe Gründe will ich dann doch nicht hinabtauchen.
Trotzdem werde ich wahrscheinlich bald vor einem Problem stehen:
Momentan bin ich mit meinem Code so weit fertig. Die Simulation läuft
prächtig und macht alles richtig. Mit Nano hatte ich so meine
Verbindungsschwierigkeiten (billige China-Büchse), habe den Code aber
erfolgreich draufgespielt und nur mit LED`s mal getestet.
Jetzt habe ich folgende Idee:
Ich möchte den BL-Motor über den Fahrtenregler direkt per ESC
ansteueren.
programmtechnischnisch ist das kein Problem. Anschließend läuft der
Schrittmotor in einer Dauerschleife durch bis zum Endschalter. Dabei muß
der Fahrtenregler, denke ich, parallel sein 2ms-Signal
(Highspeed)erhalten sonst fällt er zurück?! Während des delay im
Schrittmotortiming pausiert der Prozessor aber. Hast du einen Vorschlag,
wie man das lösen kann?
Hier mein derzeitiger Code:
Johannes S. schrieb:> State machine, das Stichwort hatte ich schonmal genannt.
Ja wie löst das jetzt das Problem der Parallelabarbeitung
(ESC/Schrittmotor)?
Ich habe schon wirklich sehr viel gelesen, das ist in der kurzen Zeit
aber schon heftig und für mich schwer zu verstehen.
Ich benutze die Arduino Referenz als Quelle für den Code.
In der englischen Version habe ich mal etwas über eine Yield Funktion
gelesen, die irgendwie in der Delay-Zeit etwas abarbeiten kann.
Ich wäre über weiterführende Tipps sehr dankbar.
M. K. schrieb:> Ich schreibe mir für sowas eine Timer ISR die alle xx ms ein flag setzt.
Wenn man Arduino verwendet, kann man direkt den sowieso für millis()
laufenden Timer verwenden und sich z.B. per TIMER0_COMPA Interrupt dort
einklinken.
https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers
Oder man prüft den Rückgabewert von millis() auf Änderung gegenüber dem
vorherigen Aufruf ;-)
Alles schon da schrieb:> M. K. schrieb:>> Ich schreibe mir für sowas eine Timer ISR die alle xx ms ein flag setzt.>> Wenn man Arduino verwendet, kann man direkt den sowieso für millis()> laufenden Timer verwenden und sich z.B. per TIMER0_COMPA Interrupt dort> einklinken.> https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers>> Oder man prüft den Rückgabewert von millis() auf Änderung gegenüber dem> vorherigen Aufruf ;-)
Oh ja harter Tobak, für mich jedenfalls, da brauche ich Jahre, das zu
verstehen.
Vielleicht splitte ich die delays für den Schriitmmotor dann doch lieber
auf. Ich habe gelesen, dass der ESC eine Aktualisierung von 50ms
braucht, da muß ich mit den einzelnen delays für den Schrittmotor
drunter bleiben und aktualisiere den ESC dann mehrmals pro
Schrittmotor-Takt.
Nicht gerade elegant, aber ich denke, das kriege ich so auch hin.
Ich hab mir gerade nochmal die "millis" Funktion verinnerlicht, das wird
die Lösung sein.
"millis" Zeit auslesen und in Variable merken,
anstatt delay eine Schleife, mit Abfrage ob die "millis"Variable um
festgelegten Wert erreicht hat, dann folgende Aktion.
In der Schleife kann ich dann belibigen Code ausführen, z. B. den ESC
aktualisieren.
Ich hoffe, ich habe das so richtig verstanden.
hier hatte ich mal ein Beispiel für eine state machine genannt. Es geht
nur ums Prinzip, nicht jetzt hier das konkrete Problem.
Beitrag "Re: Schrittmotor"
Also das Programm rennt immer im Kreis und guckt was aktuell zu tun ist
(die case im switch statement). Wenn ein Schritt fertig kann auf den
nächsten oder einen anderen geschaltet werden. Den cases kann man auch
Namen geben um das übersichtlicher zu machen.
So 'hängt' das Programm nicht in einem Schritt, sondern ist immer bereit
auf Ereignisse zu reagieren. Auch wenn dir dein Programm jetzt einfacher
erscheint, so ein switch-case ist einfacher zu testen.
Johannes S. schrieb:> hier hatte ich mal ein Beispiel für eine state machine genannt. Es geht> nur ums Prinzip, nicht jetzt hier das konkrete Problem.> Beitrag "Re: Schrittmotor">> Also das Programm rennt immer im Kreis und guckt was aktuell zu tun ist> (die case im switch statement). Wenn ein Schritt fertig kann auf den> nächsten oder einen anderen geschaltet werden. Den cases kann man auch> Namen geben um das übersichtlicher zu machen.> So 'hängt' das Programm nicht in einem Schritt, sondern ist immer bereit> auf Ereignisse zu reagieren. Auch wenn dir dein Programm jetzt einfacher> erscheint, so ein switch-case ist einfacher zu testen.
Ich habe das jetzt erst mal so gelöst. Ich hoffe es funktioniert.
Die Simulationmit TinkerCAD ist ein bisschen einfach aber besser als gar
nichts.
1
digitalWrite(DirPin,HIGH);//Richtung Schrittmotor
2
while(digitalRead(EndPin)==HIGH){//Schleife solange Endschalter nicht geschaltet
3
digitalWrite(StepPin,HIGH);//Signal Schrittmotor
4
Time=millis();//aktuelle Laufzeit in Time
5
StepTime=Time+Step;//Zeit für nächstes Schrittmotorsignal berechnen
6
while(StepTime>Time){//Schleife Signal ESC
7
digitalWrite(MotorSpeedPin,HIGH);
8
delayMicroseconds(ESCSpeed);
9
digitalWrite(MotorSpeedPin,LOW);
10
delayMicroseconds(ESCPause);
11
Time=millis();//aktuelle Laufzeit in Time
12
}
13
digitalWrite(StepPin,LOW);//Signal Schrittmotor
14
Time=millis();//aktuelle Laufzeit in Time
15
StepTime=Time+Step;//Zeit für nächstes Schrittmotorsignal berechnen
16
while(StepTime>Time){//Schleife Signal für ESC
17
digitalWrite(MotorSpeedPin,HIGH);
18
delayMicroseconds(ESCSpeed);
19
digitalWrite(MotorSpeedPin,LOW);
20
delayMicroseconds(ESCPause);
21
Time=millis();//aktuelle Laufzeit in Time
22
}
23
}
Eine Frage zur switch Funktion.
in der switch Abfrage wird ja nur eine Funktion, eben die, die die
Bedingung erfüllt, ausgeführt. Das break steigt dann aus, also ist diese
Funktion keine Scleife, wenn ich richtig verstanden habe. so muß ich die
switch Funktion also noch in eine Dauerschleife legen?
Johannes S. schrieb:> Jens R. schrieb:>> so muß ich die switch Funktion also noch in eine Dauerschleife legen?>> Ja, richtig. Aber es blockiert aber nicht an den Delays.
Ah ja. Ostern hab ich Zeit zum probieren.
Die delays sind ja auch immer noch drin.
Jens R. schrieb:> Ja wie löst das jetzt das Problem der Parallelabarbeitung
Tja, das ist genau der Teil in den Du nicht so tief einsteigen willst.
Wasch mir den Pelz, aber mach mich nicht nass...
Entweder löst Du Dich von dem Delay Gemurkse und machst das richtig,
oder Du lebst mit dem Gemurkse.
Aber die Frage einfach nochmal stellen weil die Antwort nicht genehm
war, funktioniert nicht.
M. K. schrieb:> Entweder löst Du Dich von dem Delay Gemurkse und machst das richtig,> oder Du lebst mit dem Gemurkse.> Aber die Frage einfach nochmal stellen weil die Antwort nicht genehm> war, funktioniert nicht.
Na wenigstens hab ich noch deine Aufmerksamkeit.
In einem Punkt hast du recht, ich und auch nur ich werde mit dem
Gemurkse leben müssen.
Dein letzter Beitrag war genauso unfreundlich, aber hilfreicher.
Wenn das ganze erst mal läuft, kräht kein Hahn mehr danach, ob delay
oder nicht delay.
Im Falle eines Scheiterns mache ich ein Video von der abbrennenden
Maschine und stell es hier ein. Dann kommt deine Zeit, dich mit
erhobenen Zeigefinger hinzuzustellen und zu sagen "Ich hab ja gleich
gesagt, der hat von nichts eine Ahnung!"
Ich hoffe auf weiter Beiträge, vielleicht auch mal wieder mit
hilfreichem Inhalt, so wie die der anderen Beteiligten.
Wolfgang schrieb:> Ein Schrittmotor läuft nicht einfach los> und fährt dann bis zu einem Endschalter. Ein Schrittmotor muss jeden> einzelnen Schritt gesagt bekommen und die Anzahl der Schritte bestimmt> den Fahrweg. Da braucht man keinen Endschalter. Es reicht eine> Referenzmarke, an der sich der µC orientieren kann.
Nunja und als Referenzmarke eignet sich besonders gut ein Endschalter ;)
Ausserdem kann man wenn man in der Tat zwei Endschalter benutzt und
auswertet,
eine einfache while loop ohne Schrittzähler schreiben
gehen wir mal von NC schaltern aus:
wäre das
in pseudo code in etwa:
[code]
while(endschalter_ende) schrittmotor.step(fwd);
delay(pause);
while(endschalter_start) schrittmotor.step(rwd);
delay(pause);
[code]
banal, gell?
'sid
sid schrieb:> in pseudo code in etwa:> [code]> while(endschalter_ende) schrittmotor.step(fwd);> delay(pause);> while(endschalter_start) schrittmotor.step(rwd);> delay(pause);> [code]>> banal, gell?
Genau so habe ich es umgesetzt.
Eine Frage zu switch-case.
Ich frage die aktuelle Laufzeit ab, das ist die Vergleichsvariable im
switch
zur Laufzeit addiere ich die Taktzeit um die Bedingung für diesen case
festzulegen und speichere die in einer Variable.
Die Variable kann ich laut Referenz aber nicht im case eintragen.
Bleibt mir nur die Möglichkeit über return der Variable einen Zahlenwert
zuzuweisen?
So klappt das nicht, in switch() muss eine Variable rein die definiert
gesetzt wird. Und dann landet man beim Aufruf in dem passenden case.
Also einfaches Beispiel Ampel: switch(Farbe) und case Rot/gelb/Grün
setzt den entsprechenden Ausgang.
Um eine Schrittkette zu bauen also die einzelnen Schritte definieren und
dann in jedem Schritt (case) weiterschalten wenn eine Bedingung erfüllt
ist.
Jens R. schrieb:> Dein letzter Beitrag war genauso unfreundlich,
Nein, er war ehrlich.
Du hattes gefragt wie Du schnelle Reaktionen in Deinem Zeitablauf
integrieren kannst.
Du würdest ja gerne dazulernen und deswegen bereit sein die LIBs nicht
zu verwenden.
Darauf haben ich und andere geantwortet.
Du hast erkannt, das das eben nicht mal so mit drei Zeilen gemacht ist
und hast entschieden nicht nur bei den LIBs zu bleiben, sondern die auch
noch auf die einfachst mögliche Art einzusetzen..
Das steht Dir zu, ist ja Dein Projekt.
Nun hast Du aber natürlich immer noch die gleichen Probleme, weil Du es
ja weiterhin auf die gleiche Art tust, und stellst einfach nochmal die
Frage wie man die Probleme loswird.
Die Antwort ist aber die gleiche wie zuvor und genau darauf habe ich
Dich hingewiesen.
Nun ist es aber von mir unfreundlich Dir unangenehme Wahrheiten zu
sagen, von Dir aber nicht, die gegebenen Antworten zu ignorieren?
Das widerum macht Dich zu einem der üblichen MC.net Fragesteller und die
verlieren meine Aufmerksamkeit.
M. K. schrieb:> Nein, er war ehrlich.
O.K. ich versteh deine Sprache offensichtlich nicht, aber dass dieses
Forum nichts für Zartbesaitete ist, wurde mir ja schon angekündigt.
M. K. schrieb:> Nun hast Du aber natürlich immer noch die gleichen Probleme, weil Du es> ja weiterhin auf die gleiche Art tust, und stellst einfach nochmal die> Frage wie man die Probleme loswird.
Leider weist du mich nur darauf hin, dass ich alles falsch mache.
Ein Schubs in die richtige Richtung z.B. wäre nicht schlecht.
Ich wurde animiert, es mit der switch-Case Funktion zu probieren, ich
denke, ich habe verstanden wozu sie gut ist, hänge aber an der Umsetzung
fest, wie man an meinem letzten switch-Gemurkse erkennen kann.
Du bist doch Mitglied seit 2012 ich seit 2 Wochen, genau so lange
beschäftige ich mich mit der Programmierei um den Arudino.
Vielleicht könntest du von deiner reichlichen Erfahrung etwas an mich
weitergeben?
M. K. schrieb:> Das widerum macht Dich zu einem der üblichen MC.net Fragesteller und die> verlieren meine Aufmerksamkeit.
Das wäre das letzte, was ich erreichen wollte!
Johannes S. schrieb:> So klappt das nicht, in switch() muss eine Variable rein die definiert> gesetzt wird. Und dann landet man beim Aufruf in dem passenden case.> Also einfaches Beispiel Ampel: switch(Farbe) und case Rot/gelb/Grün> setzt den entsprechenden Ausgang.> Um eine Schrittkette zu bauen also die einzelnen Schritte definieren und> dann in jedem Schritt (case) weiterschalten wenn eine Bedingung erfüllt> ist.
Bitte entschuldige, ich habe deinen Beitrag glatt übersehen.
Danke für die Antwort.
Ich bin da wohl einem Mißverständnis unterlegen.
Hier der korrigierte Code, der zumindest keinen Fehler wirft.
1
igitalWrite(DirPin,HIGH);//Richtung Schrittmotor
2
Time=millis();//aktuelle Laufzeit in Time
3
StepTime=Time+Step;//Zeit für nächstes Schrittmotorsignal berechnen
4
while(digitalRead(EndPin)==HIGH){//Schleife solange Endschalter nicht geschaltet
5
Time=millis();//aktuelle Laufzeit in Time
6
if(Time==StepTime){Zustand=1;}//Zustand wird 1 gesetzt, wenn die akt.Zeit gleich der berechneten Zeit für das Schrittmotorsignal ist
7
switch(Zustand){
8
case1:
9
if(StepPin==HIGH){
10
digitalWrite(StepPin,LOW);//Signal Schrittmotor LOW wenn HIGH
11
}
12
else{
13
digitalWrite(StepPin,HIGH);//Signal Schrittmotor HIGH wenn LOW
14
}
15
Time=millis();//aktuelle Laufzeit in Time
16
StepTime=Time+Step;//Zeit für nächstes Schrittmotorsignal berechnen
17
break;
18
default:
19
digitalWrite(MotorSpeedPin,HIGH);
20
delayMicroseconds(ESCSpeed);
21
digitalWrite(MotorSpeedPin,LOW);
22
delayMicroseconds(ESCPause);
23
break;
Allerdings stellt sich mir die Frage, ob 2 Zustände wirklich den Switch
benötigen, wie man sieht gibt es nicht viel zu entscheiden.
Dieser Code bedient ja auch nur den Zustand Endschalter HIGH.
Wenn ich alle möglichen Zustände ansehe, dann kommt mir das Ganze
plausibel vor. Dann werde ich mein Gerüst mal wieder abreißen und neu
aufbauen.
Bis dahin kann ich ja schon mal die einzelnen Codeschnipsel für
Schrittmotoransteuerung, BL-Motorsteuerung ausprobieren.
Danke für den Stubser in die richtige Richtung.
Bin momentan schwer am Programmieren, sieht auch schon vielversprechend
aus leider noch ohne switch-case.
In der Simulation läuft es auch schon ganz gut.
Jetzt habe ich den Ardunino mit einem einfachen Programm für die
Steuerung des ESC des BL-Motors geladen und da gibt es gleich ein großes
Problem. Der Motor läuft kurz an, und wieder aus. nicht wie
programmiert.
Nun geh ich der Sache erstmal auf den Grund.
Dann teste ich den Schrittmotor mit einem einfachen Programm.
Dann weiter mit Programmieren. Mir qualmt schon der Kopf!
Für den BL Motor über ESC hat Arduino etwas fertiges: die Servo Library.
Teste mal das Beispiele/Servo/Sweep.
Servo erledigt die schnelle Pulsausgabe im Hintergrund per Timer und
Interrupt, das läuft also vor sich hin während du dich um die
Schrittkette kümmern kannst. Mit dem Hardwaretimer ist das präziser, in
SW hast du einen Jitter im Signal. Wenn ein Servo angeschlossen wäre,
dann würdest ein zittern sehen.
Das main bzw. die Arduino loop kann dann nach dem alten EVA Prinzip
arbeiten: Eingabe, Verarbeiten, Ausgabe.
Eingabe ist ein Unterprogramm checkInputs(), das liest alles Taster ein
und macht die Flankenerkennung und erzeugt Ereignisse. So ist das
Weiterverarbeiten einfacher. Ein Button Start setzt dann die
Schrittkette auf den Startschritt.
Für die Schrittkette überlegtst du dir was jeweils passieren soll:
0 stateIdle : Ruhezustand, keine Änderungen
1 stateMoveHome : Säge ausschalten. wenn nicht in Hompos, Schlitten in
Homeposition fahren auslösen. wenn in Homepos, state++
2 stateSawStart : Sägemotor einschalten (spin up kann man später noch
einbauen). Setzte Wartezeit. state++
3 stateMoveEnd: wenn nicht in Endpos, Fahrt in Endpos auslösen sonst
state++
usw.
Johannes S. schrieb:> Für den BL Motor über ESC hat Arduino etwas fertiges: die Servo Library.> Teste mal das Beispiele/Servo/Sweep.
Das ist nicht so einfach mit dem BL-Motor.
Das Problem liegt in der Initialisierung des Fahrtenreglers, der ja noch
zwischen Motor und Arduino hängt.
Aber ich habe eine Bibliothek gefunden, womit es funktionieren könnte.
Somit verabschiede ich mich jetzt von der Idee, alles selbst
programmieren zu wollen. Es wird ja sowieso alles Murks, aber vielleicht
funktionierender Murks.
Johannes S. schrieb:> Für die Schrittkette überlegtst du dir was jeweils passieren soll:> 0 stateIdle : Ruhezustand, keine Änderungen> 1 stateMoveHome : Säge ausschalten. wenn nicht in Hompos, Schlitten in> Homeposition fahren auslösen. wenn in Homepos, state++> 2 stateSawStart : Sägemotor einschalten (spin up kann man später noch> einbauen). Setzte Wartezeit. state++> 3 stateMoveEnd: wenn nicht in Endpos, Fahrt in Endpos auslösen sonst> state++
Das sind dann die case Schritte?
Ich muß aber in Schleifen erst die einzelnen Variablen mit einem Wert
belegen, sodaß im switch das entsprechende case ausgeführt wird.
Sehe ich das richtig so?
Jens R. schrieb:> Ich frage die aktuelle Laufzeit ab, das ist die Vergleichsvariable im> switch
Nein.
Die variable in switch ist der aktuelle BewegungsZustand, steht ja wohl
auch in den case-Kommentaren deutlich drin.
Johannes S. schrieb:> Für den BL Motor über ESC
Er möchte aber einen Schrittmotor ohne ESC.
Michael B. schrieb:> Er möchte aber einen Schrittmotor ohne ESC.
er hat zwei Motoren, einen SM der einen Schlitten mit Säge antreibt und
einen BL mit ESC der das Sägeblatt antreibt. Wenn es noch so ist.
Gegen die Corona Langeweile habe ich mal ein Beispiel für den Nano
gemacht, so wie ich es machen würde.
Die Schrittkette wird über einen Button an D2 (gegen Masse) gestartet.
An D3 ist ein Button mit Stopfunktion.
Am Serial Monitor wird die Änderung des Zustands ausgegeben. Das Servo
ist hier noch nicht drin, kann aber über die Servo Klasse einfach
eingebaut werden.
Arduino ist nicht meine Lieblingsplattform, eventuelle Unschärfen sind
gut möglich.
Jens R. schrieb:> Das Problem liegt in der Initialisierung des Fahrtenreglers, der ja noch> zwischen Motor und Arduino hängt.
Die muss man aber üblicherweise nur einmal machen, der Fahrtenregler
speichert dann die min/max Werte. Das muss also nicht unbedingt in den
gleichen Code mit rein, geht aber auch.
Da kann man auch den Serial Monitor nutzen um zusätzliche Kommandos zu
schicken um nicht alles auf Tasten legen zu müssen. Dafür kann man auch
übergeordnet wieder ein switch/case machen um verschiedene Programme
ablaufen zu lassen und nicht alles in eine riesige Schrittkette
einzufügen.
millis vergleichen kann in die Hose gehen und schon deswegen ist der
switchcase mMn der falsche weg.
zunächst..
Du kannst einen Pin mit sich selbst vergleichen
statt
1
if (StepPin==HIGH){
2
digitalWrite(StepPin, LOW); //Signal Schrittmotor LOW wenn HIGH
3
}
4
else{
5
digitalWrite(StepPin, HIGH); //Signal Schrittmotor HIGH wenn LOW
6
}
reicht
1
digitalWrite(StepPin,!digitalRead(StepPin)); //liest StepPin, und setzt ihn negiert neu
wenn Du millis vergleichen willst sei darauf vorbereitet,
daß der gelesene Wert vom Erwarteten abweichen kann.
ich weiss nicht wie lange die Säge laufen soll
eventuell rennst du sogar in einen timer overflow;
deswegen sei damit extra Vorsichtig..
'sid
sid schrieb:> Du kannst einen Pin mit sich selbst vergleichen> statt
Danke guter Tipp
sid schrieb:> wenn Du millis vergleichen willst sei darauf vorbereitet,> daß der gelesene Wert vom Erwarteten abweichen kann.> ich weiss nicht wie lange die Säge laufen soll> eventuell rennst du sogar in einen timer overflow;> deswegen sei damit extra Vorsichtig..
Deswegen hätte ich >=/<= im Vergleich genommen, um den richtigen Moment
nicht zu verpassen, wenn es das Problem darstellen sollte. Eine
zeitliche Toleranz sollte kein Problem darstellen.
Sonst stecke ich in einem Dilemma, denn delay blockiert nun mal die
Abarbeitung.
Johannes S. schrieb:> Die muss man aber üblicherweise nur einmal machen, der Fahrtenregler> speichert dann die min/max Werte. Das muss also nicht unbedingt in den> gleichen Code mit rein, geht aber auch.
Ich habe eine Bibliothek ESC.h, damit funktioniert es jetzt.
Johannes S. schrieb:> er hat zwei Motoren, einen SM der einen Schlitten mit Säge antreibt und> einen BL mit ESC der das Sägeblatt antreibt. Wenn es noch so ist.>> Gegen die Corona Langeweile habe ich mal ein Beispiel für den Nano> gemacht, so wie ich es machen würde.
Ja so ist es:
Hier die Hardware
Ein BL-Motor für Säge mit Fahrtenregler (ESC-Eingang)
Ein Schrittmotor mit Schrittmotorkarte A4988 (Sep/Dir-Eingang) für
Hin-Her-Bewegung
Ein Taster Start/Stop
Ein Taster Enschalter
Ein Taster Anfangsschalter.
Hier die Befehlskette:
Starttaste gedrückt
1. BL-Motor starten
2. Wartezeit zum Hochtouren des BL-Motor
3. SM-Motor starten Richtung hin
4. Bei Taste Endsch. gedrückt SM-Motor anhalten und BL-Motor ausschalten
5. SM-Motor starten Richtung zurück
6. Bei Anfangssch. gedrückt SM-Motor abschalten
Schleifenende
An allen Positionen soll die Abarbeitung unterbrochen werden können, das
heißt SM-Motor aus BL-Motor aus.
Für einen Neustart bei einer Unterbrechung sollte ganz am Anfang
vielleicht noch die Anfangpos. angefahren werden.
So ist mein Grundkonzept.
In deinem Code finde ich die End/Anf.-Scahlter nicht.
Ein Relais wird nicht benötigt, da der BL-Motor über den ESC gestartet
wird.
Michael B. schrieb:> Nein.>> Die variable in switch ist der aktuelle BewegungsZustand, steht ja wohl> auch in den case-Kommentaren deutlich drin.
Ja danke, das habe ich jetzt kapiert.
tommy schrieb:> Jens R. schrieb:>> Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus>> unterschiedlichen Gründen.>> Das passiert nur Bastlern.
Das halte ich für ein Gerücht.
Dem hier vertraue ich: :-)
http://www.schrittmotor-blog.de/
Eine "Rampe" reduziert die Möglichkeit eines Schrittverlustes - kann
diesen aber nicht gänzlich verhindern.
Hugo H. schrieb:> tommy schrieb:>> Jens R. schrieb:>>> Erfahrungsgemäß kommt es bei Schrittmotoren zu Schrittverlusten, aus>>> unterschiedlichen Gründen.>>>> Das passiert nur Bastlern.>> Das halte ich für ein Gerücht.>> Dem hier vertraue ich: :-)>> http://www.schrittmotor-blog.de/>> Eine "Rampe" reduziert die Möglichkeit eines Schrittverlustes - kann> diesen aber nicht gänzlich verhindern.
Danke für die Unterstützung, deshalb ja die Endschalter. Und die Rampe,
damit die schwere Last in Fahrt kommt.
Jens R. schrieb:> Danke für die Unterstützung, deshalb ja die Endschalter. Und die Rampe,> damit die schwere Last in Fahrt kommt.
Am Ende hast du das gleiche Problem. Nachdem der andere Endschalter
angeschlagen hat, braucht man noch eine Rampe zum Abbremsen, d.h. nach
Ansprechen des Endschalter muss noch genügend Spielraum für die
Abbremsrampe sein. Abhängig von der Fahrgeschwindigkeit fährt der Motor
immer ein Stück über die Endschalterposition hinaus.
Anders ausgedrückt: Mit dieser Vorgehensweise kann der Schrittmotor nie
mit voller Fahrt in Richtung Endschalter fahren und dort anhalten.
Jens R. schrieb:> In deinem Code finde ich die End/Anf.-Scahlter nicht.> Ein Relais wird nicht benötigt, da der BL-Motor über den ESC gestartet> wird.
Das sollte ja auch ein Muster sein und noch nicht die komplette Lösung.
Es funktioniert soweit, habe ich auf dem Steckbrett getestet.
Endschalter sind weitere Eingänge die in checkInputs eingelesen werden,
Flankenerkennung wie bei den Tasten ist bei denen nicht nötig. Die
states enum muss erweitert werden und in processStateMachine() die
entsprechenden Aktionen.
Das Servo Objekt liefert das Timing das für den ESC gleich ist, also
kann man mit servo.write(speed) die Geschwindigkeit vom BL Motor
einstellen.
Johannes S. schrieb:> Jens R. schrieb:>> In deinem Code finde ich die End/Anf.-Scahlter nicht.>> Ein Relais wird nicht benötigt, da der BL-Motor über den ESC gestartet>> wird.>> Das sollte ja auch ein Muster sein und noch nicht die komplette Lösung.> Es funktioniert soweit, habe ich auf dem Steckbrett getestet.> Endschalter sind weitere Eingänge die in checkInputs eingelesen werden,> Flankenerkennung wie bei den Tasten ist bei denen nicht nötig. Die> states enum muss erweitert werden und in processStateMachine() die> entsprechenden Aktionen.> Das Servo Objekt liefert das Timing das für den ESC gleich ist, also> kann man mit servo.write(speed) die Geschwindigkeit vom BL Motor> einstellen.
Bitte nicht falsch verstehen, natürlich freut es mich, dass du bisher
als einziger einen Code zusammengebastelt, äh programmiert hast.
Vielen Dank dafür. Ich bin schon am Lesen und versuche es zu verstehen.
Wolfgang schrieb:> Anders ausgedrückt: Mit dieser Vorgehensweise kann der Schrittmotor nie> mit voller Fahrt in Richtung Endschalter fahren und dort anhalten.
Ja, da lasse ich mir dann etwas Luft, wie gesagt ich muß hier nicht
hochgenau positionieren!
Ich habe mich auch bemüht ein paar Kommentare reinzuschreiben :)
Den Anfang habe ich ja mitverfolgt, da warst du noch bei einer Steuerung
aus Relais und Verzögerungsschaltern. Das man das nicht alles sofort
versteht wenn man mit µC anfängt ist ok, dafür bist du schon lernfähiger
als einige andere die hier im Forum aufschlagen. Also nicht entmutigen
lassen und weiter so.
Das Serial.print() ist zwar nicht so schön wie ein Debugger um etwas zu
verfolgen, hilft hier aber auch.
Johannes S. schrieb:> Ich habe mich auch bemüht ein paar Kommentare reinzuschreiben :)> Den Anfang habe ich ja mitverfolgt, da warst du noch bei einer Steuerung> aus Relais und Verzögerungsschaltern. Das man das nicht alles sofort> versteht wenn man mit µC anfängt ist ok, dafür bist du schon lernfähiger> als einige andere die hier im Forum aufschlagen. Also nicht entmutigen> lassen und weiter so.> Das Serial.print() ist zwar nicht so schön wie ein Debugger um etwas zu> verfolgen, hilft hier aber auch.
Nun ja, mein Projekt ist und bleibt eigentlich die Gehrungssäge.
Als ich mit der Idee anfing, habe ich mir zuerst die Säge konstruiert
und gebaut.
Also "Steuerung" war der BL-Motor für die Säge ein DC-Motor für den
Vortrieb und Endschalter, die per Relais die Richtung umschalten, also
nix mit großartiger Elektronik, gedacht.
Dann gab es schon Probleme mit der Logik und den Relais.
Das Ganze schien im Aufwand aus dem Ruder zu laufen.
Ich bekam den Tipp, das mit dem Arduino zu lösen, ich hatte bis dato
noch geglaubt, dass man solche Chips noch "brennen" muß, also nichts für
Hobby.
Auch preislich war ich überrascht.
Da ich schon mal etwas vom "Programmieren" gehört habe, dachte ich, das
kiegst du auch hin.
Zwangsläufig muß ich mich auch mit der "Arduino-Sprache"
auseinandersetzen.
Dr. Google hilft da ungemein, beantwortet aber deine Fragen nicht.
Deshalb bin ich hier gelandet.
Ich möchte jetzt nochmal neu anfangen mit dem Programmieren.
Aus meiner Arbeit kenn ich das Programmieren so:
Ich schreibe alle Dinge, die sich wiederholen in ein label nach dem
Programmende.
Aus dem Hauptprogramm heraus rufe ich die label bei Bedarf auf.
das geschieht mit "call label", dadurch gibt es einen Rücksprung hinter
die Aufrufstelle.
In der Arduino-Referenz finde ich nur den goto-Befehl, kein Rücksprung,
nicht außerhalb der Schleife.
Klar kann man das mit wiederum goto-Befehlen lösen, ist aber sehr
aufwendig.
Ich möchte das so, wie es schon mal einer mit der Steuererklärung auf
dem Bierdeckel machen wollte, schön klein und dadurch übersichtich (für
mich).
Seht ihr da eine Möglichkeit.
Nicht gleich wettern, mit dem switch-case kann ich mich noch nicht
anfreunden, da ich da mehrere Probleme sehe:
Wenn ich das richtig verstanden habe, bekommt die switch-Variable einen
Wert zugewiesen, dann ein Sprung zum Vergleichswert im case und den Code
dort ausführen. Anschließend geht`s nach break hinter dem switch-Befehl
weiter.
Jetzt kann ich jedem case eine Funktion zuweisen. Z.B. BL-Motor an,
BL-Motor aus, Schrittmotor vorwärts, Schrittmotor rückwärts, Starttaste
gedrückt, u.s.w.
Ich muß aber jedesmal vorher die switch-Variable entsprechend zuweisen.
Starttaste hat aber z.B. 2 Funktionen.
Auch wird immer nur eine Funktion oder mehrere hintereinander, aber in
der Reihenfolge ausgeführt.
Oder ich gebe jeder möglich Konstellation einen case und habe ein
Programm, das nicht auf den Chip passt.
Einen Rücksprung zu Variablendefinition gibt es auch nicht.
Jens R. schrieb:> In der Arduino-Referenz finde ich nur den goto-Befehl, kein Rücksprung,> nicht außerhalb der Schleife.
Weil eigentlich niemand goto braucht.
Wie wäre es denn, wenn du mal die einzelnen Funktionen, die dein
Programm erfüllen soll, als Blöcke definierst und dir auf ein Blatt
Papier zeichnest?!
Programmieren ist nicht, alles in einer bestimmten Programmiersprache
einzuhacken, sondern das Zerlegen eines Problems in Einzellösungen, die
dann in Algorithmen übersetzt werden, die dann wiederum in einer
beliebigen Programmiersprache dem Computer verständlich gemacht werden.
Na gut, vielen Dank für die gut gemeinten Ratschläge.
Aber ich baue das Ganze jetzt konventionell, Schritt für Schritt auf. So
komplex ist das Konstrukt nun wieder auch nicht.
Ich will am Anfang nicht gleich eine Rakete bauen, fange besser erstmal
mit einem Papierflugzeug an. Es bringt nichts, wenn ich mich mit Dingen
beschäftige, wo das Reindenken länger dauert, als einen ersten
funktionierenden Code zu schreiben. Später kann man immer noch, wenn
überhaupt nötig, optimieren, oder zusätzliche Funktionen einbauen.
Wie schon gesagt, mein eigentliches Projekt ist die Säge und nicht die
Programmierung eines µC für dessen Steuerung.
So hier mal der ungetestete Code für das Anfahren des Schrittmotors Bis
zum Endschalter.
Die delay`s sind gewollt, da ist auch die Maschine inaktiv.
An allen ausführenden Punkten habe ich eine Start/Stop-Tasterabfrage
eingefügt.
Auch wenn keiner goto braucht, habe ich es hier verwendet, um aus dem
laufenden Programm komplett rauszukommen und einen End-Code auszuführen.
Ein Neustart ist jeder Zeit möglich.
Was meint ihr dazu?
und wenn es lieber Spaghetti werden soll bin ich auch raus, mein
Programmrumpf hat doch schon fast alles gemacht. Weitere Schritte da
einfügen ist das enum und das switch case um ein weiteres Element
erweitern.
Jens R. schrieb:> Ich muß aber jedesmal vorher die switch-Variable entsprechend zuweisen.> Starttaste hat aber z.B. 2 Funktionen.
nein, der Zustand ist in meinem Muster global und bleibt solange gesetzt
bis er geändert wird.
Die Starttaste würde ich nicht doppelt belegen, besser eine Stoptaste
die in jedem Fall Stop macht und damit alle Bewegungen abbricht.
In dem Fall muss für Start auch erst eine definierte Ausgangslage
geschaffen werden, bei Start einfach losfahren ist auch nicht richtig.
Hatte ich auch schon geschrieben:
Johannes S. schrieb:> Für die Schrittkette überlegtst du dir was jeweils passieren soll:> 0 stateIdle : Ruhezustand, keine Änderungen> 1 stateMoveHome : Säge ausschalten. wenn nicht in Hompos, Schlitten in> Homeposition fahren auslösen. wenn in Homepos, state++
Wenn es gut werden soll startet man noch einen Überwachungstimer für die
Fahrfunktion: Fehler, wenn der Enschalter nicht nach einer max. Zeit
erreicht wurde.
Das ist mit dem µC nicht aufwändig, bietet dafür mehr Sicherheit als
eine dumme Relaissteuerung.
S
STK500-Besitzer schrieb:> Um Schleifen zu verlassen, verwendet man "break;" oder eine (weitere)> Abbruchbedingung.
Ja aber auch nur aus der laufenden Schleife, oder ist das nicht so?. Ich
möchte aber mit dem Aus-Schalter die Bearbeitung sofort abbrechen. Da
erschien mir der Sprung zu Aus-label am schnellsten.
STK500-Besitzer schrieb:> Dir ist nict zu helfen.
Ja leider!
Johannes S. schrieb:> Die Starttaste würde ich nicht doppelt belegen, besser eine Stoptaste> die in jedem Fall Stop macht und damit alle Bewegungen abbricht.
Schade, das Geld für eine 2.Taste wollte ich mir sparen. Ich muß doch
jetzt schon an die Kosten denken, wenn ich in Großserie gehe;-)
Nun gut, wenigstens das leuchtet mir ein. Ich werde es überdenken, aber
wenn`s hart auf hart kommt und ich habe 2 Tasten zur Auswahl,
hoffentlich drücke ich in der Hektik dann die richtige. Ein
Notausschalter in der Netzleitung ist auf jeden Fall geplant.
Johannes S. schrieb:> nein, der Zustand ist in meinem Muster global und bleibt solange gesetzt> bis er geändert wird.
Ich bin ganz ehrlich, dein Programm kann ich leider nicht nachvollziehen
und das liegt gewiss nicht an dir.
Johannes S. schrieb:> Wenn es gut werden soll startet man noch einen Überwachungstimer für die> Fahrfunktion: Fehler, wenn der Enschalter nicht nach einer max. Zeit> erreicht wurde.
Ja, Stück für Stück. Ich habe gemerkt, dass ich mit einem kompletten
Programmcode aus der Hüfte nicht weit komme.
für den Anfang sollte man zumindest die von Arduino mitgelieferten
Beispiele aus Control durchsehen und verstehen. Das sind die
Standardkostrukte für Abfragen, Schleifen und Switch drin.
Weil ich das Programm in ähnlicher Form auch gebrauchen kann habe ich
die Endschalter und den Ablauf auch noch eingebaut.
Als Anfänger neigt man natürlich dazu alles in ein meterlanges main bzw.
beim Arduino loop() zu Schreiben, aber sowas will keiner lesen. Deshalb
sofort angewöhnen mit Unterprogrammen zu strukturieren.
Der Code macht die Initialisierung der Ports im setup(), das sollte
leicht verständlich sein. Arduino blöd finde ich nur die Art wie PullUps
aktiviert werden, ist aber einfach so.
Im loop() wird dann einfach das Einlesen, Verarbeiten von Wartezeit und
Zustand ausgeführt. Immer wieder im Kreis rum ohne anzuhalten.
Wenn nix zu tun ist, wird immer in den idle Zustand gesprungen und es
passiert nichts. Wenn die Starttaste gedrückt wird, dann wird der
Zustand auf stateStart gesetzt. Von da an passieren die Dinge in der
Reihenfolge wie sie sollen. Aber eben so, das nicht auf etwas gewartet
wird, sondern wenn z.B. eine Position nicht erreicht ist dann wird das
processStateMachine wieder verlassen und beim nächsten mal wieder
geprüft.
Das kann man mit den Tasten und Endschaltern testen, im Serial Monitor
gibt s Ausgaben.
Johannes S. schrieb:> Als Anfänger neigt man natürlich dazu alles in ein meterlanges main bzw.> beim Arduino loop() zu Schreiben, aber sowas will keiner lesen.
Ja das habe ich gemacht und es funktioniert schon mal zufriedenstellen.
Johannes S. schrieb:> Deshalb sofort angewöhnen mit Unterprogrammen zu strukturieren.
Das ist es, was ich auf der Arbeit in Label, dort nach dem
Hauptprogramm, schreibe und diese aus dem Hauptprogramm bei Bedarf
aufrufe. Toll, dass das
hier auch funktioniert.
Johannes S. schrieb:> für den Anfang sollte man zumindest die von Arduino mitgelieferten> Beispiele aus Control durchsehen und verstehen. Das sind die> Standardkostrukte für Abfragen, Schleifen und Switch drin.
Wird gemacht!
Johannes S. schrieb:> Im loop() wird dann einfach das Einlesen, Verarbeiten von Wartezeit und> Zustand ausgeführt. Immer wieder im Kreis rum ohne anzuhalten.
So habe ich mir das auch gedacht.
Johannes S. schrieb:> im Serial Monitor> gibt s Ausgaben.
Da habe ich leider noch nicht verstanden, wie ich das nutzen kann.
Dein Code ist ziemlich umfangreich, aber ich glaube die Struktur zu
erkennen.
Sehr schön!
und Danke
Johannes S. schrieb:> Deshalb> sofort angewöhnen mit Unterprogrammen zu strukturieren.
Eben das versuch ich gerade.
Ich habe jetzt für alle Funktionen ein eigenes void geschrieben.
Also:
SM-Motor hochtouren
SM-Motor fahren
SM-Motor abtouren
BL-Motor hochtouren
BL-Motor fahren
BL-Motor abtouren
Über if-Abfragen der Endschalter kann ich jetzt jeden nötigen Schritt
ausführen.
Jetzt möchte ich über Interrupts den Starttaster als Ausschalter
benutzen, den ESC über Interrupt alle -zig ms aktualisieren.
Bevor ich damit anfange, ist bis hierher alles richtig?
Jens R. schrieb:> Ich habe jetzt für alle Funktionen ein eigenes void geschrieben.
void ist der Rückgabetyp, man schreibt kein void. Aber ich verstehe
schon was du meinst, du hast Unterprogramme geschrieben.
Jens R. schrieb:> Jetzt möchte ich über Interrupts den Starttaster als Ausschalter> benutzen, den ESC über Interrupt alle -zig ms aktualisieren.> Bevor ich damit anfange, ist bis hierher alles richtig?
Kann man über Ints machen, nur die Doppelbelegung Start/Stop würde ich
nicht so machen. Das muss jedenfalls gut entprellt werden und EMV fest
sein, nicht das die Säge losrennt wenn du Licht oder ein Gerät daneben
einschaltetst.
Die Servo Lib vom Arduino ist gar nicht schlecht, die arbeitet schon mit
Interrupt und der Wert muss nicht in jedem Zyklus neu gesetzt werden.
Und mit AccelStep gibt es eine gut Lib für SM, die läuft ebenfalls über
HW Timer. Man muss nur aufpassen das sich die HW Resourcen nicht in die
Quere kommen.
Johannes S. schrieb:> Kann man über Ints machen, nur die Doppelbelegung Start/Stop würde ich> nicht so machen. Das muss jedenfalls gut entprellt werden und EMV fest> sein, nicht das die Säge losrennt wenn du Licht oder ein Gerät daneben> einschaltetst.
Also genügt die delay-Zeit nach der Starttasterbetätigung wohl nicht zum
Entprellen. Aber kann dieser ominöse EMV nicht jederzeit vorkommen?
Nun ich werde wohl einen separaten Aus-Schalter einzufügen.
Not-Aus zur Netzttrennung muß aber trotzdem sein!
Dann habe ich schon 3 Schalter. 1-2oder 3 letzte Chance...
Johannes S. schrieb:> Die Servo Lib vom Arduino ist gar nicht schlecht, die arbeitet schon mit> Interrupt und der Wert muss nicht in jedem Zyklus neu gesetzt werden.> Und mit AccelStep gibt es eine gut Lib für SM, die läuft ebenfalls über> HW Timer.
Wenn das so einfach ist, bediene ich mich dann mal ganz frech.
Johannes S. schrieb:> Man muss nur aufpassen das sich die HW Resourcen nicht in die> Quere kommen.
Du meinst, die beiden Pin`s, die ich für interrupt zur Verfügung habe?
Jens R. schrieb:> Aber kann dieser ominöse EMV nicht jederzeit vorkommen?
ja, nur Interrupts reagieren da schnell empfindlich. Keine lange Leitung
dranmachen, und ext. RC Glied würde ich einsetzen. Bzw. sowieso lieber
meine Polling Lösung. Über Polling vs. Ints gibts hier ja gerade mehrere
Diskussionen...
Jens R. schrieb:> Du meinst, die beiden Pin`s, die ich für interrupt zur Verfügung habe?
nein, die HW Timer Resourcen. Wenn man nicht weiss wie die Libs intern
arbeiten und die belegten Resourcen nicht dokumentiert sind kann die
Kombination mehrerer Libs schief gehen. Versuch macht kluch, oder eben
in die Internas gucken.
Jens R. schrieb:> Deswegen hätte ich >=/<= im Vergleich genommen, um den richtigen Moment> nicht zu verpassen,
das ist aber auch noch "unzureichend" eventuell..
die laufen nämlich irgendwann über
in einigen Arduino IDEs gibt's n kleineren Schluckauf,
und der rollover passiert nach etwa neuneinhalb stunden
(was bei "langer" Laufzeit ein Problem sein könnte)
bei Neueren Versionen wurd das meine ich gefixxt und der Rollover ist
tatsächlich erst nach 49 Tagen zu erwarten;
was vermutlich eh nie eintrifft, weil man alle paar tage das Dingen mal
zur "wartung" abschaltet.
korrekt verhindern kann man den Fehler aber in etwa so:
1
// ins init:
2
const unsigned long STEP = 5*1000UL; //ich nahm einfach mal 5 sek...
3
static unsigned long lasttime; // brauchen wir zum Vergleich
4
5
// dann irgendwann:
6
if ( millis() - lasttime >= STEP )
7
{ //hier was auslösen und
8
lasttime += STEP; // das läuft zeitgleich über und der vergleich stimmt wieder
9
}
wie gesagt in etwa so ...
also sofern das Dingen wirklich im permanenten Dauerbetrieb ist,
wenn es nur n stündchen oder zwei am Stück läuft bist Du so weit vom
Überlauf weg, dass es keinen Unterschied macht :D
'sid
Johannes S. schrieb:> ja, nur Interrupts reagieren da schnell empfindlich. Keine lange Leitung> dranmachen, und ext. RC Glied würde ich einsetzen. Bzw. sowieso lieber> meine Polling Lösung. Über Polling vs. Ints gibts hier ja gerade mehrere> Diskussionen...
Also Hardwareentprellung!
Johannes S. schrieb:> nein, die HW Timer Resourcen. Wenn man nicht weiss wie die Libs intern> arbeiten und die belegten Resourcen nicht dokumentiert sind kann die> Kombination mehrerer Libs schief gehen. Versuch macht kluch, oder eben> in die Internas gucken.
Ich habe gelesen, dass 2 interrupts auf meinem Arduniono Nano laufen
müßten.
So würde ich den einen für den ESC und den anderen für den Stop
verwenden.
Damit könnte ich das von `sid` angesprochene Überlaufproblem auch
loswerden, indem ich wieder mit delay rummurkse und es mir einfach
mache.
Da der interrupt auch hinter dem Delay läuft wäre eine Entprellung mit
delay und Verwendung eines Tasters für Start/Aus sowieso sinnlos, also
kommt nun endgültig ein 2. Schalter rein.
zwei endschalter machen immer Sinn mMn;
im Grunde kann alles passieren und man will sich selbst das Leben ja
nicht schwerer machen als nötig.
Beispiel: optischer endschalter wird versehentlich zu früh ausgelöst
(Späne, Kabel, unvorsichtiger Humanoid, ne Fliege krabbelt drüber...)
der Automat hält seine Null Referenz nun fälschlich als 10cm vor dem
eigentlichen Nullpunkt an..
ohne zweiten Endschalter versucht er nun 10 über das hintere Ende
hinauszufahren (und das wird schnell gruselig)
Also n zweiter Endschalter (entweder getrennt oder aber in Reihe)
kann Mechanik retten wenn man mal nicht aufpasst.
Ausserdem muss man keine Schritte zählen oder verlorene Schritte
befürchten.
(schritte zählen macht aber zur Fehlersuche sinn.. 4000 schritte hin und
4200 zurück bedeutet man hat ein Problem um das man sich ggf kümmern
sollte ;))
Endschalter würde ich wie Notausschalter an einen interrupt klemmen
ehrlich gesagt.. beim polling kann man sich leichter 'verrechnen' mit
schleifenlaufzeiten und so... das kann ggf auch Probleme machen.
aber wir wollen diese Diskussion vielleicht nicht überall hintragen ;)
falls Du eine ISR benutzt,
dann denk unbedingt daran sie so kurz wie irgendmöglich zu halten
und niemals nie ein delay oder auch nur eine zweite millis-abfrage drin
zu haben, innerhalb der isr steht die zeit nämlich still!
'sid
Ich möchte nach Schalten des Aus-Taster per interrupt ein Unterprogramm
ausführen lassen. Nach dessen Abarbeitung springt das Programm an die
Stelle der Unterbrechung zurück. Nun soll dort die loop-Schleife zum
Start springen . Wie bewerkstelle ich so etwas?
Ich hatte mal wieder etwas Zeit und einen Code geschrieben. Es scheint
ja wenigstens noch einen zu geben, der meine Beiträge liest(siehe
Bewertungen), denn man kann ja erst bewerten, wenn man gelesen hat.
Hier meine neueste Murksversion:
1
#include"ESC.h"
2
#define SPEED_MIN 1000 // Set the Minimum Speed in microseconds
3
#define SPEED_MAX 2000 // Set the Minimum Speed in microseconds
4
#define DirPin 8 //Dir Schrittmotor
5
#define StepPin 7 //Step Schrittmotor
6
#define EndPin 6 //Endschalter
7
#define AnfPin 5 //Anfangsschalter
8
#define ESCPin 4 //Motordrehzahl
9
#define StartPin 3 //Starttaster
10
#define StopPin 2 //Stoptaster
11
ESCBL(ESCPin,SPEED_MIN,SPEED_MAX,1000);//ESC_Name (ESC PIN, Minimum Value, Maximum Value, Default Speed, Arm Value)
12
intESC;//Variable for the speed sent to the ESC
13
intStepMin=2000;//HIGH/LOW-Zeit min. Geschwindigkeit Schrittmotor
Pin 2 ist der Notaus taster?
dann ist es in der tat so einfach:
1
// in der setup()...
2
pinMode(StopPin, INPUT_PULLUP);
3
attachInterrupt(digitalPinToInterrupt(StopPin), AUS, LOW); //ich würde FALLING bevorzugen aber das ist gusto
digitalPinToInterrupt stellt sicher, dass der passende Interrupt zum Pin
gewählt ist, Du kannst manuell konfigurieren, aber das kann bei
boardwechsel in die Hose gehen... deswegen so in der "sichereren"
Version.
Ich bin kein fan der main loop um ehrlich zu sein..
ende anfang anfang ende anfang stop... uiuiui
ich bin schon kein fan von uppercase funktionsnamen, aber auch hier das
ist nur Geschmacksache,
Camelcase liest sich mir leichter
upper defines const und co,
lowercase variablen (und ggf unterstrich)
camelcase funktionen
Aber egal; geht ja hier nciht um n Schönheitspreis oder was MIR besser
gefällt ;)
Ich seh jetzt akut keinen logischen Fehler, wenngleich mir der
SpeedController nicht ausreichend definiert ist um eine Aussage dazu zu
treffen, geh ich davon aus Du hast die includes dazu und weisst sie zu
lesen und verstehen (ergo auch zu benutzen).
Das einzige was mir n bisserl sauer aufstösst
is die SM_FAHR
das ist ziemlicher kokolores...
(obschon das dennoch fast laufen sollte)
1
voidSM_Fahr()
2
{
3
/* was soll denn das hier zB */
4
StepTime=StepMin;
5
StepTime=StepTime+StepStepup;
6
7
/* diese einzelne Zeile täte dasselbe */
8
StepTime=StepMin+StepStepup;
9
10
/* while dann schritt dann if dann while kommt mir oll vor */
beim rest halte ich die Funktionen für teils unnötig, teils unsinnig;
aber soweit ich sehen kann jdf nicht falsch und darum geht's ja
letztendlich, richtig?
'sid
watt? warte.. is schon spät.. das ist doch käse.. speed max kleiner
speed min und dann delays und was?
Ich muss mal ne runde nickern und komm drauf zurück, aber das ist doch
schlimmer als zunächst angenommen fürhte ich
'sid
// was wenn die säge nicht läuft kann man dann gefahrlos zurückfahren?
89
ENDE();
90
ANFANG();
91
}
92
}
ist mir so immernoch nicht recht, aber wie gesagt ist spät und der Kopp
ist bisserl Brei ....
ich guck wacher nochmal drüber
(vllt find ich ja auch die esc.h auf meinem anderen Puter :D)
'sid
sid schrieb:> int StepdelayMin = 600; // HIGH/LOW-Zeit min.> Geschwindigkeit Schrittmotor> int StepdelayMax = 2000; // HIGH/LOW-Zeit max.> Geschwindigkeit Schrittmotor
ist ein bisschen verwirrend, aber kürzere Zeit =höhere Geschwindigkeit,
oder?
Ich glaube deiner Bezeichnung `delay` ist das eindeutiger.
sid schrieb:> void SM_Fahr(&Pin)> {> StepTime = StepdelayMax; // langsamste Geschwindigkeit (ww mit erster> erhöhung?)>> while (digitalRead(Pin) == HIGH) // schalter noch nicht erreicht> {> if (StopStatus == 1)> break; // immer anhalten wenn Notaus gedrückt!!> // fahren:> digitalWrite(StepPin, !digitalRead(StepPin)); //StepPin umschalten> delay(StepTime);> if (StepTime >= StepdelayMin) StepTime -= StepSpeedup;> //Schrittmotor beschleunigen falls noch nicht schnell genug> }
Sieht besser aus als bei mir.
sid schrieb:> void SM_Fahr(&Pin)
Wofür steht hier (&Pin)?
sid schrieb:> void BL_speed(bool increase)> {> int spd_diff = SPEED_MAX - SPEED_MIN;> for (int i = 0; i <= spd_diff; i++)> {> if (StopStatus == 1)> break;> if (increase)> BL.speed(SPEED_MIN+i); // increase> else> BL.speed(SPEED_MAX-i); // decrease> }> }
Da kann ich nicht ganz folgen, wofür steht BL.speed?
sid schrieb:> ANFANG();//wenn Anfangspos. nicht erreicht> // was wenn die säge nicht läuft kann man dann gefahrlos> zurückfahren?
Am Start soll die Säge in Ausgangspos. fahren, ohne laufenden Motor um
keinen zu verletzen. Das wäre nach einem Abbruch. Dass das ohne
laufenden Sägenmotor geht, muß ich vor Drücken der Starttaste absichern.
Allerdings, wahrscheinlich habe ich den Abbruch herbeigeführt, da etwas
nicht stimmt. So sollte vielleicht nach Anfahren der Startpos. durch
nochmaliges Start drücken der Arbeitsvorgang erst dann in Gang gesetzt
werden. Da muß ich mir nochmal Gedanken drüber machen.
Überhaupt verwirren mich die vielen Funktionen mehr, als dass sie mir
Struktur geben. Ist es vielleicht doch besser, die paar Funktionen
gleich ins loop zu schreiben?
Auf jeden Fall kann ich deiner Korrektur schon mal halbwegs folgen.
Danke dafür.
Die ESC.h habe ich im Arduino 1.8.12
-Bibliotheken verwalten
-Suche `brushless`
-`Brushless Servo`
gefunden. Sie setzt wohl auf die servo.h auf
Deine Benennungen sind echt verwirrend für mich,
ich hab mal so zusammengekürzt wie ich meine dass es am meisten Sinn
macht;
hab auch ein paar variablen entfernt (weil nutzlos) oder umbenannt(weil
zu verwirrend)
Ich denke Du solltest das einigermassen nachvollziehen können
wenn Du Zeile für zeile vergleichst
ich hab eine ESC.h die passt gefunden, schau mal ob's dieselbe ist,
falls nicht, bitte anhängen (geht drum ob's ein arm() und ein stop()
command gibt)
SM_Fahr(AnfPin);// Fahren zum Endschalter der Anfangsposition
91
92
BL_speed(false);// Säge langsam anhalten
93
BL.stop();// und wieder abschalten
94
}
95
}
Was passiert erklärt sich in den inline Kommentaren ;)
Jens R. schrieb:> Wofür steht hier (&Pin)?
&Pin ist der zu überwachende Pin des Endschalters für die
"Fahranweisung"
(da hab ich nur den typ vergessen)
Jens R. schrieb:> Da kann ich nicht ganz folgen, wofür steht BL.speed?
BL ist Dein speedcontroller.. BL.speed [BL(PUNKT)speed] setzt die
Geschwindigkeit des angeschlossenen Motors
BL_speed indes [BL(unterstrich)speed] ist mein Ersatz für Deine beiden
funktionen die das incrementell tun (BL_up und BL_down .. nur eben in
einer Funktion uzusammengefasst)
die boolean gibt an in welche Richtung das geschehen soll
(schneller/langsamer)
Jens R. schrieb:> Am Start soll die Säge in Ausgangspos. fahren, ohne laufenden Motor um> keinen zu verletzen. Das wäre nach einem Abbruch.
Wenn die Säge tatsächlich nicht laufen soll wenn das Dingen in die
Startposition fährt,
dann musst Du den Motor natürlich später anschalten in der loop
also
so
1
voidloop()
2
{
3
if(digitalRead(StartPin)==LOW)// wenn Starttaste gedrueckt geht`s los
4
{
5
StopFlag=false;// StopFlag löschen sonst könnte es klemmen
6
if((digitalRead(AnfPin)==HIGH)&&(digitalRead(EndPin)==HIGH))// wenn Anfangspos. nicht erreicht zurück auf Start
SM_Fahr(AnfPin);// Fahren zum Endschalter der Anfangsposition
20
21
BL_speed(false);// Säge langsam anhalten
22
BL.stop();// und wieder abschalten
23
}
24
}
hast Du keine arm() und stop() commands für dein benutztes ESC library;
dann musst Du das natürlich wieder entfernen, aber n motor sollte man
immer auch anhalten können ;)
'sid
UUUPS, Vergebung, man sollte Tipp und Flüchtigkeitsfehler auch entfernen
bevor man was anbappt.
Dafür hab ich Dir mal ne weiteres define verpasst welches klärt ob Du
mit oder ohne laufender Säge in die Startposition fährst ;)
wird ja alles wegoptimiert
so jetzt kompiliert die Arduino IDE das auch
sid schrieb:> Deine Benennungen sind echt verwirrend für mich
Ja, ich hab den Dingen einfach Namen gegeben. Ich kenne mich da nicht
mit dem Programmierknigge aus, aber wie ich sehe, hast du ja doch
verstanden, was ich will.
Die ESC.h ist die richtige, hab das verwechselt mit der Anleitung.
Ich werde mir dein Programm mal ausgiebig vornehmen. Ich stecke ja nich
in den Babyschuhen, das ist für mich schon höhere Programmierkunst, aber
in den letzten Wochen habe ich schon mal eine Menge dazugelernt. Schade,
dass ich den Code nicht alleine hingekriegt habe. Aber ich will ganz
erlich sein, es bleibt ein Abstecher ins Programmieren eines µC. Wer
weiß, ob ich mal wieder so ein Projekt anvisiere.
Noch eine Frage, du verwendest jetzt aber auch millis() ..., anstatt
delay, obwohl du davon eigentlich abgeraten hast, wenn ich mich recht
entsinne. Was ist denn nun so schlimm am `delay`.
Der Notaus läuft doch trotzdem im Hintergrund und wenn der µC gerade
auch nichts tun soll, warum lassen wir ihn dann nicht auch ein bisschen
ausruhen?
Danke für deine Mühe.
Ich werde die Sache im Versuchsaufbau testen.
Ach, da war noch was. Mir ist gerade eingefallen, dass es besser wäre,
wenn man zum Starten 2 Tasten betätigt, aber das kriege ich vielleich
selbst gebacken.
Jens R. schrieb:> Noch eine Frage, du verwendest jetzt aber auch millis() ..., anstatt> delay, obwohl du davon eigentlich abgeraten hast, wenn ich mich recht> entsinne. Was ist denn nun so schlimm am `delay`.> Der Notaus läuft doch trotzdem im Hintergrund und wenn der µC gerade> auch nichts tun soll, warum lassen wir ihn dann nicht auch ein bisschen> ausruhen?
Wollt nur, dass Du für beides eine Beispiel hast..
ich mag delay normalerweise nicht so gerne, da es eben allen
Programmablauf blockiert.
ein wait mit millis ist fast immer sinnvoller (nur eben nicht ohne
Tücken)
Da ich aber nicht glaube, dass Deine Säge 39Tage nonstop läuft seh ich
kein wirkliches Problem darin eine Zeitgesteuerte Warteschleife zu
nutzen statt eines delays,
vor allem weil sie so wie gesagt schneller auf den Notaus Befehl
reagiert
(effektiv wird bei Dir keine Zeile Programm weniger oder mehr
ausgeführt, es geht also wirklich um millisekunden an Unterschied)
Es ist nur eine formal Andere Lösung.
Wenn Du weiter dran arbeitest, dann könnte sich das ggf ändern;
und dann kann das eine oder andere besser sein
Ob Du so
1
voidSM_Fahr(constint&Pin)// no delay version; Pin ist der zu überwachende Endschalter
2
{
3
intStepInc=StepdelayMax;// langsamste Geschwindigkeit (ww mit erster erhöhung?)
4
unsignedlongStepTime=millis()+StepdelayMax;// Zeitpunkt für ersten Schritt festlegen
5
while(digitalRead(Pin)==HIGH)// Endschalter noch nicht erreicht
6
{
7
while(millis()<StepTime)// warten auf den Zeitpunkt 2 sekunden find ich aber arg viel!!
8
{
9
if(StopFlag)// auch beim Warten auf NotAus hören!
10
return;// falls: BEIDE Schleifen unterbrechen also raus hier
11
}
12
digitalWrite(StepPin,!digitalRead(StepPin));// einen Schritt tun
wartest ist im Moment noch völlig egal;
sei eben nur 'informiert', daß Beides Vor- und Nachteile haben kann ;)
wie Du siehst ist es auch egal WO in der schleife das delay
stattfindet;
wichtig ist nur, dass zwischen dem überwachen des Notaus-Flags und dem
eigentlichen Schritt (toggle des StepPins) möglichst keine Zeit vergeht.
(also den delay nicht dazwischen!)
Zwei taster geht auch;
am einfachsten dann als NO (normally open) und in Reihe an einem Pin
erst wenn beide tasten gedrückt sind wird die Verbindung von Pin und GND
hergestellt und der Pin ist LOW
bei nur einer Taste bleibt die andere getrennt und der internal Pullup
gewinnt ;)
'sid
So, ich habe den Versuchsaufbau endlich fertig und ausprobiert.
Natürlich funktionierte es nicht wie gewollt. Der Schrittmotor rast
gleich zu Beginn los ohne Tastendruck. Es fehlte der pinMode für den
Starttaster mit dem Pullup. Ich nehme an, der Pin war undefiniert LOW
also dauergedrückt. Jetzt funktioniert es von der Schalterei glaube ich
korrekt. Nur der BL-Motor springt nicht an. Der Fahrtregler, eigentlich
ist es ein Flugregler, piept wie wild und geht wohl in den
Programmiermodus. Hier muß er beim Einschalten denke ich wie beim Modell
in Nullstellung sein. Das klappt noch nicht.
Eine Frage:
sid schrieb:> if(RunningReturn) //> wird im define geklärt ob mit laufender Säge zurückgefahren wird oder> nicht> {> BL.arm();> // ESC 'bewaffnen'> BL_speed(true);> // und Säge anwerfen> }
Muß das nicht nach
sid schrieb:> if ((digitalRead(AnfPin) == HIGH) && (digitalRead(EndPin) == HIGH))//> wenn Anfangspos. nicht erreicht zurück auf Start
stehen?
Jens R. schrieb:> Muß das nicht nach>> sid schrieb:>> if ((digitalRead(AnfPin) == HIGH) && (digitalRead(EndPin) == HIGH))//>> wenn Anfangspos. nicht erreicht zurück auf Start>> stehen?
ÖHm nee wie gesagt nicht wenn Du mit laufender Säge in Nullstellung
willst,
wenn nicht dann schon, deswegen steht da ja auch:
sid schrieb:>
>HIGH))// wenn Anfangspos. nicht erreicht zurück auf Start
12
>{
13
>digitalWrite(DirPin,LOW);
14
>// DirPin 'rückwärts' setzen
15
>SM_Fahr(AnfPin);
16
>// Fahren zum Endschalter der Anfangsposition
17
>}
18
>if(!RunningReturn)
19
>// wird im define geklärt ob mit laufender Säge zurückgefahren wird oder
20
>nicht
21
>{
22
>BL.arm();
23
>// ESC 'bewaffnen'
24
>BL_speed(true);
25
>// und Säge anwerfen
26
>}...
was dein controller für einen Befehl wann wie erwartet weiss nur das
Datenblatt.
Aber ich schätze wenn Du es auf 1000,2000,500 gelassen hast sollte das
eigentlich passen.
wenn er dauerpiept, ist meistens der arm value zu hoch (haste den wieder
auf 1000 gesetzt?) und der controller vermutet ein throttle signal beim
einschalten und mault.
programmier modus halte ich für unwahrscheinlich.
'sid
sid schrieb:> wenn er dauerpiept, ist meistens der arm value zu hoch (haste den wieder> auf 1000 gesetzt?) und der controller vermutet ein throttle signal beim> einschalten und mault.
Ja da liegt wohl der Hase im Pfeffer. Das Programm habe ich 1 zu 1 von
dir übernommen, nur den pinMode für den StartPin eingebaut.
Ich habe mir nochmal das Beispiel ESC_Ramp draufgespielt, da
funktioniert es.
dort ist die Beschleunigung so geschrieben:
1
for(oESC=SPEED_MIN;oESC<=SPEED_MAX;oESC+=1){// goes from 1000 microseconds to 2000 microseconds
2
myESC.speed(oESC);// tell ESC to go to the oESC speed value
3
delay(10);// waits 10ms for the ESC to reach speed
4
}
Ich denke es fehlt:
delay(10); // waits 10ms for
the ESC to reach speed
sonst pfeifft er hoch auf Max Speed und der Controller denkt
Vollausschlag, also Programmiermodus.
Das ist nur meine Vermutung, aber ich weiß nicht, wie ich das in dein
sonst bisher gut funktionierendes Programm einflechten kann.
Jens R. schrieb:> Ich denke es fehlt:> delay(10); // waits 10ms for
Oh ich seh gerade, der delay ist ja doch drin.
Na jedenfalls funktioniert das ESC_Ramp mit meinem Controller.
Vielleicht hast du noch eine Ahnung, woran es liegt?
Oh! ich habe jetzt schon 2 zwei Anti-Fans.
Danke dafür!
Leider hat der Virus jetzt auch den momentan einzigen Helfer `sid`
erwischt.
Es tut mir leid, das war nicht meine Absicht, dich mit dem
Negativbewertungsvirus, kurz NBV-20 (ist das korrekt?) anzustecken. Ich
hätte beim Schreiben wohl besser Mundschutz, oder Schal oder was weiß
ich tragen sollen, wie es unsere Führung uns aufgetragen hat.
Ich habe mich nochmal mit sid`s Programm auseinandergesetzt und bin beim
"void BL_speed" hängen geblieben. so habe ich auch gleich noch etwas
über die Übergabe von Variablen in Unterprogramme gelernt.
sid schrieb:> for (unsigned int i = 0; i <= spd_diff; i += 10) // dahin wird gezählt> ich hab die Schritte mal erweitert
Da habe ich den Wert wie im Beispiel den "i+=10" wieder auf 1 gesetzt.
Jetzt läuft die Säge auch an.
Bei einem "Notaus" stopt der Motor sofort, aber es kommt auch gleich die
Überlast des PC-Netzteils. Das ist aber auch der Sinn eines Notaus:
schnellstmöglicher Stillstand!
Ich werde weiter experimentieren und melde mich wieder, wenn es Probleme
gibt.
Danke an alle!
Bis dahin, bleibt gesund und helft weiter solchen Idioten wie mir, ihre
sinnlosen Projekte umsetzen können.
Gruß Jens