Forum: Mikrocontroller und Digitale Elektronik Schrittkette


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Markus O. (markusjo)


Lesenswert?

Hallo zusammen,

danke nochmal für die zahlreich Beteiligung meines letztens Posts!

leider komme ich bei meinem letzten Menüpunkt nicht weiter, dabei habe 
ich diesen Step für den einfachsten gehalten :D Wie das immer so ist...

Folgendes soll passieren.

Wenn der Aktor1 (hier "Act1") nicht false ist, soll dieser schalten und 
erst wenn dieser wieder auf low ist, soll dieser auf false schalten und 
die Variable für Step 2 auf true gesetzt werden.
Zwischen Step 1 und Step zwei soll noch ein Timer ablaufen.
Der Timer soll starten wenn Aktor1 wieder auf low ist.

Mit dem aktuellem Code rührt sich nur der erste Aktor.
Ich hab schon mehrfach versucht den Code zu vereinfachen und dann 
Schritt für Schritt so umzuschreiben bis der gewünschte Zustand erreicht 
wird. Leider ohne Erfolg.

Vielleicht habt ihr ja noch ein, zwei Tricks um den Code zu vereinfachen 
und damit leichter umzusetzen.

Gruß
1
int potisave = 2000;
2
byte const Actuator_1 = 5;
3
byte const Actuator_2 = 6;
4
5
static boolean ActState1 = true;
6
static boolean ActState2 = false;
7
8
unsigned long counter;
9
10
void setup() {
11
  pinMode(Actuator_1, OUTPUT);
12
  pinMode(Actuator_2, OUTPUT);
13
  Serial.begin(9600);
14
}
15
16
void loop() {
17
  two();
18
}
19
20
void Act1() {
21
22
  static boolean Actuator_1_timerState;
23
  unsigned long currentMillisActuator_1;
24
  static unsigned long previousMillisActuator_1;
25
  const unsigned int cycleActuator_1 = 5000;
26
27
  currentMillisActuator_1 = millis();
28
  if (currentMillisActuator_1 - previousMillisActuator_1 >= cycleActuator_1)
29
  {
30
    previousMillisActuator_1 = currentMillisActuator_1;
31
    if (Actuator_1_timerState == LOW)Actuator_1_timerState = HIGH; else Actuator_1_timerState = LOW;
32
    digitalWrite(Actuator_1, Actuator_1_timerState);
33
    if (Actuator_1_timerState == LOW)
34
    {
35
      ActState1 = false;
36
      ActState2 = true;
37
    }
38
  }
39
40
}
41
42
void Act2() {
43
44
  static boolean Actuator_2_timerState;
45
  unsigned long currentMillisActuator_2;
46
  static unsigned long previousMillisActuator_2;
47
  const unsigned int cycleActuator_2 = 5000;
48
49
  currentMillisActuator_2 = millis();
50
  if (currentMillisActuator_2 - previousMillisActuator_2 >= cycleActuator_2)
51
  {
52
    previousMillisActuator_2 = currentMillisActuator_2;
53
    if (Actuator_2_timerState == LOW)Actuator_2_timerState = HIGH; else Actuator_2_timerState = LOW;
54
    digitalWrite(Actuator_2, Actuator_2_timerState);
55
    if (Actuator_2_timerState == LOW)
56
    {
57
      ActState1 = true;
58
      ActState2 = false;
59
    }
60
  }
61
}
62
void two() {
63
  unsigned long currendMillis;
64
  static unsigned long previousMillis;
65
  const int delayy = 5000;
66
67
  if (ActState1 == true)Act1();
68
  if (ActState2 == true)
69
  {
70
    currendMillis = millis();
71
    if (millis() - previousMillis >= delayy)
72
    {
73
      previousMillis = currendMillis;
74
      Act2;
75
      ActState1 = true;
76
    }
77
  }
78
}

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Markus O. schrieb:

> Wenn der Aktor1 (hier "Act1") nicht false ist,

Also true

> soll dieser schalten und
> erst wenn dieser wieder auf low ist,

also false

> soll dieser auf false schalten und
> die Variable für Step 2 auf true gesetzt werden.

Und was soll der Sinn dahinter sein? Klingt wirr.

> Zwischen Step 1 und Step zwei soll noch ein Timer ablaufen.
> Der Timer soll starten wenn Aktor1 wieder auf low ist.
>
> Mit dem aktuellem Code rührt sich nur der erste Aktor.
> Ich hab schon mehrfach versucht den Code zu vereinfachen und dann
> Schritt für Schritt so umzuschreiben bis der gewünschte Zustand erreicht

Meinst du nicht eher Step by step?

> Vielleicht habt ihr ja noch ein, zwei Tricks um den Code zu vereinfachen
> und damit leichter umzusetzen.

Dein Problem ist nicht in erster Line der Code, sondern das klare Denken 
und Formulieren von logischem Verhalten. Und die Ignoranz der 
Netiquette. Entweder hängt man Quelltext (vulgo code) als Anhang 
(neudeutsch Attatchment) an, oder markiert ihn wenigstens als Code, 
damit die Darstellung per syntax highlighting funktioniert.
1
int variable;
2
// ich bin ein Kommentar

Das macht man mit eckigen Klammern, ohne die Leerzeichen.

[ c ]
[ /c ]

Und das Thema Quelltextformatierung hast du immer noch nicht beachtet.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Markus O. schrieb:
> Ich hab schon mehrfach versucht den Code zu vereinfachen und dann
> Schritt für Schritt so umzuschreiben bis der gewünschte Zustand erreicht
> wird. Leider ohne Erfolg.

