Newbie Led Taster Attiny mit Timer

Hi,

Habe mir in den Kopf gesetzt (von meinen Jungs angeregt) Legospielzeug mit LEDs auszustatten. Für den Beginn habe ich den Wunsch, dass der Attiny

  • auf Tasterdruck aufwacht und die Led einschaltet
  • nach 5min automatisch abschaltet und in den Schlafmodus geht bzw dies auf Tasterdruck geschieht

1led an 3v Cr2032 mit Taster an Attiny45

Habe tagelang gebastelt, zusammenkoppelt und versucht. Kann mir jemand einen Gesankenanstoss bzgl Programmierung geben? Das wäre ungeheuerlich toll für meine Nerven :slight_smile:

Herzlichen Dank Minisme

Willkommen!

Anstoß: Taster an Interrupt der den Tiny aufweckt, LED an, Zeit zählen, ausschalten, schlafen legen

Habe dir eine PM geschickt mit einem Bespielcode.

Hallo,

Danke für den Beispielcode und den Anstoss! (sry XenOn hatte versehentlich eine Nachricht statt Post gesendet).

Ist es nun so, dass ich Interrupt, Sleep_Mode und die Schaltung mit Timer kombinieren kann?

Aktuell gibt mir die Überprüfung noch einen Fehler aus welchen ich noch nicht ergooglen konnte...??
Ursache ---> GIMSK |= _BV(INT0); //enable INT0
MCUCR &= ~(_BV(ISC01) | _BV(ISC00)); //INT0 on low level

Darauf folgend die Frage ob ich so den Stromverbrauch minimiert habe.

#include <avr/sleep.h>
#include <avr/interrupt.h>
#define BODS 7                   //BOD Sleep bit in MCUCR
#define BODSE 2                  //BOD Sleep enable bit in MCUCR
uint8_t mcucr1, mcucr2;

#define taster 0                // Die Zahlen mit den genutzten Pins ersetzten
#define led 1                  // Bei diesem Beispiel ist der Taster an Pin 0 und die led an Pin 1

boolean tasterold, tasternew;  // Bit Variabeln für Flankenerkennung
boolean state;                 // Bit Variabel für den Zustand der led
unsigned int timer;            // Variabel von 0 - 65535 für Zeit


void goToSleep(void)
{
  GIMSK |= _BV(INT0);                       //enable INT0
  MCUCR &= ~(_BV(ISC01) | _BV(ISC00));      //INT0 on low level
  ACSR |= _BV(ACD);                         //disable the analog comparator
  ADCSRA &= ~_BV(ADEN);                     //disable ADC
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  //turn off the brown-out detector.
  //must have an ATtiny45 or ATtiny85 rev C or later for software to be able to disable the BOD.
  //current while sleeping will be <0.5uA if BOD is disabled, <25uA if not.
  cli();
  mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
  mcucr2 = mcucr1 & ~_BV(BODSE);
  MCUCR = mcucr1;
  MCUCR = mcucr2;
  sei();                         //ensure interrupts enabled so we can wake up again
  sleep_cpu();                   //go to sleep
  cli();                         //wake up here, disable interrupts
  GIMSK = 0x00;                  //disable INT0
  sleep_disable();               
  sei();                         //enable interrupts again (but INT0 is disabled from above)
}

ISR(INT0_vect) {
}                  //nothing to actually do here, the interrupt just wakes us up!


void setup() {
  pinMode(taster, INPUT);      // taster als Input festlegen
  pinMode(led, OUTPUT);        // led als Output festlegen
  digitalWrite(led, LOW);      // led ausschalten
}

void loop() {
  // Flankenerkennung
  tasterold = tasternew;
  tasternew = digitalRead(taster);

  if (!tasterold & tasternew)  // Auf die positive Flanke der Taste
  {
    state = !state;            // Zustand der Led wechseln (wenn on dann off/ wenn off dann on)
    timer = 0;                 // Timer resetten
  }

  if(state == HIGH)            // überprüfen ob die led ein sein soll
  {
    if (timer == 1000)         // Die Zeit bis zum automatischen ausschalten in 10ms -> 1s = 100, 1min -> 600..
    {
      state = LOW;              // Wenn Zeit abgelaufen led ausschalten
    }
    else
    {
      timer++;                  // Zeit hochzählen
    }
    digitalWrite(led, HIGH);    // LED EINSCHALTEN
  }
  else                         // sonst:
  {
    digitalWrite(led, LOW);     // LED AUSSCHALTEN
  }

  delay(10);                  // Verzögerung von 10ms
}

