Interrupt: wie den Sleep Power Down mit mehreren tastern beenden

Hallo zusammen,
ich habe ein interessantes Problem.
Ich verwende den "Uno" als Modem zum Programmieren eines ATMega 328PU der im 8Mhz Onboard Crystal Modus läuft.

Auf diesem 328 habe ich eine Fernbedienung programmiert. Nun sollen die Batterien etwas länger halten und ich möchte gern in den Power Down gehen. (Idle bringt mir fast nichts)

Soweit so gut.. aufwachen tut er sobals sich was an PIN 2 oder PIN3 tut (das sind die Interruptfähigen Eingänge beim UNO)

Jetzt hat meine Fernbedienung aber mehr als 2 Knöpfe.. ich möchte das mein 328 auch aufwacht wenn man einen anderen Knopf drückt als am Interrupt angeschlossen.

Kann ich in der Einschlaffunktion die anderen Eingänge irgendwie mit dem Interrrupt verbinden (attach klappt irgendwie nicht oder ich schreibe es falsch) und beim aufwachen wieder detachen?

Oder muss ich das Hardwaretechnisch lösen (Taster mit 2 unabhängigen Schaltkontakten- einer gibt LOW auf den Interrupt, der andere gibt ein Signal an den Digital Port)

Von jedem Pin über eine Diode zu den interrupt Pins wäre eine Hardware Möglichkeit.

Der Pinchange Interrupt tuts auf jedem Pin/Port.
Außer A6 A7

Eine Diode pro Taster könnte gehen;
Alternativ all 1/10 Sekunde durch Timerinterrupt aufwachen und Tastendrücke kontrollieren ginge auch.

Wie hast Du die Tasten angeschlossen? Schaltplan

Grüße Uwe

uwefed:
Eine Diode pro Taster könnte gehen;
Alternativ all 1/10 Sekunde durch Timerinterrupt aufwachen und Tastendrücke kontrollieren ginge auch.

Wie hast Du die Tasten angeschlossen? Schaltplan

Grüße Uwe

Interessante Lösung. Wenn er dann z.b. nur einen loop macht, reicht das? und man braucht nur den Betriebsstrom für den einen loop ?

ElEspanol:
Interessante Lösung. Wenn er dann z.b. nur einen loop macht, reicht das? und man braucht nur den Betriebsstrom für den einen loop ?

Das verstehe ich jetzt nicht.
Grüße Uwe

Ich meinte folgendes:

  1. Schlafen schicken
  2. aufwachen, loop beginnen, in dem geschaut wird, ob eine Taste gedrückt wurde. Wenn nicht, schlafen schicken (das dürfte ja nur wenige Mikrosekunden gedauert haben). Wenn ja, agieren, danach schlafen schicken. Also max. nur einen loop

Wenn er nun alle Zehntel Sekunde für eben diese wenige Microsekunden aufwacht, benötigt er doch nur in dieser kurzen Zeit den normalen Betriebsstrom und die Batterien halten somit viel länger. Je kürzer die Tastenabfrage, desto länger halten die Batterien?

Hallo,

wenn die Fernbedienung nur bei gedrückter Taste sendet, könnte man über die Tasten auch die Betriebsspannung einschalten. Dann braucht in den Pausen die Schaltung absolut keinen Strom.

BetaCarotin:
Jetzt hat meine Fernbedienung aber mehr als 2 Knöpfe… ich möchte das mein 328 auch aufwacht wenn man einen anderen Knopf drückt als am Interrupt angeschlossen.

Dann bräuchte er ALLE Tasten mit 2x ein.

Aber den Ansatz hatten wir vor kurzem bei einem Türkontakt, da wäre es perfekt.

Heul....
Warum mag nur keiner meine Pin Change Interrupts...?
:frowning:

Pin Change Interrupt.. das gefällt mir gut! Damit werde ich es jetzt versuchen..Danke!

Die andere Lösung mit 2x Ein und die Betriebsspannung damit einschalten..ist auch wirklich gut, ich werde mal probieren wie schnell der 328 "bootet"-also ob das ganze dann noch funzt.

Mit Dioden klappts nicht..war auch mein erster Gedanke..

Hardware: Die Taster liegen auf Masse und schalten diese auf die digital Ports. Diese sind zwar als PullUp definiert..leider brauche ich aber trotzdem noch einen externen Pullup Widerstand da die Fernbedienung sonst einfach anfängt zu senden und die Taster "hängenbleiben" ..vielleicht habe ich aber auch noch nicht verstanden wie ich diesen internen Pullup zuschalte..

pinMode (tmenu, INPUT_PULLUP);

so, oder?

Oder muss ich dann nochmal einen

digitalWrite (tmenu,HIGH):

machen?

Sooo jetzt erstmal auf zum pin change interrupt:-)

Hättest du einen sketch bitte ?

Ich würde das mit dem Power Down auch sehr gerne mal testen.

lG
Gawan

Ich würde das mit dem Power Down auch sehr gerne mal testen.

Meist möchte man den Prozessor für eine bestimmte Zeit in den Schlaf schicken…

Dafür habe ich ein kleines Beispiel in meiner Wühlkiste:

#include <avr/wdt.h>
#include <avr/sleep.h>

extern volatile unsigned long timer0_millis;
const byte LED = 13;


void sleep(uint16_t seconds)
{
  wdt_enable(WDTO_1S);
  WDTCSR |= _BV(WDIE);
  while(seconds--)
  {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);// SLEEP_MODE_PWR_SAVE
    sleep_enable(); 
    sleep_mode(); 
    // sleeping
    sleep_disable();
    WDTCSR |= _BV(WDIE);
  }
  wdt_disable();
}


void setup() 
{
  pinMode(LED,OUTPUT);
}

void loop() 
{
  digitalWrite(LED,!digitalRead(LED));
  sleep(3);
}



ISR(WDT_vect) // Watchdog timer ISR
{
    timer0_millis += 1000; // atomic
}

So wird wenigsten die Zeit halbwegs vernünftig weiter gesetzt.