Der Hauptfehler ist, gleich alles direkt in Code hacken zu wollen.
Der bessere Weg ist, erstmal in Worten einen Programmablaufplan zu 
erstellen. Diesen kann man dann gedanklich auf Funktion überprüfen, d.h. 
die Schritte einzeln ablaufen lassen.
Wenn dann der PAP geprüft ist, ist das Code hacken nur noch ein 
Kinderspiel.

von Markus O. (markusjo)


Lesenswert?

Falk B. schrieb:
> Und was soll der Sinn dahinter sein? Klingt wirr.

Dass der Aktor 2 nicht anfängt eh der erste nicht wieder in 
Grundstellung ist.

> Dein Problem ist nicht in erster Line der Code, sondern das klare Denken
> und Formulieren von logischem Verhalten.

Formulierung ok, aber einen klaren Ablauf habe ich. Oder was stört dich?

Danke

von Falk B. (falk)


Lesenswert?

Peter D. schrieb:
> Der Hauptfehler ist, gleich alles direkt in Code hacken zu wollen.
> Der bessere Weg ist, erstmal in Worten einen Programmablaufplan zu
> erstellen. Diesen kann man dann gedanklich auf Funktion überprüfen, d.h.
> die Schritte einzeln ablaufen lassen.
> Wenn dann der PAP geprüft ist, ist das Code hacken nur noch ein
> Kinderspiel.

Wenn der OP schon das etwas SPS-lastige Wort "Schrittkette" verwendet, 
kann und sollte er auch gleich ein Zustandsdiagramm zeichnen. Siehe 
Statemachine.

von Falk B. (falk)


Lesenswert?

Markus O. schrieb:
> Falk B. schrieb:
>> Und was soll der Sinn dahinter sein? Klingt wirr.
>
> Dass der Aktor 2 nicht anfängt eh der erste nicht wieder in
> Grundstellung ist.

Das steht aber nicht in deinem Text. Bestenfalls in deinem Kopf.

>> Dein Problem ist nicht in erster Line der Code, sondern das klare Denken
>> und Formulieren von logischem Verhalten.
>
> Formulierung ok, aber einen klaren Ablauf habe ich. Oder was stört dich?

Es reicht nicht, keinen klaren Gedanken fassen zu können, man muss auch 
unfähig sein, ihn auszudrücken. Oder so ähnlich ;-)

von Falk B. (falk)


Lesenswert?

Bei solchen Sachen sollte man die Problembeschreibung von einer 
möglichen Umsetzung strikt trennen. Sprich, mit welchen Variablen das 
gemacht wird, ist bei der Problembeschreibung (Zustandsdiagramm!) egal!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus O. schrieb:
> Wenn der Aktor1 (hier "Act1") nicht false ist, soll dieser schalten und
> erst wenn dieser wieder auf low ist, soll dieser auf false schalten und
> die Variable für Step 2 auf true gesetzt werden.
> Zwischen Step 1 und Step zwei soll noch ein Timer ablaufen.
> Der Timer soll starten wenn Aktor1 wieder auf low ist.
>
> Mit dem aktuellem Code rührt sich nur der erste Aktor.
Der Code passt zu deiner Beschreibung.
Darin passiert auch nichts mit dem "zweiten Aktor".
Ich kann in der Beschreibung nicht erkennen, wer was auslöst und wer 
darauf wie regieren sollte. Und das, obwohl ich normalerweise gut im 
Rätseln bin.

> Wenn der Aktor1 (hier "Act1") nicht false ist, soll dieser schalten und
> erst wenn dieser wieder auf low ist, soll dieser auf false schalten
Du solltest an der textlichen Gestaltung dieses Satzes noch ein wenig 
arbeiten und zudem die verwendeten Begriffe und Pegel namens "schalten", 
"low" und "false" etwas klarifizieren.

Du könntest z.B. einfach mal ein Timing-Diagramm malen, wo man sieht, 
wann was low und high sein soll und wer dabei was auslöst und 
weiterschaltet. Es wird dir bei der Sortierung deiner Gedanken helfen.


BTW: denk mal drüber nach, die beiden 
unheimlichlangenundziemlichunleserlichen Variablennamen 
currentMillisActuator_1 und currentMillisActuator_2 einfach nur mit 
AktZeit (oder, wenns unbedingt Denglisch sein muss eben CurrTime) zu 
bezeichnen. Denn es gibt eigentliche keine "aktuelle Zeit für den 
Actuator 1" und keine spezielle "aktuelle Zeit für den Actuator 2", 
sondern nur die eine einzige "aktuelle Zeit", die im Augenblick gilt.

: Bearbeitet durch Moderator
von Markus O. (markusjo)


Lesenswert?

Lothar M. schrieb:
> Ich kann in der Beschreibung nicht erkennen, wer was auslöst und wer
> darauf wie regieren sollte. Und das, obwohl ich normalerweise gut im
> Rätseln bin.

Hallo Lothar M.

Der Status beider Aktoren wurde am Anfang global mit
"static boolean ActState1 = true;
und
static boolean ActState2 = false;
initialisiert.

Beide Aktoren werden über die untere Methode two aufgerufen. Die 
zeitliche Abfolge ist so gedacht, dass, da ActState1 eingangs mit true 
initialisiert wurde, in der two Methode nach dem jeweiligem Status 
gefragt und entsprechend ausgeführt wird.

