mein Name ist Matthias und ich lese hier bereits eine lange Zeit mit.
Nun zu meinem ersten Problem bei dem ich anscheinend komplett ein Brett vor dem Kopf habe. Ich finde einfach keinen Einstig in die Lösung.
Daher habe ich auch hierzu leider noch keinen Code.
Hier zu meinem Problem:
Es geht darum vier Ausgänge für eine variable Zeit zu schalten dieses allerdings Zeitversetzt.
(Steuerung der Einspritzdüsen eines 4 Zylinder 4-Takt Motor).
Folgende Variablen:
Zykluszeit für alle 4 Zylinder 20 - 500ms
Einschaltdauer pro Zylinder 0-20ms
Zum Beispiel: Gesamt 100ms - Zylinder 10ms
Zeitpunkt und An Zeiten
0ms Zylinder 1 10ms an
25ms Zylinder 2 10ms an
50ms Zylinder 3 10ms an
75ms Zylinder 4 10ms an
100ms Zylinder 1 10ms an
125ms Zylinder 2 10ms an
150ms Zylinder 3 10ms an
175ms Zylinder 4 10ms an
... usw
Soweit noch kein Problem...
Aber bei z.B. Gesamt 40ms - Zylinder 20ms
0ms Zylinder 1 20ms an
10ms Zylinder 2 20ms an
20ms Zylinder 3 20ms an
30ms Zylinder 4 20ms an
40ms Zylinder 1 20ms an
50ms Zylinder 2 20ms an
60ms Zylinder 3 20ms an
70ms Zylinder 4 20ms an
... usw
Hier "überlappen" sich die Ausgänge und bei mir überlappt sich der Knoten im Gehirn...
Kann mir hier jemand auf die Sprünge helfen bitte?
Hallo Knoten, ich hätte Lesestoff für Deine Auflösung: Anleitung: Endlicher Automat mit millis()
Wenn Du das Beispiel um zwei LEDs erweiterst, hast Du schon mal die halbe Miete, dann fehlt nur noch die Synchronisation. Soll "0 ms" ab Reset des Arduino zählen oder von einem Schalter oder Zustand abhängig sein?
HotSystems:
Wo ist denn dein Sketch?
Schreibt er doch, Knoten statt Sketch!
Doc_Arduino:
Hallo,
Deine Mühen sind sehr löblich. Aber Du mußt dir bewußt sein, dass der Thread irgendwann nach hinten rutscht und verschwindet. Ich hab schon ähnliches durch. Du kannst den für dich fertig machen und bei Gelegenheit rausholen. Oder Du schreibst irgendwann ein Buch.
Du siehst meine Strategie gegen das Vergessen: Immer wieder dran erinnern
Dann lies dir die Basics in der IDE durch.
Da wird genau beschrieben, wie du Leds ein bzw. ausschaltest.
Du schaltest damit dann eben nur deine Ausgänge für die Steuerung der Zylinder. Was sich dahinter befindet hälst du ja geheim.
erstmal danke für die Antworten. Wie ich Ausgänge schalte, wie ich millis ohne Delay einsetzte das ist mir schon klar....
Was ich mit "Zylinder" schalte steht oben (Benzineinspritzventile mit 1Ohm Spulen).
Vielleicht zu meinem Hintergrund: Ich bin Elektroniker. Zwar lange aus dem Beruf raus aber die Hintergründe und auch wie ein Mikrocontroller funktioniert ist mir klar.
Agmue: Vielen Dank für den Link zum endlichen Automaten. Um bei dem Beispiel aus dem Link zu bleiben ist bei mir nur so das auch zwei Zustände gleichzeitig sein können.
Im Anhang habe ich mal zwei Zeitabläufe skizziert.
Der obere wäre einfach mit dem Automaten zu machen.
Aber bei Beispiel zwei überlappen sich die Zustände.
Ich werde morgen mal einen Sketch mit einem endlichen Automaten bauen und in hier zur Diskussion stellen. Vielleicht löst sich der Knoten ja beim tippen
Matze7779:
Aber bei Beispiel zwei überlappen sich die Zustände.
Bei meinem Link läuft die Ampel nach den vorgegebenen Zeiten (bei Dir Zylinder eins), dazu in anderem Takt blinkt die blaue LED (Zylinder zwei). Ampel und blaue LED überlappen sich wie unten in Deinem Zeitdiagramm.
Hier "überlappen" sich die Ausgänge und bei mir überlappt sich der Knoten im Gehirn...
Das zweite versteh ich nicht
Da du kein delay verwendest, braucht loop() deutlich weniger als eine ms, und hat viel Zeit entweder festzustellen dass nichts zu tun ist, oder das gleiche wie beim vorigen mal zu machen. ( Was bei digitalWrite in diesen Zeitdimensionen ziemlich wurscht ist. )
Ganz selten ergibt es sich, dass einer der vier Ausgänge anders gesetzt wird als beim vorigen Mal, aber das hat ja erstmal mit den anderen Zylindern nicht viel zu tun.
Ich mag die "endliche Automaten" - Denkweise eigentlich auch nicht, aber ich weiss, dass man alles so sehen kann und damit in den Griff kriegt.
Wenn es dir hilft, denk an 4 "Automaten" gleichzeitig mit je zwei Zuständen. Zusätzlich brauchst du wohl einen Gesamt-Zyklus, der die aktuelle Drehzahl und die Referenz-Zeit für jeden Zylinder ergibt.
Aber ich denke du hast das Problem gut verstanden welches ich meine.
Es ist gut wenn man darüber redet anstatt immer nur zu Grübeln
Mittlerweile denke ich das ich einen Automaten mit 4 Zustanden brauche. Und dazu 4 Automaten mit zwei Zustanden.
Hier nochmal der Ablauf aus dem zweiten Beispiel im Diagramm:
Zeitpunkt : Ausgänge
0ms Zylinder 1 EIN
5ms Zylinder 4 AUS
15ms Zylinder 2 EIN
20ms Zylinder 1 AUS
30ms Zylinder 3 EIN
35ms Zylinder 2 AUS
45ms Zylinder 4 EIN
50ms Zylinder 3 AUS
usw....
Also Gesamtzyluszeit 60ms (Zylinder 1-4). alle 15ms "startet" ein Zylinder kann aber 20ms laufen...
Dabei ist der Gesamtzyklus (hier 60ms) variablel bis 500ms. Und die Laufzeit für jeden Zylinder auch 0-20ms.
Ich grübel mal weiter....
Aber vielen Dank für eure Zeit! Ist nicht selbstverständlich...
Matze7779:
Mittlerweile denke ich das ich einen Automaten mit 4 Zustanden brauche. Und dazu 4 Automaten mit zwei Zustanden.
Das ist zu kompliziert gedacht. Ein endlicher Automat mit zwei Zuständen für den Taster und eine for-Schleife über alle vier Ausgänge genügt. Die Grafik aus #6 ist eine gute Hilfe
Ein mehr mathematischer Ansatz wäre, sich ein 60 ms Zeitfenster iMicros=(aktMicros - startMicros) % gesamtMicros zu erzeugen, um dann mittels Relationen eine HIGH- oder LOW-Bedingung zu beschreiben:
Hier mein Vorschlag für "überlappendes Blinken" von LEDs. Lässt sich sicher auch für dein Zylinderproblem anpassen.
Die Idee dahinter ist ein Bit-Pattern pro LED/Ausgang, welches zyklisch durchgetaktet wird. Damit lassen sich auch andere Muster darstellen, aber immer nur auf Basis der Grundtaktes (hier z. B. 20 ms) für ein Bit.
// overlapping LED pattern (bit = 1 means ON)
#define PATTERN1 0x0FFFF000
#define PATTERN2 0x00FFFF00
#define PATTERN3 0x000FFFF0
// LED pins
#define LED1 4
#define LED2 5
#define LED3 13
// Macro returns HIGH, if addressed bit is set, otherwise LOW.
#define TEST(idx, pattern) ((pattern & (1 << idx)) ? HIGH : LOW)
// bit position counter
byte index = 0;
void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
}
void loop()
{
digitalWrite(LED1, TEST(index, PATTERN1));
digitalWrite(LED2, TEST(index, PATTERN2));
digitalWrite(LED3, TEST(index, PATTERN3));
index = (index + 1) % 32;
delay(20);
}
Matze7779:
Habe leider kein Oszi da um das zu überprüfen.
Wenn Du den kompletten Sketch zeigst, lasse ich mein Programm malen.
Ist das Hobby oder wird das benotet? Ich frage nur, weil ich Dir Deine Note nicht durch zu viel Hilfe kaputtmachen will. Auch Lehrer und Ausbilder lesen im Forum
Der komplette Sketch ist noch nicht fertig da die Eingaben für die Zeiten (drehzahl und Einblaszeit) über den Drehencoder noch nicht komplett fertig sind.
Zum Hobby oder Aufgabe: Ich glaube mit 39 Jahren benotet mich nur meine Frau wie lange ich im Keller bin
Ein working example schicke ich dir die nächsten Tage per PN. Ist das ok?
Matze7779:
Der komplette Sketch ist noch nicht fertig da die Eingaben für die Zeiten (drehzahl und Einblaszeit) über den Drehencoder noch nicht komplett fertig sind.
Mit "komplett" meinte ich nur die Variablendefinitionen, setup und loop wie es jetzt ist.
Matze7779:
Zum Hobby oder Aufgabe: Ich glaube mit 39 Jahren benotet mich nur meine Frau wie lange ich im Keller bin
Woher kommt mir das nur bekannt vor :
Dann kann ich Dir ja "gefahrlos" meine Überlegungen zeigen: