An/Aus Button für Arduino

Hallo Leute,

ich bin in der Programmierung noch relativ neu mit dem Arduino.
Ich suche jetzt schon eine ganze weile, aber ich finde keinen passenden Sketch.
Mein Problem ist folgendes.
Ich würde gerne den Arduino (auf einem Breadboard) mit einem Button an- und ausschalten.

Im Endeffekt möchte ich einen An- und Ausschaltknopf wie an einem Handy. Sprich kurz gedrückt (ca. 3 sek.) halten und der Arduino fährt hoch und durch läuft sein Programm. Wenn ich den Knopf nun nocheinmal kurz gedrückt halte (ca. 3 sek.) soll er sich wieder ausschalten.

Ich suche jetzt schon eine ganze Weile nach einem passenden Sketch aber bis jetzt habe ich noch nichts gefunden. Vielleicht nehme ich auch die falschen Suchbegriffe.

Wenn ich das alles richtig verstanden habe, dann sollte es doch mit einem Interrupt an PIN2 funktionieren und den Arduino mit dem SLEEP_MODE_PWR_DOWN Befehl schlafen legen auf unbestimmte Zeit. Nur bekomme ich ihn teilweise nicht wieder an.

Hat da jemand eine Idee?
Ich wäre da sehr dankbar für.

Beste Grüße

Zeile 42 des Kodes hat einen fetten Fehler, im Schaltplan sind 4 Dioden zuviel.

Kann aber auch eine Störung meiner Glaskugel sein...

:smiley:

Quarzkristall ist sehr empfindlich gegen Aufladung.

Okay, jetzt spaß beiseite. Was Whandall meint ist, dass du sehr gut geschrieben hast was du möchtest.
Und du auch bereits in irgendeiner Art und Weise damit angefangen.
Dann bitte zeig uns doch wie du den Arduino angesteuert hast und wie dein Sketch dazu aussieht.
Es ist nicht schlimm wenn dein Sketch gelinde gesagt lustig aussieht aber nur so können wir dir helfen.
Stefan

Hi StefanBoth, danke für die vernünftige Antwort. Ich kenne es so, dass man erst erklärt bevor man demjenigen den Code zeigt.

Nun zu meinem folgenden Problem. Ich kann die Taste 3,5 sek lang drücken, dann geht der Arduino auch in den PWR_DOWN Modus. Jedoch muss ich nur einmal kurz drücken, dann springt er wieder an.
Hier mein folgender Sketch:

#include <avr/sleep.h>
#include <avr/power.h>  //nachladen der benoetigen Bibliotheken
#include <math.h>

volatile int a = 0;
volatile int button = 2;
int led = 13;

int buttonstate = 0;
int debounceTime = 3500;
unsigned long buttonTime = 0;
int buttonpressed = 0;

void setup() {
   pinMode(13, OUTPUT);  //definieren von Pin 13 als OUTPUT
   attachInterrupt(0, interrupt, RISING);  //festlegen des Interrupts an Pin 2
  Serial.begin(9600);
}

void loop() {
  
  digitalWrite(led, HIGH);

buttonstate = digitalRead(button);

buttonpressed = 1;

if (buttonstate == LOW)
{
  buttonTime = 0;
  buttonpressed = 0;
}

if (buttonTime == 0)
{
  buttonTime = millis();
  buttonpressed = 0;
}

if((millis() - buttonTime >= debounceTime) && buttonpressed == 1)
  {
  //buttonpressed = 1;
    delay(80);
  //}
  //if(digitalRead(button) == HIGH && a == 1)
  //{
  Serial.println("Gehe schlafen");
  delay(10);
  for (int i = 0; i < 5; i++)
  {
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);  //3 Sekunden LED leuchten
    delay(200);
  }
  enterSleep();  //starten der enterSleep() Funktion
  buttonTime = 0;
  }

  Serial.println(millis() - buttonTime);
  Serial.println(buttonstate);

}

void interrupt() {
  //leere Interruptfunktion
}  

void enterSleep(){
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  //festlegen des Schlafmoduses
  sleep_enable();  //ermoeglichen der angegebenen Schlaffunktion
  sleep_mode();  //starten der Schlaffunktion
  //hier geht es nach dem Interrupt weiter

  sleep_disable();  //deaktivieren der Schlaffunktion
  power_all_enable();  //reaktivieren aller Chips/Funktionen
  Serial.println("Wieder wach");
 
}