Ansteuerung des ersten Aktors - klappt auch soweit.
if (ActState1 == true)Act1();
Nachdem dieser Aktor geschalten wurde und wieder LOW ist, werden in der 
Methode des Aktors1 die Variablen
ActState1 = false; //da jetzt einmal geschlaten
ActState2 = true; //nächster Schritt
zugewiesen.
Danach soll das Programm wieder in die two Methode. Da der ActState1 nun 
auf false steht, wird dieser nicht mehr durchgeführt, sondern Aktor 2.,
nachdem der Timer abgelaufen ist. Im gleichen Zuge wird auch ActState1 
wieder auf true gesetzt, damit der neue Durchlauf starten kann.
1
if (ActState1 == true)Act1();                  
2
  if (ActState2 == true)
3
  {
4
    currendMillis = millis();
5
    if (millis() - previousMillis >= delayy)
6
    {
7
      previousMillis = currendMillis;
8
      Act2;
9
      ActState1 = true;
10
    }
11
  }
12
}

von Falk B. (falk)


Lesenswert?

Markus O. schrieb:

> Der Status beider Aktoren wurde am Anfang global mit
> "static boolean ActState1 = true;
> und
> static boolean ActState2 = false;
> initialisiert.

Das brauchst du nicht nochmal zu schreiben, das sieht man.

> Beide Aktoren werden über die untere Methode two aufgerufen.

Das sind schnöde Funktionen. Methoden gibt es nur in C++ Klassen. Die 
hast du hier aber nicht.

> Die
> zeitliche Abfolge ist so gedacht, dass, da ActState1 eingangs mit true
> initialisiert wurde, in der two Methode nach dem jeweiligem Status
> gefragt und entsprechend ausgeführt wird.
>
> Ansteuerung des ersten Aktors - klappt auch soweit.
> if (ActState1 == true)Act1();
> Nachdem dieser Aktor geschalten wurde und wieder LOW ist, werden in der
> Methode des Aktors1 die Variablen
> ActState1 = false; //da jetzt einmal geschlaten
> ActState2 = true; //nächster Schritt
> zugewiesen.

> Danach soll das Programm wieder in die two Methode.

Nö, soll es nicht. Du bist schon viel zu tief in irgendwelchen 
UMSETZUNGEN drin, von denen du als blutiger Anfänger schon gar nicht 
viel verstehst.

Zeichne je ein Zustandsdiagramm für deine beiden Aktoren! Dann reden wir 
weiter.

von EAF (Gast)


Lesenswert?

Markus O. schrieb:
> Act2;
Statement has no Effect

von Markus O. (markusjo)


Lesenswert?

Oh, yes, of course. I forgot the "()" :D

Thanks !

But now the Actuator 2 works as long as the delayy :/

: Bearbeitet durch User
von realisator (Gast)


Lesenswert?

Ohne das jetzt im Detail verstanden zu haben, es geht doch nur darum 2 
"Aktoren" hin und her zu fahren, oder ???
Könnte wetten, das ganze ist mit maximal 6 Relais realisierbar. Wie kann 
man darum nur so ein verworrenes utopisches Geschwurbel veranstalten... 
:-)
TO ist hoffnungslos überqualifiziert...:-))

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Markus O. schrieb:
> But now the Actuator 2 works as long as the delayy
Und danach ist er kaputt und "arbeitet" fürderhin nicht mehr?
Eine Last ist "eingeschaltet" oder "ausgeschaltet".
Die meisten Aktoren "tun" auch was, wenn sie ausgeschaltet sind.

Wie gesagt: du MUSST ganz dringend eindeutige und definierte Begriffe 
für deine Beschreibungen wählen. Und begrifflich auch zwischen den 
eigentlichen Bauteilen und deinen Variablen klar unterscheiden.

von realisator (Gast)


Lesenswert?

Markus O. schrieb:
> Wenn der Aktor1 (hier "Act1") nicht false ist, soll dieser schalten und
> erst wenn dieser wieder auf low ist, soll dieser auf false schalten und
> die Variable für Step 2 auf true gesetzt werden.
> Zwischen Step 1 und Step zwei soll noch ein Timer ablaufen.
> Der Timer soll starten wenn Aktor1 wieder auf low ist.

Kann man das nicht auch alles in normaler Umgangssprache formulieren?

Markus O. schrieb:
> Wenn der Aktor1 (hier "Act1") nicht false ist,

Wenn der Motor1 nicht aus ist

> soll dieser schalten

häää???

> und erst wenn dieser wieder auf low ist,

wenn dieser wieder aus ist?

> soll dieser auf false schalten

soll dieser abschalten

> und die Variable für Step 2 auf true gesetzt werden.

Hilfsrelais 1 anziehen

> Zwischen Step 1 und Step zwei soll noch ein Timer ablaufen.

korrigiere: das anzugsverzögerte Hilfsrelais 1 anziehen

> Der Timer soll starten wenn Aktor1 wieder auf low ist.

Jetzt hör aber auf..!:-)

von Teo D. (teoderix)


Lesenswert?

Jo mei, wos wuist da macha!?
Es gibt halt Leute, die haben in ihrer Kindheit noch nicht mal mit Lego 
gespielt. Woher sollen Sie also wissen, was zu einer Kommunikation über 
Technisch/Physikalischem-Probleme nötig ist, geschweige den auch nur im 
Ansatz die geeignete Terminologie dazu zu kennen?!

Was Hänschen nich lernt.... Vieeel Spaß noch ;)=

von Markus O. (markusjo)


Lesenswert?

Also noch einmal einfach gesagt:

1. Aktor 1 läuft eine definierte Zeit.
2. Wenn Aktor 1 aus dann Timer start.
3. Wenn Timer fertig - > Aktor 2 läuft eine definierte Zeit.
4. Wenn Aktor 2 aus dann wider Schritt eins.

