Taster doppelt verwenden

Hallo Zusammen

Ich baue ein Futterspender für Pferfutter. Es gibt 2 DC motoren welche mit einer H_Brigde gesteuert werden. Die DC Motoren treiben 2 förder schnecken an welche einmal Pellets und einemal müsli Fördern. Anschliesend fällt beides in eine röhre und kann ein stock tiefer aufgefangen werden.

Zu meinem Problem.

Ich möchte gerne einen Manuel modus. So das wen ich dort bin kann ich einen button betätigen solange laufen dan die motoren am besten pro motor ein button ich habe ja drei wie im Program zu erkennen. Ich glaube das ist keine große aufgabe ich bekomme ea leider trotzdem nicht hin. Das aktuelle program habe ich mit hilfe von videos und websiten gemacht.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(32,16,2);
int menu = 1;


//Deklarieren Fülstand Muesli
int trigger_muesli= A0; //Trigger-Pin des Ultraschallsensors an Pin7 des Arduino-Boards 
int echo_muesli=2; // Echo-Pim des Ultraschallsensors an Pin6 des Arduino-Boards 
long dauer_muesli=0; // Das Wort dauer ist jetzt eine Variable, unter der die Zeit 
//gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt. 
//Startwert ist hier 0.
long entfernung_muesli=0; // Das Wort „entfernung“ ist jetzt die variable, unter der 
//die berechnete Entfernung gespeichert wird. Info: Anstelle von „int“ steht 
//hier vor den beiden Variablen „long“. Das hat den Vorteil, dass eine größere 
//Zahl gespeichert werden kann. Nachteil: Die Variable benötigt mehr Platz im 
//Speicher.
int muesliprozent = 0;

//Deklarieren Fülstand Pellets
int trigger_pellets=6; //Trigger-Pin des Ultraschallsensors an Pin7 des Arduino-Boards 
int echo_pellets=13; // Echo-Pim des Ultraschallsensors an Pin6 des Arduino-Boards 
long dauer_pellets=0; // Das Wort dauer ist jetzt eine Variable, unter der die Zeit 
//gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt. 
//Startwert ist hier 0.
long entfernung_pellets=0; // Das Wort „entfernung“ ist jetzt die variable, unter der 
//die berechnete Entfernung gespeichert wird. Info: Anstelle von „int“ steht 
//hier vor den beiden Variablen „long“. Das hat den Vorteil, dass eine größere 
//Zahl gespeichert werden kann. Nachteil: Die Variable benötigt mehr Platz im 
//Speicher.
int pelletsprozent = 0;

//Deklarieren Button
int hoch = 12;
int runter = 11;
int select = 10;

// Deklarieren Motoren

// Motor Müsli connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor Pelets connections
int enB = 3;
int in3 = 5;
int in4 = 4;