Sowas würde ich mit Hardware lösen, welche dann vom Sketch bedient wird. Gibt irgendwo hier im Forum einen guten Threat dazu, mit Schaltplänen und Beispiel. Also echtes Aus- und Einschalten

Jedoch muss ich nur einmal kurz drücken, dann springt er wieder an.

Das ist normal und unabwendbar.
Der Interrupt feuert beim ersten Kontakt.

evt. kannst du mit einem RC Glied eine Verzögerung bauen.
Oder mit einem Hardware Monoflopp

Hi ElEspanol,

danke für die Antwort, das klingt auch gut, ich bin da für jede Idee offen. Wenn du weißt wo wonach ich suchen kann oder du einen Link hast, wäre ich dafür auch dankbar.
Sollte es aber mit dem oben und überarbeiteten Code gehen, wäre ich auch zufrieden.

combie:
Das ist normal und unabwendbar.
Der Interrupt feuert beim ersten Kontakt.

evt. kannst du mit einem RC Glied eine Verzögerung bauen.
Oder mit einem Hardware Monoflopp

Du kannst aber zuerst schauen ob die 3 sekunden um sind und erst dann den sketch ausführen. wenn der Taster weniger als 3 Sekunden gedrückt wird legst Du den Arduino wieder Schlafen.

Hi uwefed,

genau da hänge ich gerade. Ich finde nur meinen Fehler noch nicht.

Mh, jetzt habe ich noch einen Fehler.

Woran liegt das. Ich bin gerade wohl etwas blind.

#include <avr/sleep.h>
#include <avr/power.h>  //nachladen der benoetigen Bibliotheken
#include <math.h>

volatile int a = 0;
volatile int button = 2;
int led = 13;

int buttonstate = 0;
int debounceTime = 3500;
int debounceTimeOn = 2000;
unsigned long buttonTime = 0;
int buttonpressed = 0;

void setup() {
   pinMode(13, OUTPUT);  //definieren von Pin 13 als OUTPUT
   attachInterrupt(0, interrupt, RISING);  //festlegen des Interrupts an Pin 2
  Serial.begin(9600);
}

void loop() {
  
  digitalWrite(led, HIGH);

buttonstate = digitalRead(button);

buttonpressed = 1;

if (buttonstate == LOW)
{
  buttonTime = 0;
  buttonpressed = 0;
}

if (buttonTime == 0)
{
  buttonTime = millis();
  buttonpressed = 0;
}

if((millis() - buttonTime >= debounceTime) && buttonpressed == 1)
  {
  //buttonpressed = 1;
    delay(80);
  //}
  //if(digitalRead(button) == HIGH && a == 1)
  //{
  Serial.println("Gehe schlafen");
  delay(10);
  for (int i = 0; i < 5; i++)
  {
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);  //3 Sekunden LED leuchten
    delay(200);
  }
  enterSleep();  //starten der enterSleep() Funktion
  buttonTime = 0;
  }

  Serial.println(millis() - buttonTime);
  Serial.println(buttonstate);

}

void interrupt() {
  //leere Interruptfunktion
}  

void enterSleep(){
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  //festlegen des Schlafmoduses
  sleep_enable();  //ermoeglichen der angegebenen Schlaffunktion
  sleep_mode();  //starten der Schlaffunktion
  //hier geht es nach dem Interrupt weiter
  //sleep_disable();  //deaktivieren der Schlaffunktion
  //power_all_enable();  //reaktivieren aller Chips/Funktionen
  //Serial.println("Wieder wach");
  delay(50);
  check_Time();
 
}  


void check_Time()
{


buttonstate = digitalRead(button);

buttonpressed = 1;

if (buttonstate == LOW)
{
  buttonTime = 0;
  buttonpressed = 0;
}

if (buttonTime == 0)
{
  buttonTime = millis();
  buttonpressed = 0;
}

if((millis() - buttonTime <= debounceTimeOn) && buttonpressed == 1)
  {
  //buttonpressed = 1;
  //delay(80);
  //}
  //if(digitalRead(button) == HIGH && a == 1)
  //{

  sleep_disable();  //deaktivieren der Schlaffunktion
  power_all_enable();  //reaktivieren aller Chips/Funktionen
  for (int i = 0; i < 5; i++)
  {
    digitalWrite(led, LOW);
    delay(200);
    digitalWrite(led, HIGH);  //3 Sekunden LED leuchten
    delay(200);
  }
  Serial.println("Wieder wach");  
  buttonTime = 0;
  }
  
  else
  {
  enterSleep();  //starten der enterSleep() Funktion
  buttonTime = 0;
  }

  Serial.println(millis() - buttonTime);
  Serial.println(buttonstate);
}