von EAF (Gast)


Lesenswert?

Codeduplikate sind böse, weil sie schwerer zu warten sind und den 
Speicherbedarf erhöhen.

Durchnummerierte Variablen sind böse, denn sie führen u.A. oft zu 
Codeduplikaten, wie man auch hier sieht.

Lokale statische Variablen sind böse, da die Funktion jedes mal ein 
anderes Verhalten zeigt, zeigen kann. Das macht sie schlecht wieder 
verwendbar und schwerer zu debuggen. Führt u.A. zu Codeduplikaten.

Verschiedenartige Daten, welche zusammengehören stopft man in eine 
Struktur, oder bei dir/C++ in Klassen.

Gleichartige Daten(auch Strukturen) stopft man in Arrays.

Merksatz:
Jeder ist seines Glückes Schmied.

von Falk B. (falk)


Lesenswert?

Markus O. schrieb:
> Also noch einmal einfach gesagt:
>
> 1. Aktor 1 läuft eine definierte Zeit.
> 2. Wenn Aktor 1 aus dann Timer start.
> 3. Wenn Timer fertig - > Aktor 2 läuft eine definierte Zeit.
> 4. Wenn Aktor 2 aus dann wider Schritt eins.

AHA!!!! Das ist schon ganz anders. Aber auch das kann und sollte man in 
einem Zeitdiagramm darstellen.

Wer bestimmt denn, wie lange die Aktoren aktiv sind? Eine konstante 
Zeit? Ein Sensorsignal (Endlagenschalter?). Wenn ersteres, dann ist es 
umso trivialer.

1. Aktor 1 x ms an
2. Pause   y ms
3. Aktor 2 z ms an
4. Goto 1

von Markus O. (markusjo)


Lesenswert?

Falk B. schrieb:

> Wer bestimmt denn, wie lange die Aktoren aktiv sind? Eine konstante
> Zeit? Ein Sensorsignal (Endlagenschalter?). Wenn ersteres, dann ist es
> umso trivialer.

Das ist alles über Timer(Millis) geregelt, wie m Code zu sehen.

Aktor 1 5000ms
delayy  5000ms
Aktor 2 5000ms

Falk B. schrieb:
> AHA!!!! Das ist schon ganz anders. Aber auch das kann und sollte man in
> einem Zeitdiagramm darstellen.

Weiß nicht so recht wie ich das umsetzten soll das Zeichnerisch 
darzustellen.

von EAF (Gast)


Lesenswert?

Markus O. schrieb:
> das Zeichnerisch
> darzustellen.

Man malt einen Pfeil von links nach rechts.
Einen Zeitpfeil.
Auf dem setzt man dann benannte Markierungen.

Bei zyklischen Prozessen, darf man auch einen Keis (mit Richtungspfeil) 
malen.

von Udo S. (urschmitt)


Lesenswert?

Markus O. schrieb:
> Weiß nicht so recht wie ich das umsetzten soll das Zeichnerisch
> darzustellen.

Wie jetzt:
Es gibt nur zwei Schaltausgänge Aktor 1 und Aktor 2.

Wer oder was bestimmt wann Aktor 1 das erste mal einschaltet?

Ab dann:
  Aktor 1 ist 5 Sekunden an
  5 Sekunden Pause
  Aktor 2 5 Sekunden an
  5 Sekunden Pause
dann wieder von vorne?

Oder soll Aktor 1 sofort einschalten wenn Aktor 2 wieder ausgeschaltet 
wird?

Es gibt keinerlei Eingänge, die diesen Betrieb modifizieren oder 
unterbrechen?

: Bearbeitet durch User
von Markus O. (markusjo)


Lesenswert?

Udo S. schrieb:
> Wer oder was bestimmt wann Aktor 1 das erste mal einschaltet?

Das hab ich doch schon erläutert. Oder was fehlt dir?

Udo S. schrieb:
> Wer oder was bestimmt wann Aktor 1 das erste mal einschaltet?

Wenn der Ardu das erste Mal eingeschaltet wird ist die globalen 
Variablen für den Aktor 1 mit true definiert. Also wird diese nach der 
Funktion two erstmalig ausgeführt.

Eine Unterbrechung ist jetzt noch nicht definiert.

von Egon D. (Gast)


Lesenswert?

EAF schrieb:

> Codeduplikate sind böse, [...]
>
> Durchnummerierte Variablen sind böse, [...]
>
> Lokale statische Variablen sind böse, [...]

Missionieren ist böse.


Wenn Du nicht Moses bist, halte Dich mit dem Verkünden
von Geboten zurück.

von EAF (Gast)


Lesenswert?

Egon D. schrieb:
> Wenn Du nicht Moses bist, halte Dich mit dem Verkünden
> von Geboten zurück.
Du hast doch einen Schlag an der Kanne!

Wie soll denn eine "Anfänger" je sauber programmieren lernen, wenn ihm 
nie gesagt wird, was falsch und richtig ist.
Und wo die Probleme stecken.

Was ihm dann daraus macht:
> Jeder ist seines Glückes Schmied.

Egon D. schrieb:
> Missionieren ist böse.
Tipp: Halte dich an deine eigene Ansagen, dann wirkst du evtl. etwas 
glaubwürdiger.

von Egon D. (Gast)


Lesenswert?

EAF schrieb:

> Wie soll denn eine "Anfänger" je sauber programmieren
> lernen, wenn ihm nie gesagt wird, was falsch und richtig
> ist.