void setup()
{
  
// Initialisieren Füllstand
Serial.begin (9600); //Serielle kommunikation starten, damit man sich später die Werte am serial monitor ansehen kann.
pinMode(trigger_muesli, OUTPUT); // Trigger-Pin ist ein Ausgang
pinMode(echo_muesli, INPUT); // Echo-Pin ist ein Eingang
pinMode(trigger_pellets, OUTPUT); // Trigger-Pin ist ein Ausgang
pinMode(echo_pellets, INPUT); // Echo-Pin ist ein Eingang
  
// Initialisieren LCD display
lcd.begin(16,2);
lcd.init();
lcd.backlight();
Serial.begin(9600);

// Initialisieren Button
  pinMode(hoch, INPUT_PULLUP);
  pinMode(runter, INPUT_PULLUP);
  pinMode(select, INPUT_PULLUP);
  updateMenu();
  
  //Initialisieren Motoren
  // Output deklaration
	pinMode(enA, OUTPUT);
	pinMode(enB, OUTPUT);
	pinMode(in1, OUTPUT);
	pinMode(in2, OUTPUT);
	pinMode(in3, OUTPUT);
	pinMode(in4, OUTPUT);
	
	// Alle Motoren aus
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
  
  // Geschwindigkeit motoren deklarieren
  	analogWrite(enA, 5);
	analogWrite(enB, 5);
  
  // Erstes mal Füllstands abfragen
  fuelstand();
}
void fuelstand()
{
// Füllstand Messen Müsli
digitalWrite(trigger_muesli, LOW); //Hier nimmt man die Spannung für kurze Zeit vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
delay(5); //Dauer: 5 Millisekunden
digitalWrite(trigger_muesli, HIGH); //Jetzt sendet man eine Ultraschallwelle los.
delay(10); //Dieser „Ton“ erklingt für 10 Millisekunden.
digitalWrite(trigger_muesli, LOW);//Dann wird der „Ton“ abgeschaltet.
dauer_muesli = pulseIn(echo_muesli, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
entfernung_muesli = (dauer_muesli/2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern. Man teilt zunächst die Zeit durch zwei (Weil man ja nur eine Strecke berechnen möchte und nicht die Strecke hin- und zurück). Den Wert multipliziert man mit der Schallgeschwindigkeit in der Einheit Zentimeter/Mikrosekunde und erhält dann den Wert in Zentimetern.
muesliprozent = (-0.325*entfernung_muesli)+101;
if (entfernung_muesli >= 500 || entfernung_muesli <= 0) //Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
{
Serial.println("Kein Messwert Muesli"); //dann soll der serial monitor ausgeben „Kein Messwert“, weil Messwerte in diesen Bereichen falsch oder ungenau sind.
}
else //  Ansonsten…
{
Serial.print(entfernung_muesli); //…soll der Wert der Entfernung an den serial monitor hier ausgegeben werden.
Serial.println(" cm Muesli"); // Hinter dem Wert der Entfernung soll auch am Serial Monitor die Einheit "cm" angegeben werden.
}
delay(1000); //Das delay von einer Sekunde sorgt in ca. jeder neuen Sekunde für einen neuen Messwert.

// Füllstand Pellets
  // Füllstand Messen Müsli
digitalWrite(trigger_pellets, LOW); //Hier nimmt man die Spannung für kurze Zeit vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
delay(5); //Dauer: 5 Millisekunden
digitalWrite(trigger_pellets, HIGH); //Jetzt sendet man eine Ultraschallwelle los.
delay(10); //Dieser „Ton“ erklingt für 10 Millisekunden.
digitalWrite(trigger_pellets, LOW);//Dann wird der „Ton“ abgeschaltet.
dauer_pellets = pulseIn(echo_pellets, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
entfernung_pellets = (dauer_pellets/2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern. Man teilt zunächst die Zeit durch zwei (Weil man ja nur eine Strecke berechnen möchte und nicht die Strecke hin- und zurück). Den Wert multipliziert man mit der Schallgeschwindigkeit in der Einheit Zentimeter/Mikrosekunde und erhält dann den Wert in Zentimetern.
pelletsprozent = (-0.325*entfernung_pellets)+101;
if (entfernung_pellets >= 500 || entfernung_pellets <= 0) //Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
{
Serial.println("Kein Messwert Pellets"); //dann soll der serial monitor ausgeben „Kein Messwert“, weil Messwerte in diesen Bereichen falsch oder ungenau sind.
}
else //  Ansonsten…
{
Serial.print(entfernung_pellets); //…soll der Wert der Entfernung an den serial monitor hier ausgegeben werden.
Serial.println(" cm Pellets"); // Hinter dem Wert der Entfernung soll auch am Serial Monitor die Einheit "cm" angegeben werden.
}
delay(1000); //Das delay von einer Sekunde sorgt in ca. jeder neuen Sekunde für einen neuen Messwert.

  
}
  
void loop()
{  
// Auswahl buttom Program
  if(!digitalRead(runter))
  {
    menu++;
    updateMenu();
    delay(20);
    while(!digitalRead(runter));
  }
  if(!digitalRead(hoch))
  {
    menu--;
    updateMenu();
    delay(20);
    while(!digitalRead(hoch));
  }
    if(!digitalRead(select))
  {
    ausfueren();
    delay(20);
    while(!digitalRead(select));
  }

  
}
// Programm Menü
void updateMenu()
{
switch (menu)
{
  case 0:
  menu = 1;
  break;
    
  case 1:
  lcd.clear();
  lcd.print(">Alonso Klein");
  lcd.setCursor(0,1);
  lcd.print(" Alonso Gross");
  break;
  
  case 2:
  lcd.clear();
  lcd.print(" Alonso Klein");
  lcd.setCursor(0,1);
  lcd.print(">Alonso Gross");
  break;
  
  case 3:
  lcd.clear();
  lcd.print(" Alonso Gross");
  lcd.setCursor(0,1);
  lcd.print(">Ellena Klein");
  break;
  
  case 4:
  lcd.clear();
  lcd.print(" Ellena Klein");
  lcd.setCursor(0,1);
  lcd.print(">Ellena Gross");
  break;
  
  case 5:
  lcd.clear();
  lcd.print(" Ellena Gross");
  lcd.setCursor(0,1);
  lcd.print(">Manuell");
  break;
  
   case 6:
  lcd.clear();
  lcd.print(" Manuell");
  lcd.setCursor(0,1);
  lcd.print(">Fuelstand");
  break;
  
  case 7:
  menu = 1;
  break;
}
}

// Programm zum ausführen
void ausfueren()
{
switch (menu)
{
  case 0:
  menu = 1;
  break;
    
  case 1:
  lcd.clear();
  lcd.print("Futter wird");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  delay(2000);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  lcd.clear();
  lcd.print("Futter wurde");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  delay(1000);
  updateMenu();
  fuelstand();
  break;
  
  case 2:
  lcd.clear();
  lcd.print("Futter wird");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  delay(2000);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  lcd.clear();
  lcd.print("Futter wurde");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  delay(1000);
  updateMenu();
  fuelstand();
  break;
  
  case 3:
  lcd.clear();
  lcd.print("Futter wird");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  delay(2000);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  lcd.clear();
  lcd.print("Futter wurde");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  delay(1000);
  updateMenu();
  fuelstand();
  break;
  
  
  case 4:
   lcd.clear();
  lcd.print("Futter wird");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  delay(2000);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  lcd.clear();
  lcd.print("Futter wurde");
  lcd.setCursor(0,1);
  lcd.print("ausgegeben");
  delay(1000);
  updateMenu();
  fuelstand();
  break;
  
  
  case 5:
  // Hier soll solange der "hoch" taster gerückt wird 
  //die motoren sich drehen und mit einem anderen taster 
// zurück zum menü
  if(!digitalRead(hoch))
  {
  lcd.clear();
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  lcd.clear();
  lcd.print("ausgabe");
  }
  if(digitalRead(runter))
  {
  lcd.clear();
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  }
  break;
  
  case 6:
  lcd.clear();
  lcd.print("Muesli ");
  lcd.print(muesliprozent);
  lcd.print(" %");
  lcd.setCursor(0,1);
  lcd.print("Pellets ");
  lcd.print(pelletsprozent);
  lcd.print(" %");
  delay(500);
  updateMenu();
  fuelstand();
  break;
  
  case 7:
  menu = 1;
  break;
}
}

Hi,
wenn ich Dich richtig verstehe, dann funktioniert der Sketch so wie er ist, Du möchtest zusätzlich einbauen dass Du den Ablauf durch Tastendruck übersteuern kannst ?

Mit den vielen delays wird das nix gescheites....

Ich möchte halt das in Case 5 mit den tastern ein Manuell Modus funktioniert.

Warum funktioniert das mit den delays nicht?

Delay heisst "mache nichts", - das wiederum heißt dass der MC, so lange er im "mache nichts" hängt, auch nicht darauf achtet ob jemand auf einen Taster drückt.
Im ungünstigsten Fall musst Du dann so lange auf den Taster drücken wie das längste delay ist bevor eine Reaktion erfolgt.

Einen Taster für 2 unterschiedliche Aktionen benutzen geht m.E. nur, wenn Du die Aktion die ausgeführt werden soll, davon abhängig machst wie lange der Taster gedrückt wird. Der Benutzer muss dann wissen wie lange er den Taster drücken muss um eine bestimmte Aktion zu erhalten.
Jetzt kommt das delay Problem: Du weißt, dass Du für Aktion A maximal 0,5 Sekunden auf den Taster drücken darfst, - der MC hängt aber gerade für 2 Sekunden im "mache nichts".
In dem Zusammenhang musst Dir auch darüber im Klaren sein, dass bei so langen delays der MC eigentlich fast immer im "mache nichts" hängt.

Ich habe den Code allerdings noch nicht so weitverstanden, dass ich beurteilen kann ob die langen delays nur in einem Programmteil stehen bei dem es gewünscht ist dass zu der Zeit nichts anderes passiert (auch kein manueller Eingriff). :slight_smile:

Ich würde eine Variable funktion einführen und damit festlegen welche Funktion man gerade will.
Da mich dieses 0, 1, 2 ... bei den Menüs schon verwirrt hat, habe ich dazu eine enumeration gemacht, die Festlegt, ob man in der Funktion AUTOMATIK oder MANUELL ist.

im Menü dann von AUTOMATIK auf MANUELL umschalten.
den MANUELL Modus beenden, z.B. wieder mit druck auf SELECT

in der Tastenauswertung musst du dann halt auch auf Funktion prüfen ob du im Menü springst (weil AUTOMATIK) oder der Taster was anderes machen soll (MANUELL).

Das weitere Menü ist eigentlich nur eine Anzeige dass der MANUELL Modus aktiv ist und eine Info wie man zurück kommt. Kann man sicher noch weiter ausbauen.

ca so:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(32, 16, 2);
int menu = 1;


//Deklarieren Fülstand Muesli
int trigger_muesli = A0; //Trigger-Pin des Ultraschallsensors an Pin7 des Arduino-Boards
int echo_muesli = 2; // Echo-Pim des Ultraschallsensors an Pin6 des Arduino-Boards
long dauer_muesli = 0; // Das Wort dauer ist jetzt eine Variable, unter der die Zeit
//gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt.
//Startwert ist hier 0.
long entfernung_muesli = 0; // Das Wort „entfernung“ ist jetzt die variable, unter der
//die berechnete Entfernung gespeichert wird. Info: Anstelle von „int“ steht
//hier vor den beiden Variablen „long“. Das hat den Vorteil, dass eine größere
//Zahl gespeichert werden kann. Nachteil: Die Variable benötigt mehr Platz im
//Speicher.
int muesliprozent = 0;

//Deklarieren Fülstand Pellets
int trigger_pellets = 6; //Trigger-Pin des Ultraschallsensors an Pin7 des Arduino-Boards
int echo_pellets = 13; // Echo-Pim des Ultraschallsensors an Pin6 des Arduino-Boards
long dauer_pellets = 0; // Das Wort dauer ist jetzt eine Variable, unter der die Zeit
//gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt.
//Startwert ist hier 0.
long entfernung_pellets = 0; // Das Wort „entfernung“ ist jetzt die variable, unter der
//die berechnete Entfernung gespeichert wird. Info: Anstelle von „int“ steht
//hier vor den beiden Variablen „long“. Das hat den Vorteil, dass eine größere
//Zahl gespeichert werden kann. Nachteil: Die Variable benötigt mehr Platz im
//Speicher.
int pelletsprozent = 0;

//Deklarieren Button
int hoch = 12;
int runter = 11;
int select = 10;

// Deklarieren Motoren

// Motor Müsli connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor Pelets connections
int enB = 3;
int in3 = 5;
int in4 = 4;

enum Funktion  {AUTO, MANUELL} funktion = AUTO;


void setup()
{

  // Initialisieren Füllstand
  Serial.begin (9600); //Serielle kommunikation starten, damit man sich später die Werte am serial monitor ansehen kann.
  pinMode(trigger_muesli, OUTPUT); // Trigger-Pin ist ein Ausgang
  pinMode(echo_muesli, INPUT); // Echo-Pin ist ein Eingang
  pinMode(trigger_pellets, OUTPUT); // Trigger-Pin ist ein Ausgang
  pinMode(echo_pellets, INPUT); // Echo-Pin ist ein Eingang

  // Initialisieren LCD display
  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  //Serial.begin(9600);

  // Initialisieren Button
  pinMode(hoch, INPUT_PULLUP);
  pinMode(runter, INPUT_PULLUP);
  pinMode(select, INPUT_PULLUP);
  updateMenu();

  //Initialisieren Motoren
  // Output deklaration
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  // Alle Motoren aus
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);

  // Geschwindigkeit motoren deklarieren
  analogWrite(enA, 5);
  analogWrite(enB, 5);

  // Erstes mal Füllstands abfragen
  fuelstand();
}
void fuelstand()
{
  // Füllstand Messen Müsli
  digitalWrite(trigger_muesli, LOW); //Hier nimmt man die Spannung für kurze Zeit vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
  delay(5); //Dauer: 5 Millisekunden
  digitalWrite(trigger_muesli, HIGH); //Jetzt sendet man eine Ultraschallwelle los.
  delay(10); //Dieser „Ton“ erklingt für 10 Millisekunden.
  digitalWrite(trigger_muesli, LOW);//Dann wird der „Ton“ abgeschaltet.
  dauer_muesli = pulseIn(echo_muesli, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
  entfernung_muesli = (dauer_muesli / 2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern. Man teilt zunächst die Zeit durch zwei (Weil man ja nur eine Strecke berechnen möchte und nicht die Strecke hin- und zurück). Den Wert multipliziert man mit der Schallgeschwindigkeit in der Einheit Zentimeter/Mikrosekunde und erhält dann den Wert in Zentimetern.
  muesliprozent = (-0.325 * entfernung_muesli) + 101;
  if (entfernung_muesli >= 500 || entfernung_muesli <= 0) //Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
  {
    Serial.println("Kein Messwert Muesli"); //dann soll der serial monitor ausgeben „Kein Messwert“, weil Messwerte in diesen Bereichen falsch oder ungenau sind.
  }
  else //  Ansonsten…
  {
    Serial.print(entfernung_muesli); //…soll der Wert der Entfernung an den serial monitor hier ausgegeben werden.
    Serial.println(" cm Muesli"); // Hinter dem Wert der Entfernung soll auch am Serial Monitor die Einheit "cm" angegeben werden.
  }
  delay(1000); //Das delay von einer Sekunde sorgt in ca. jeder neuen Sekunde für einen neuen Messwert.

  // Füllstand Pellets
  // Füllstand Messen Müsli
  digitalWrite(trigger_pellets, LOW); //Hier nimmt man die Spannung für kurze Zeit vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
  delay(5); //Dauer: 5 Millisekunden
  digitalWrite(trigger_pellets, HIGH); //Jetzt sendet man eine Ultraschallwelle los.
  delay(10); //Dieser „Ton“ erklingt für 10 Millisekunden.
  digitalWrite(trigger_pellets, LOW);//Dann wird der „Ton“ abgeschaltet.
  dauer_pellets = pulseIn(echo_pellets, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
  entfernung_pellets = (dauer_pellets / 2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern. Man teilt zunächst die Zeit durch zwei (Weil man ja nur eine Strecke berechnen möchte und nicht die Strecke hin- und zurück). Den Wert multipliziert man mit der Schallgeschwindigkeit in der Einheit Zentimeter/Mikrosekunde und erhält dann den Wert in Zentimetern.
  pelletsprozent = (-0.325 * entfernung_pellets) + 101;
  if (entfernung_pellets >= 500 || entfernung_pellets <= 0) //Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
  {
    Serial.println("Kein Messwert Pellets"); //dann soll der serial monitor ausgeben „Kein Messwert“, weil Messwerte in diesen Bereichen falsch oder ungenau sind.
  }
  else //  Ansonsten…
  {
    Serial.print(entfernung_pellets); //…soll der Wert der Entfernung an den serial monitor hier ausgegeben werden.
    Serial.println(" cm Pellets"); // Hinter dem Wert der Entfernung soll auch am Serial Monitor die Einheit "cm" angegeben werden.
  }
  delay(1000); //Das delay von einer Sekunde sorgt in ca. jeder neuen Sekunde für einen neuen Messwert.


}

void loop()
{
  // Auswahl buttom Program
  if (!digitalRead(runter))
  {
    Serial.println(F("runter"));
    if (funktion == AUTO)
    {
      menu++;
      updateMenu();
    }
    else
    {
      Serial.println(F("motoren manuell für runter betätigen"));
      //manuellRunter(); // existiert noch nicht
    }
    delay(20);
    while (!digitalRead(runter));
    if (funktion == MANUELL) manuellMotorStop();
  }
  if (!digitalRead(hoch))
  {
    Serial.println(F("hoch"));
    if (funktion == AUTO)
    {
      menu--;
      updateMenu();
    }
    else
    {
      Serial.println(F("motoren manuell für hoch betätigen"));
      manuellHoch();
    }
    delay(20);
    while (!digitalRead(hoch));
    if (funktion == MANUELL) manuellMotorStop();
  }
  if (!digitalRead(select))
  {
    Serial.println(F("select"));
    if (funktion == AUTO)
    {
      ausfueren();
    }
    else
    {
      Serial.println(F("ende manuell- zurück zu AUTO"));
      funktion = AUTO;
      menu = 6;
      updateMenu();
    }
    delay(20);
    while (!digitalRead(select));
  }
}



void manuellHoch()
{
  //lcd.clear();
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  //lcd.clear();
  //lcd.print("ausgabe");
}

void manuellMotorStop()
{
  //lcd.clear();
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}



// Programm Menü
void updateMenu()
{
  switch (menu)
  {
    case 0:
      menu = 1;
      break;

    case 1:
      lcd.clear();
      lcd.print(">Alonso Klein");
      lcd.setCursor(0, 1);
      lcd.print(" Alonso Gross");
      break;

    case 2:
      lcd.clear();
      lcd.print(" Alonso Klein");
      lcd.setCursor(0, 1);
      lcd.print(">Alonso Gross");
      break;

    case 3:
      lcd.clear();
      lcd.print(" Alonso Gross");
      lcd.setCursor(0, 1);
      lcd.print(">Ellena Klein");
      break;

    case 4:
      lcd.clear();
      lcd.print(" Ellena Klein");
      lcd.setCursor(0, 1);
      lcd.print(">Ellena Gross");
      break;

    case 5:
      lcd.clear();
      lcd.print(" Ellena Gross");
      lcd.setCursor(0, 1);
      lcd.print(">Manuell");
      break;

    case 6:
      lcd.clear();
      lcd.print(" Manuell");
      lcd.setCursor(0, 1);
      lcd.print(">Fuelstand");
      break;

    case 7:
      lcd.clear();
      lcd.print("*Manuel aktiv");
      lcd.setCursor(0, 1);
      lcd.print(" SELECT=retour");
      break;

    case 8:
      menu = 1;
      break;
  }
}

// Programm zum ausführen
void ausfueren()
{
  switch (menu)
  {
    case 0:
      menu = 1;
      break;

    case 1:
      lcd.clear();
      lcd.print("Futter wird");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);
      delay(2000);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
      lcd.clear();
      lcd.print("Futter wurde");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      delay(1000);
      updateMenu();
      fuelstand();
      break;

    case 2:
      lcd.clear();
      lcd.print("Futter wird");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);
      delay(2000);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
      lcd.clear();
      lcd.print("Futter wurde");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      delay(1000);
      updateMenu();
      fuelstand();
      break;

    case 3:
      lcd.clear();
      lcd.print("Futter wird");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);
      delay(2000);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
      lcd.clear();
      lcd.print("Futter wurde");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      delay(1000);
      updateMenu();
      fuelstand();
      break;


    case 4:
      lcd.clear();
      lcd.print("Futter wird");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);
      delay(2000);
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
      lcd.clear();
      lcd.print("Futter wurde");
      lcd.setCursor(0, 1);
      lcd.print("ausgegeben");
      delay(1000);
      updateMenu();
      fuelstand();
      break;


    case 5:

      // Hier soll solange der "hoch" taster gerückt wird
      //die motoren sich drehen und mit einem anderen taster
      // zurück zum menü
      funktion = MANUELL;
      menu = 7;
      updateMenu();
      break;

    case 6:
      lcd.clear();
      lcd.print("Muesli ");
      lcd.print(muesliprozent);
      lcd.print(" %");
      lcd.setCursor(0, 1);
      lcd.print("Pellets ");
      lcd.print(pelletsprozent);
      lcd.print(" %");
      delay(500);
      updateMenu();
      fuelstand();
      break;

    case 7:
      funktion = AUTO;
      break;

    case 8:
      menu = 1;
      break;
  }
}

Persönlich hat mir insbesondere das Menü zu viel Code Duplikate, und wie gesagt diese nichtsprechende Nummerierung der Menüs machts anderen sehr schwer zu folgen. Außerdem solltest du über das F-Makro nachlesen und anwenden.

zum Spielen:
https://wokwi.com/projects/351642537790800471

Die meisten delays sind nur da um das Programm nicht rucklig zu machen. Bis auf die delays welche den motor ein schaltet die werden noch so verändert das die richtige dosierung raus kommt.

Hört sich schlüssig an aber die an der umsetzung haperts noch. Zum Beißpiel verstehe ich nicht für was man den Auto modus braucht. Ich habe ja so gesehen 4 Auto modi.

du hast ja selber geschrieben:

Im MANUELL Modus kannst du deinen Motor manuell bedienen.
Irgend einen anderen Modus muss es ja geben, wenn du nicht in den MANUELL Modus bist.
Diesen anderen Modus habe ich halt AUTO - so wie Automatik genannt.
Im AUTO Modus werden die Futtermengen eben automatisch ausgegeben.

Schau dir mal den Sketch an. Die Tastenabfrage macht jetzt unterschiedliche Sachen je nach dem in welchem Modus du bist.

Ahh Geil es funktioniert :smiley:
und ich hab es jetzt verstanden.

Hätte es auch funktioniert wen ich mit digitalRead in zwei IF schleifen einmal auto und einmal manuel den wert ausgelesen hätte und jeweils einer anderen variable zugewiesen hätte?

Ich hätte nochmal ein problem welches aber nicht so leicht zu lösen ist.

Ich hätte gerne eine APP für ein smartphone die im heimnetzwerk eingebunden ist und auf der man ablesen kann wie voll die behälter sind und wie die temperatur im stall ist. Evtl. kommt noch eine fotosensor rein um nachts festzustellen ob das licht noch an ist. Aber nur vieleicht.

Die App möchte ich mit der Ionic machen da ich mal html und css gelernt hab und dieses gerne wieder auffrischen will.

Jetzt frag ich mich wie das funktioniert den ich hab ja den router dazwischen. Woher weis der das die informationen die vom arduino kommen zu der APP müssen?
Brauche ich da einen Web server? Ich hab leider keine ahnung von Netzwerktechnik. Vielen dank schonmal.

Achso hab mich zu dem Thema schon informiert aber nichts richtiges gefunden.

versteh ich nicht. Probier es aus.

Zu deinem anderen Frageblock, das ist umfangreicher. Damit du Daten wo abfragen kannst, brauchst du die Daten irgendwo. Das kann ein Webserver sein auf den du dann zugreifst. Aber der Arduino müsste dann auch mit einem Webclient die Daten dorthin schicken.

Du kannst auch auf dem Arduino einen (sehr kleinen) webserver laufen lassen, und direkt den Arduino abfragen. Dazu schreibst du deine HTML/CSS Seiten direkt in C++. Dann musst du aber von Außen auf den Arduino zugriff zulassen. Mittels Dyndns weist du wie deine Public IP aktuell lautet, mit der kannst du dich dann verbinden. Am Router wirst vermutlich ein Portforwarding benötigen. Eine App ist dann noch mal was eigenes... kommt halt noch was dazu falls du noch nicht genug hast.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.