Hier ist der von EIEspanol zitierte Beitrag.

Die Schaltung kannst du ja für deinen Bedarf etwas abändern.
Der Sketch ist einfach zu stricken und benötigt keinen Interrupt.
Ist eine echte Abschaltung, kein Schlafmodus.

Wenn Du das hardwareseitig lösen möchtest, dann einfach einen Schalter an die Versorgung. Wenn es ein Taster sein soll, kann ein Schaltfolgekonverter Abhilfe schaffen (sowas hier)

Danke für die Antworten.

Ich habe es nun gelöst, leider aber mit delay. Das möchte ich aber eher weniger. Hat jemand eine Idee wie das ohne gehen könnte?

void check_Time()
{

buttonstate = digitalRead(button);

if (buttonstate == HIGH)
{
  buttonpressed = 1;
  delay(3000);
  

if(digitalRead(button) == HIGH && buttonpressed == 1)
  {
  Serial.println("Wieder wach");
  delay(10);
  for (int i = 0; i < 5; i++)
  {
    digitalWrite(led, LOW);
    delay(200);
    digitalWrite(led, HIGH);  //3 Sekunden LED leuchten
    delay(200);
  }
  buttonTime = 0;
  sleep_disable();  //deaktivieren der Schlaffunktion
  power_all_enable();  //reaktivieren aller Chips/Funktionen
  buttonTime = 0;
  }
  else
  {
    buttonpressed = 0;
    delay(10);
    enterSleep();  //starten der enterSleep() Funktion
  
  }
}
  Serial.println(millis() - buttonTime);
  Serial.println(buttonstate);
}

Schlupp:
Ich habe es nun gelöst, leider aber mit delay. Das möchte ich aber eher weniger. Hat jemand eine Idee wie das ohne gehen könnte?

Ja:

Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:
Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay,

Blink Without Delay
Der Wachmann

Multitasking Macros
Intervall Macro

Nur mal so zum Verständnis, was du realisiert nennt sich “Stand by” und ist was anderes wie “Aus”.

Gruß

Schlupp:
Ich kann die Taste 3,5 sek lang drücken, dann geht der Arduino auch in den PWR_DOWN Modus. Jedoch muss ich nur einmal kurz drücken, dann springt er wieder an.

Das wäre für mich ehrlich gesagt schon der Idealzustand.
Wie Combi allerdings schon stichwortartig bemerkt hat, währen das die nächsten Schlagwörter die du dir anschauen solltest.
Ansonsten nimm uns bitte unseren schrägen Humor
nicht übel. So eigentlich steht hier irgendwo im Forum eine Art Checkliste für das Fragen stellen.
Leider auf englisch - und nach Überzeugung der Veteranen hier auch völlig Wurscht,selbst wenn es in Deutsch wäre. :wink:
Dem in der Konsequenz folgenden täglichen Murmeltiertag begegnet man dann halt mit einer Kristallkugel :smiley:

Da ist wirklich nichts Böses dabei - und ich habe hier alle als ziemliche Koryphäen erlebt.
Durchhalten :wink:

Stefan

und ich habe hier alle als ziemliche Koryphäen erlebt.

Vom mir weiß ich definitiv, dass ich kein kleiner Idiot bin!

combie:
Vom mir weiß ich definitiv, dass ich kein kleiner Idiot bin!

:o
ja nee? Wie kommste den ? Wer sagt das denn ?
:o

Hallo,

Leute, der TO möchte seinen Arduino nicht schlafen legen sondern ein und ausschalten. Genauer gesagt auf Tastendruck einschalten und ausschalten lassen Vom Begriff "power down mode" hat er sich fehl leiten lassen. Er benötigt demnach eine externe Beschaltung die auf Tastendruck die Spannung zuschaltet und per Softwareansteuerung diese externe Versorgung wieder unterbricht. So habe ich sein anliegen verstanden. Scherherz übrigens auch. Auf AVR-Transistortester – Mikrocontroller.net kann er sich die externe Beschaltung abschauen, dass war er dafür benötigt und den benötigten Pin programmieren. Das wäre richtiges ein- und ausschalten.

Der Transistortester geht sofort an.
Da muss man nicht erst mal 3,5 Sekunden drücken.

Sofort an gehen, das soll nämlich nicht.