Er lernt es auf jeden Fall nicht dadurch, dass man ihn
mit "Regeln" bombardiert, die zwar in vielen Fällen
richtig, aber auch in vielen Fällen falsch sind.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Markus O. schrieb:
> Falk B. schrieb:
>> AHA!!!! Das ist schon ganz anders. Aber auch das kann und sollte man in
>> einem Zeitdiagramm darstellen.
>
> Weiß nicht so recht wie ich das umsetzten soll das Zeichnerisch
> darzustellen.

Bis du wirklich so unbedarft oder einfach nur faul? Mensch Meier, jeder 
5. Klässler kann sowas!

von Egon D. (Gast)


Lesenswert?

Markus O. schrieb:

> Falk B. schrieb:
>> AHA!!!! Das ist schon ganz anders. Aber auch das kann
>> und sollte man in einem Zeitdiagramm darstellen.
>
> Weiß nicht so recht wie ich das umsetzten soll das
> Zeichnerisch darzustellen.

Man kann auch einen Automatengraphen zeichnen.

von Markus O. (markusjo)


Lesenswert?

Genau so!

Ab und zu etwas unbeholfen :/ Jetzt weiß ich aber auch was du meinst :)

von Egon D. (Gast)


Lesenswert?

Falk B. schrieb:

> Bis du wirklich so unbedarft oder einfach nur faul?
> Mensch Meier, jeder 5. Klässler kann sowas!

Ich stelle mir ab und zu vor, wie die Weltgeschichte
verlaufen wäre, wenn Du mein Lehrausbilder gewesen
wärest.
Schätzungsweise wärst Du auf dem Heidefriedhof und
ich im Knast... :)

von Falk B. (falk)


Lesenswert?

Egon D. schrieb:
> Ich stelle mir ab und zu vor, wie die Weltgeschichte
> verlaufen wäre, wenn Du mein Lehrausbilder gewesen
> wärest.
> Schätzungsweise wärst Du auf dem Heidefriedhof und
> ich im Knast... :)

Wenn das mal kein Irrtum ist ;-)

"Ich werde euch brechen, und dann gaaanz langsam wieder aufbauen! HABT 
IHR MADEN DAS VERSTANDEN?!!"

von Teo D. (teoderix)


Lesenswert?

Egon D. schrieb:
> Schätzungsweise wärst Du auf dem Heidefriedhof und
> ich im Knast... :)

Jaja, Andersdenkend Umbringen.... Hatten wir das nich schon mal, irgend 
wann, irgend wo?
In welcher Hohle/Hölle bist du den aufgewachsen?!

von Falk B. (falk)


Lesenswert?

Teo D. schrieb:
>> Schätzungsweise wärst Du auf dem Heidefriedhof und
>> ich im Knast... :)
>
> Jaja, Andersdenkend Umbringen.... Hatten wir das nich schon mal, irgend
> wann, irgend wo?
> In welcher Hohle/Hölle bist du den aufgewachsen?!

Das mit dem sinnerfassenden Lesen mußt du noch ein wenig üben . . .

von EAF (Gast)


Lesenswert?

Egon D. schrieb:
> Ich stelle mir ab und zu vor, wie die Weltgeschichte
> verlaufen wäre, wenn Du mein Lehrausbilder gewesen
> wärest.
> Schätzungsweise wärst Du auf dem Heidefriedhof und
> ich im Knast... :)

Mit deiner fachlichen Kompetenz scheinst du ja nicht glänzen zu können.
Eher schon mit mieser Anmache und Priestertum.



Egon D. schrieb:
> aber auch in vielen Fällen falsch sind.
Oder kannst du das begründen, ohne dich auf Faulheit oder Dummheit 
berufen zu müssen?
Bedenke: Ich habe jede der "Regeln" (mehr oder weniger) begründet.
Das erwarte ich jetzt auch von dir, diese Ansage zu begründen.

von Egon D. (Gast)


Lesenswert?

Falk B. schrieb:

> Egon D. schrieb:
>> Ich stelle mir ab und zu vor, wie die Weltgeschichte
>> verlaufen wäre, wenn Du mein Lehrausbilder gewesen
>> wärest.
>> Schätzungsweise wärst Du auf dem Heidefriedhof und
>> ich im Knast... :)
>
> Wenn das mal kein Irrtum ist ;-)

Ja, wer weiss... Wir werden es wahrscheinlich nie
erfahren... :)


> "Ich werde euch brechen, und dann gaaanz langsam wieder
> aufbauen! HABT IHR MADEN DAS VERSTANDEN?!!"

:)

von Stefan F. (Gast)


Lesenswert?

Markus O. schrieb:
> Wenn der Aktor1 (hier "Act1") nicht false ist, soll dieser schalten und
> erst wenn dieser wieder auf low ist, soll dieser auf false schalten und
> die Variable für Step 2 auf true gesetzt werden.

Dieser Satz ergibt für mich keinen Sinn. Ich vermute du hängst fest weil 
du auch keinen richtigen Plan vom Ablauf hast. Erstelle doch mal einen 
Plan - völlig lös gelöst von der Programmiersprache. Der bringt dich 
bestimmt weiter.

von Teo (Gast)


Lesenswert?

Falk B. schrieb:
> Teo D. schrieb:
>>> Schätzungsweise wärst Du auf dem Heidefriedhof und
>>> ich im Knast... :)
>>
>> Jaja, Andersdenkend Umbringen.... Hatten wir das nich schon mal, irgend
>> wann, irgend wo?
>> In welcher Hohle/Hölle bist du den aufgewachsen?!
>
> Das mit dem sinnerfassenden Lesen mußt du noch ein wenig üben . . .