Das mit dem externen Interrupt INT0 aktivieren und deaktivieren solltest du auch über die Arduino Mittel attachInterrupt() und detachInterrupt() machen können. Dann halt eine leere Funktion anhängen.

Gelöst ist es nun über diesen Code. Mit dem eingesetzten Attiny45 läuft es problemlos mit Timer.

CR2032 -> Taster -> Attiny45 -> 1x LED
per Taster an/ausschalten, Timer 3min -> Sleep Mode Power Down

#include <avr/sleep.h>
#include <avr/interrupt.h>
#define BODS 7                   //BOD Sleep bit in MCUCR
#define BODSE 2                  //BOD Sleep enable bit in MCUCR
uint8_t mcucr1, mcucr2;

#define taster 0                // Die Zahlen mit den genutzten Pins ersetzten
#define led 1                  // Bei diesem Beispiel ist der Taster an Pin 0 und die led an Pin 1

boolean tasterold, tasternew;  // Bit Variabeln für Flankenerkennung
boolean state;                 // Bit Variabel für den Zustand der led
unsigned int timer;            // Variabel von 0 - 65535 für Zeit


void goToSleep(void)
{
  GIMSK |= _BV(INT0);                       //enable INT0
  MCUCR &= ~(_BV(ISC01) | _BV(ISC00));      //INT0 on low level
  ACSR |= _BV(ACD);                         //disable the analog comparator
  ADCSRA &= ~_BV(ADEN);                     //disable ADC
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  //turn off the brown-out detector.
  //must have an ATtiny45 or ATtiny85 rev C or later for software to be able to disable the BOD.
  //current while sleeping will be <0.5uA if BOD is disabled, <25uA if not.
  cli();
  mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
  mcucr2 = mcucr1 & ~_BV(BODSE);
  MCUCR = mcucr1;
  MCUCR = mcucr2;
  sei();                         //ensure interrupts enabled so we can wake up again
  sleep_cpu();                   //go to sleep
  cli();                         //wake up here, disable interrupts
  GIMSK = 0x00;                  //disable INT0
  sleep_disable();               
  sei();                         //enable interrupts again (but INT0 is disabled from above)
}

ISR(INT0_vect) {
}                  //nothing to actually do here, the interrupt just wakes us up!


void setup() {
  pinMode(taster, INPUT);      // taster als Input festlegen
  pinMode(led, OUTPUT);        // led als Output festlegen
  digitalWrite(led, LOW);      // led ausschalten
}

void loop() {
  // Flankenerkennung
  tasterold = tasternew;
  tasternew = digitalRead(taster);

  if (!tasterold & tasternew)  // Auf die positive Flanke der Taste
  {
    state = !state;            // Zustand der Led wechseln (wenn on dann off/ wenn off dann on)
    timer = 0;                 // Timer resetten
  }

  if(state == HIGH)            // überprüfen ob die led ein sein soll
  {
    if (timer == 18000)         // Die Zeit bis zum automatischen ausschalten in 10ms -> 1s = 100, 1min -> 600..
    {
      state = LOW;              // Wenn Zeit abgelaufen led ausschalten
    }
    else
    {
      timer++;                  // Zeit hochzählen
    }
    digitalWrite(led, HIGH);    // LED EINSCHALTEN
  }
  else                         // sonst:
  {
    digitalWrite(led, LOW);     // LED AUSSCHALTEN
    goToSleep();                // In den Schlafmodus setzten
  }

  delay(10);                  // Verzögerung von 10ms
}

Ohne Hilfe würd ich noch immer hier sitzen - vielen Dank an alle und ganz besonderer Dank an XenOn!!!

Xen0n:
Habe dir eine PM geschickt mit einem Bespielcode.

Bitte keine Coderweitergabe über PM. Für andere, die durch diesen Tread ihr Problem lösen könnten ist das nicht nachvollziehber.
Grüße Uwe

Hallo uwefed,

verstanden :slight_smile: aus diesem Grund nochmal meine Zusammenfassung der Lösung im oberen Post damit für andere Nutzer nachvollziehbar :wink:

Ohne die PM wäre ich nie so weit. Alles in allem hat dieses Forum mit seinen Nutzern wieder
***** Sterne verdient! Danke!

Gruss minisme