Du mußt eine Loop() basteln, die ständig, ohne delay() durchläuft.
Dann würde ich zwei Zweige trennen (über if()), einen wenn keine Dosierung läuft und auf Tasterabfragen gewartet wird, und einen im dem die Dosierung läuft.
zum Beispiel so:
loop(){
- if (keine Dosierung aktiv)*
- wurde Taster gedrückt? ja: Zeit merken, alle Förderschnecken starten*
- else*
- Zeit für Schnecke1 abgelaufen? ja: Schnecke1 stoppen.*
- Zeit für Schnecke2 abgelaufen? ja: Schnecke2 stoppen.*
- Zeit für Schnecke3 abgelaufen? ja: Schnecke3 stoppen.*
- .....*
- ( kann man auch in for-Schleife machen)*
}
die Zeiten für die verschiedenen Zutaten würde ich in einem Array ablegen.
Das kann dann so aussehen: (ungetesteter Code, nur als Beispiel!)
// Array um die Zutaten pro Rezept festzulegen [Föderzeit in millisekunden]
const unsigned long Rezepte[4] = { 500, 4000, 1000, 1000};
// ein Array, um die Zuordung der Zutaten zu den Pins festzulegen
const int Schnecke[Anzahl_Zutaten] = {5,8,11,3};
boolean Dosierungaktiv = false;
int Zutat_Nr;
unsigned long Dosierstart;
void setup() {
// PinMode definitionen etc.
}
void loop() {
if (!Dosierungaktiv) { // Wenn keine Dosierung, dann Taster abfragen
if (analogRead(A0) < 512 ){ // Wenn Taster gedrückt wurde,
Dosierstart = millis(); // Zeit merken,
for (int i = 0; i < 4; i++) { // alle Dosierschnecken starten ,
digitalWrite(Schnecke[i], LOW);
}
Dosierungaktiv = true; // und Status setzen.
}
}
} else { // wenn Dosierung aktiv
for (int i = 0; i < 4; i++){ // für jede Zutat abfragen,
if ( millis() - Dosierstart > Rezepte[i]){ // ob die Dosierzeit abgelaufen ist
digitalWrite(Schnecke[i], HIGH); // dann entsprechendes Ventil abschalten
}
}
boolean AlleAus = false;
for (int i = 0; i < 4; i++){ // Wenn alle Ventile abgeschalten sind
AlleAus = AlleAus && (digitalRead(Schnecke[i]) == LOW);
}
if (AlleAus) Dosierungaktiv = false; // Status zurücksetzen
}
} // end loop()
Um das ganze flexibler zu machen, kann man die festen Grenzen der Arrays mit Konstanten ersetzen, auf die dann auch in den for Schleifen abgefragt wird.
Aus
Rezepte[4] = { 500, 4000, 1000, 1000};
...
for (int i = 0; i < 4; i++) {
wird
const int Anzahl_Zutaten = 4
Rezepte[Anzahl_Zutaten ] = { 500, 4000, 1000, 1000};
...
for (int i = 0; i < Anzahl_Zutaten ; i++) {
Der nächste Schritt ist dann, das alles auf mehrere Rezepte aufzubohren. Dafür wird das Rezepte-Array 2-dimensional und bei der Tasterabfrage muss geprüft werden, welcher gedrückt wurde.
Das könnte dann so aussehen: (ungetesteter Code, nur als Beispiel)
const int Anzahl_Rezepte = 3; // wieviele verschiedene Rezepte sind angelegt
const int Anzahl_Zutaten = 4; // wieviele verschiedene Zutaten sind angelegt
// Array um die Zutaten pro Rezept festzulegen [Föderzeit in millisekunden]
// Beispiel: 3 Rezepte, 4 Zutaten
const unsigned long Rezepte[Anzahl_Rezepte][Anzahl_Zutaten] = {{ 500, 4000, 1000, 1000},
{ 1000, 4500, 4000, 2000},
{ 3000, 1500, 2000, 3500} };
// ein Array, um die Zuordnung der Taster zu den Rezepte festzulegen
const int Taster[Anzahl_Rezepte] = {A0, A1, A2};
// ein Array, um die Zuordung der Zutaten zu den Pins festzulegen
const int Schnecke[Anzahl_Zutaten] = {5,8,11,3};
boolean Dosierungaktiv = false;
int Rezept_Nr;
int Zutat_Nr;
unsigned long Dosierstart;
void setup() {
// PinMode definitionen etc.
}
void loop() {
if (!Dosierungaktiv) { // Wenn keine Dosierung, dann Taster abfragen
for (int i = 0; i < Anzahl_Rezepte; i++){
if (analogRead(Taster[i]) < 512 ){ // Wenn Taster gedrückt wurden,
Rezept_Nr = i; // Ausgewähltes Rezept merken,
Dosierstart = millis(); // Zeit merken,
for (int i = 0; i < Anzahl_Zutaten; i++) { // Dosierschnecken starten ,
digitalWrite(Schnecke[i], LOW);
}
Dosierungaktiv = true; // und Status setzen.
}
}
} else { // Solange Dosierung aktiv
for (int i = 0; i < Anzahl_Zutaten; i++){ // für jede Zutat abfragen,
if ( millis() - Dosierstart > Rezepte[Rezept_Nr][i]){ // ob die Dosierzeit abgelaufen ist
digitalWrite(Schnecke[i], HIGH); // dann Ventil abschalten
}
}
boolean AlleAus = false;
for (int i = 0; i < Anzahl_Zutaten; i++){ // Wenn alle Ventile abgeschalten sind
AlleAus = AlleAus && (digitalRead(Schnecke[i]) == LOW);
}
if (AlleAus) Dosierungaktiv = false; // Status zurücksetzen
}
} // end loop()
Es gibt viele verschiedene Möglichkeiten sowas zu implementieren, es wurden schon welche genannt, es werden noch mehr genannt werden. Es gibt nicht DIE Richtige. Wichtig ist, dass du dir die Version suchst, die du verstehst und die dir liegt. Nimm die obige nur als Beispiel.
Im Attachment eine (ungetestete) Version als .ino mit seriellen Ausgaben.
parallel_Dosieren.ino (2.87 KB)