Jo, is nicht mein Humor! Klär mich doch mal auf!

von Stefan F. (Gast)


Lesenswert?

Was du da machen willst lässt sich wunderbar in einem Zustandsdiagramm 
(oder Tabelle) darstellen und in einem Zustandsautomaten umsetzen. Im 
Grunde genommen brauchst du eine Aufstellung aller möglichen Zustände. 
Für jeden Zustand listest du auf, welche Ereignisse auftreten können und 
wie darauf reagiert werden soll.

Siehe http://stefanfrings.de/multithreading_arduino/index.html#planung 
für ein bildliches Beispiel

von Stefan F. (Gast)


Lesenswert?

Markus O. schrieb:
> Also noch einmal einfach gesagt...

Das ist wieder wirrer Text.

Warum läuft er eine definierte Zeit? Dieser Aktor hat also zwei Zustände 
(läuft bzw läuft nicht). Aber die Maschine hat noch andere Dinge, die 
den Gesamt-Zustand definieren. Löse dich vom Aktor und definiere alle 
Zustände der gesamten Maschine, dann für jeden Zustand die möglichen 
Ereignisse und dann für jedes Ereignis die Reaktion.

Du hast in deiner Aufzählung Zustände, Ereignisse und Reaktionen 
durcheinander gewürfelt. Ebenso sieht dein Code aus. Der Fehler steckt 
primär in deinem Plan.

Soweit ich das überblicke hast du insgesamt folgende Zustände:
1
Ausgangslage (Strom an)
2
Aktor 1 läuft
3
Pause nach Aktor 1
4
Aktor 2 läuft
5
Pause nach Aktor 2

Ist das so richtig? Ich würde aussagekräftigere Namen verwenden wie
1
Ausgangslage (Strom an)
2
Abpumpen
3
Pause nach Abpumpen
4
Auffüllen
5
Pause nach Auffüllen

Nur du kannst wissen, welche Namen sinnvoll sind.

Jetzt schreibe dahinter die Ereignisse und wie darauf reagiert werden 
soll. Entsprechend meiner Vorlage auf die ich eben verlinkt habe.

Deine Nummerierungen Act1, Act1, delayy, etc. sind grausam. In unserer 
Firma wurde jemand gekündigt, weil er das immer wieder gemacht hat. 
Benutze Aussagekräftige Namen! "Actuator" ist nicht aussagekräftig. 1, 2 
und y noch weniger.

von Udo S. (urschmitt)


Lesenswert?

Ich verstehe echt das Problem nicht.

Pseudocode:

Start:
Aktor 1 aus
Aktor 2 aus
do {
  Aktor 1 an
  wait 5 Sekunden
  Aktor 1 aus
  wait 5 Sekunden
  Aktor 2 an
  wait 5 Sekunden
  Aktor 2 aus
  wait 5 Sekunden
} while (keine Abbruchbedingung)

Wo ist jetzt dein Problem?`

von Markus O. (markusjo)


Lesenswert?

Udo S. schrieb:
> Wo ist jetzt dein Problem?

blockieren do/while nicht den Arduino?

von EAF (Gast)


Lesenswert?

Markus O. schrieb:
> blockieren do/while nicht den Arduino?

Wenn man es "richtig" macht, dann nein!
Wobei man "richtig" hier mit Protothreads, oder Rtos übersetzen könnte.

von Falk B. (falk)


Lesenswert?

Markus O. schrieb:
> Udo S. schrieb:
>> Wo ist jetzt dein Problem?
>
> blockieren do/while nicht den Arduino?

Nö, aber er ist dann nur mit diesem Ablauf beschäftigt. Was anderes 
"nebenbei" machen, geht dann nur sehr schwer bis gar nicht. Darum gibt 
es andere Programmiertechniken, siehe Multitasking. Das geht auch 
problemlos auf dem Arduino.

von Falk B. (falk)


Lesenswert?

EAF schrieb:
>> blockieren do/while nicht den Arduino?
>
> Wenn man es "richtig" macht, dann nein!
> Wobei man "richtig" hier mit Protothreads, oder Rtos übersetzen könnte.

Dann bist du aber ein grottenschlechter Übersetzer! Erst recht, wenn 
deine Zielgruppe solche Leute wie der OP sind. Für Anfänger macht man 
das DEUTLICH einfacher, nämlich mit einer Statemachine.

von EAF (Gast)


Lesenswert?

Falk B. schrieb:
> Dann bist du aber ein grottenschlechter Übersetzer! Erst recht, wenn
> deine Zielgruppe solche Leute wie der OP sind. Für Anfänger macht man
> das DEUTLICH einfacher, nämlich mit einer Statemachine.

Endliche Automaten und Nebenläufigkeit sind 2 völlig unterschiedliche 
Kapitel.
Sie kommen oft gemeinsam vor, sind aber doch nicht das gleiche.

von Udo S. (urschmitt)


Lesenswert?

Markus O. schrieb:
> blockieren do/while nicht den Arduino?

Ja was denn jetzt? Kommen jetzt wieder die Nebenbedingungen.
Dann hör auf mit deiner Salamitaktik und beschreibe möglichst präzise 
was du machen willst.

Ohne blockieren brauchst du wie schonb mehrfach gesagt ein 
Zustandsautomat.

Die Zustände sind
1: Aktor 1 an
2: Pause 1 (Alle Aktoren aus)
3: Aktor 2 an
4: Pause 2 (Alle Aktoren aus)

Die Übergänge sind bei dir trivial:
Immer nach 5 Sekunden gehts zum nächsten Zustand, bei Zustand 4 gehts zu 
1.
Je nach Übergang schaltest du einen Aktor ein oder aus.
Der Timer muss bei jedem Übergang zurückgesetzt werden

In der Hauptschleife (loop) kontrollierst du ob der Timer abgelaufen 
ist, und falls ja stösst du das Umschalten zum nächsten Zustand an.

: Bearbeitet durch User
von EAF (Gast)


Angehängte Dateien:

Lesenswert?

Hier ein Vorschlag, welcher Nebenläufigkeit und Endlicher Automat 
vereint.
In Anlehnung an dem Adam Dunkels seine ProtoThreads.
Garniert, mit ein paar Endlosschleifen und Wartezeiten.....

von EAF (Gast)


Lesenswert?

EAF schrieb:
> ein Vorschlag

Sorry, das taskPriority(10000); hat da nichts zu suchen, bitte 
wegdenken.

von LostInMusic (Gast)


Lesenswert?

>taskPriority(10000)

Würde ich sogar noch raufsetzen, damit das Programm möglichst gut läuft.

von Egon D. (Gast)


Lesenswert?

EAF schrieb:

> Egon D. schrieb:
>> aber auch in vielen Fällen falsch sind.
>
> Oder kannst du das begründen,

Selbstverständlich.


Ich bin mir nur gerade nicht sicher, ob ich angesichts
von ...

> Mit deiner fachlichen Kompetenz scheinst du ja nicht
> glänzen zu können. Eher schon mit mieser Anmache und
> Priestertum.

... Lust dazu habe.


> Bedenke: Ich habe jede der "Regeln" (mehr oder weniger)
> begründet.

Sicher, und die Begründungen sind ja auch nicht falsch --
nur sind sie das, was solche Begründunge immer sind:
Unvollständig.

Das Problem bei der Programmiererei ist ja nicht, dass
es einen Mangel an Regeln gäbe, und auch ein Mangel
an Begründungen für die Regeln ist nicht das Problem.

Das Problem ist m.E., dass die meisten Regeln allgemeingültig
formuliert werden, es aber nicht sind -- und es wird kein
Detektor mitgeliefert, der zu erkennen gestattet, wann die
Regel NICHT gilt.


> Das erwarte ich jetzt auch von dir, diese Ansage zu
> begründen.

Ich bin zwar nicht verpflichtet, über jedes Stöckchen zu
springen, aber sei's drum...

Ich beschränke mich auf die erste Aussage "Codedopplungen
sind böse". Im großen und ganzen ist die Aussage richtig.
Dennoch ist es m.E. nutzlos, dies als zu befolgendes
Gebot in den Raum zu stellen: Einem einigermaßen geübten
Programmierer widerstrebt es sowieso, genau denselben
Ablauf mehrfach hinschreiben zu müssen -- der braucht
dieses Gebot nicht.

Einem Anfänger dagegen hilft die Regel in keiner Weise --
er hatte ja einen Grund , den Code mehrfach hinzuschreiben.
Man muss ihm helfen, diesen Grund zu finden, zu verstehen
und zu beseitigen.


Für die Dopplungen gilt m.E. ungefähr folgendes:

"Exakte Dopplungen längerer Codepassagen sind i.d.R.
ein Anzeichen dafür, dass das Programm noch nicht
ausgereift ist. Sie sind in Programmen, die zur
praktischen Nutzung gedacht sind, zu vermeiden, weil
sie nutzlosen Speicherplatzverbrauch, schlechtere
Wartbarkeit und schlechtere Verständlichkeit zur Folge
haben.

Während der Entwicklungsphase können solche Dopplungen
leicht auftreten, weil man oft nicht von vornherein
kompletten Problemüberblick hat, sondern in die Struktur
der zu lösenden Aufgabe erst Schritt für Schritt
eindringt. In diesem Fall kann es sehr sinnvoll sein,
zunächst mal einen verstandenen Fall nach dem anderen
wegzuprogrammieren, ohne sich um Dopplungen zu kümmern.

Wenn man dann sicher ist, dass das Programm so, wie man
es heruntergeschieben hat, korrekt ist, überarbeitet
man den Quelltext nochmal ("Refactoring") und fasst
dabei mehrfach auftretenden Passagen zusammen. Man
verhindert auf diese Art, dass man fälschlich Fälle
zusammenfasst, die in Wahrheit subtile Unterschiede
aufweisen und nicht zusammengefasst werden dürfen."

von EAF (Gast)


Lesenswert?

Egon D. schrieb:
> Ich bin zwar nicht verpflichtet, über jedes Stöckchen zu
> springen, aber sei's drum...

Mache dir keine Sorgen...
Du bist nicht über das Stöckchen gesprungen.

Ganz im Gegenteil, du folgst meiner Argumentation in allen Belangen, 
bist sogar etwas ausführlicher.
Und mit keinem Wort hast du deine "falsch" Ansage
> aber auch in vielen Fällen falsch sind.
mit irgendeinem Beleg versehen!
Also eigentlich genau das, was ich von einem vernünftigen Menschen 
erwartete.

Tipp:
Wenn du weiter auf mich einhauen möchtest, kann ich dir sogar die 
Munition liefern.
Denn meine TaskMakros beinhalten statische Variablen.
Einfach als Kompromiss, da es so schlanker und einfacher ist, als dort 
einen Stack Wechsel Mechanismus einzubauen.
Eine Form der Faulheit. Meiner Faulheit.

von Egon D. (Gast)


Lesenswert?

EAF schrieb:

> Ganz im Gegenteil, du folgst meiner Argumentation
> in allen Belangen,

Nicht ganz.


> bist sogar etwas ausführlicher.

Nicht nur das.


Ich formuliere meinen Punkt noch deutlicher:

Codedopplungen sind keineswegs immer böse.

Es ist in manchen Fällen sehr empfehlenswert, sie
während der Entwicklungsphase zeitweise in Kauf zu
nehmen oder sogar als bewusstes Hilfsmittel für das
Problemverständnis einzusetzen.

Das ist bereichsweise das exakte Gegenteil von dem,
was Du behauptet hast.


Ist aber auch nicht weiter wichtig. Wer mich verstehen
will, versteht mich, und wer nicht will, lässt es eben
bleiben.

von W.S. (Gast)


Lesenswert?

EAF schrieb:
> Wie soll denn eine "Anfänger" je sauber programmieren lernen, wenn ihm
> nie gesagt wird, was falsch und richtig ist.
> Und wo die Probleme stecken.

Ähem... Sowas lernt man zur einen Hälfte durch gute Beispiele und zur 
anderen Hälfte durch eigenes logisches Denken und einer Prise 
Selbstdisziplin. Aber nicht durch einen Wald von Verbots-Schildern.

Ich hab das hier schon recht vielen Leuten geschrieben: zuerst die 
Funktionalität durchdenken und das Projekt planen und danach erst in die 
Tastatur hauen und Quellcode produzieren.

Allerdings bin ich aus den diffusen Äußerungen des TO auch nicht schlau 
geworden. Für mich sieht das wie ein einfaches Schrittschaltwerk aus, wo 
zu bestimmten Zeiten auf der langsam drehenden Walze irgendwelche 
Kontakte für eine bestimmte Zeit mal geschlossen werden sollen. 
Irgendwelche Funktionalität, die dann boolean Ergebnisse früherer 
Aktionen berücksichtigt (if (IOResult==false) then ZieheNotbremse() oder 
so), habe ich hier nicht sehen können.

Möglicherweise meint der TO jedoch etwas ganz anderes.

W.S.

von EAF (Gast)


Lesenswert?

Egon D. schrieb:
> Das ist bereichsweise das exakte Gegenteil von dem,
> was Du behauptet hast.

Pah....
Du hast behauptet dass meine Aussagen falsch sind, zumindest in 
vielen Fällen.
Siehe:
> aber auch in vielen Fällen falsch sind.
Das hast du nicht belegt, und wirst du auch nicht belegen können.

Im Gegenteil, du hast in deinen Begründungen zugestimmt und zwar, dass 
diese "Anstandsregeln" grundsätzlich richtig sind.




W.S. schrieb:
> Aber nicht durch einen Wald von Verbots-Schildern.
Fahren lernt man in der Fahrschule.
Und da fängt es mit den Regeln an.
Erst die wichtigste Theorie und dann ans Steuer.

Ansonsten kann ich nur sagen, dass sich der TO schon viel vorher bei mir 
in die Nesseln gesetzt hat, per Dokuleseverweigerung.
Sinngemäß: "Bücher interessieren mich nicht."

Und so leid es mir tut, wenn man nur aus Beispielen lernen will, also 
herzlich kenntnisfrei ist, dann sind die Arduino Beispiele im Netz nicht 
unbedingt hilfreich. Manche gar kontraproduktiv.

So hat er einmal klare Ansagen bekommen, sogar mit Lösungsansätzen.
Was er dann daraus macht, ist ganz alleine sein Problem.
Lass ihm doch das Problem.
Warum möchtest du den Boten töten?
Warum willst du den "Anfänger" weiter seltsamen Code produzieren lassen?

Zum Zweiten:
Wir sehen doch, dass er nicht von alleine logisch denkt und 
diszipliniert schreibt. Klar kann man im Straßenverkehr auch auf alle 
Anstandsregeln oder "Verbotsschilder" kacken. Bringt nur nix positives. 
Eher nur Frust und Ärger.

"Verbotsschilder", so ein Schwachsinn....
Ersetze alle "böse" in dem angemeckerten Text durch "unvorteilhaft" oder 
"suboptimal", wenn dir das lieber ist.


----------------

Grundsätzlich:
Aus Büchern will/kann er es nicht lernen.
Die Arduino Beispiele zeigen es auch eher selten.
Und ich soll/darf es ihm nicht sagen.

Was soll der Mist?
Wollt ihr Arduino User, oder andere Anfänger, absichtlich blöd 
sein/bleiben lassen, um dann hinterher drüber herziehen zu können?
Schwachfug!

Wenn es jetzt noch fachlich was zu dem Eingangsproblem zu sagen gibt, 
dann ok. Aber mit dem anderen Kram könnt ihr mir an der Pupe schmatzen. 
Das interessiert mich nicht(mehr).

von Markus O. (markusjo)


Lesenswert?

Es funktioniert.

Habt Dank!

Ich werde den Sketch noch ordentlicher gestalten und würde mich freuen 
wenn sich den jemand ansehehn und Verbesserungsvorschläge außern würde.

Dieser Teil hier im Post war der letzte Untermenüpunkt vom ersten 
Menüpunkt.


Schönen Abend noch!

Gruß

von EAF (Gast)


Lesenswert?

Markus O. schrieb:
> und würde mich freuen
> wenn sich den jemand ansehehn und Verbesserungsvorschläge außern würde.

Eins kann ich dazu schon sagen:
Eine Kristallkugel bis zur Version 5.47.11 ist dafür nicht wirklich 
ausreichend.
Welche muss ich dafür erwerben?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.