Attiny85 will nicht aufwachen

Hallo zusammen,

seit Wochen programmiere ich einen Attiny85 8Mhz getaktet. Ich bzw. der Attiny85 hängt irgendwie immer an der gleichen Stelle fest und ich komme nicht weiter.
Es geht darum das der Attiny85 mit zwei AA Batterien betrieben werden soll. Ohne Tiefschlaf zieht er ungefähr 8 Milliampere was mir deutlich zuviel ist. Ich möchte ihn schlafen legen bis der Vibrationssensor ein Signal erkennt. Er muss schnell aufwachen, den Buzzer auslösen, das Signal über 433Mhz zu einem zweiten Attiny85 schicken und wenn der Vibrationssensor keine Vibration mehr wahr nimmt, kann er wieder schlafen bis zur nächsten Vibration. Mit diesem Sketch geht der Attiny ungefähr auf 4 Milliampere runter, Problem ist das er nicht aufwacht. Wo liegt der Fehler? Ich bin am verzweifeln?

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

#define BUZZER_PIN 0
#define VIBRATION_SENSOR_PIN 2
#define TRANSMIT_PIN 1

// Eindeutige ID für diese Einheit
const char *unitID = "UNIT1";

void setup() {
  vw_set_tx_pin(TRANSMIT_PIN);
  vw_setup(2000);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(VIBRATION_SENSOR_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(VIBRATION_SENSOR_PIN), wakeUp, RISING);
}

void loop() {
  int vibrationState = digitalRead(VIBRATION_SENSOR_PIN);
  if (vibrationState == HIGH) {
    // Wenn Vibration erkannt wurde, Buzzer aktivieren
    digitalWrite(BUZZER_PIN, HIGH);

    // Nachricht mit eindeutiger ID senden
    char msg[20];
    sprintf(msg, "%s:BEEP", unitID);
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx();
  } else {
    // Wenn keine Vibration mehr festgestellt wird, Buzzer ausschalten
    digitalWrite(BUZZER_PIN, LOW);
    sleepNow();
  }
}

void sleepNow() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();
  sleep_disable();
}

void wakeUp() {
  // Code zum Aufwachen
}

7.1 Sleep Modes
....
Note: 1. For INT0, only level interrupt

Also nix RISING

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

#define BUZZER_PIN 0             //ACHTUNG! Ordnung gewechselt // und wieder zum richtigen Pin ;)
#define VIBRATION_SENSOR_PIN 2
#define TRANSMIT_PIN 1

// Eindeutige ID für diese Einheit
const char *unitID = "UNIT1";

void setup() {
  vw_set_tx_pin(TRANSMIT_PIN);
  vw_setup(2000);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(VIBRATION_SENSOR_PIN, INPUT);
}

void loop() {
  if (digitalRead(VIBRATION_SENSOR_PIN)) {
    // Wenn Vibration erkannt wurde, Buzzer aktivieren
    digitalWrite(BUZZER_PIN, HIGH);

    // Nachricht mit eindeutiger ID senden
    char msg[20];
    sprintf(msg, "%s:BEEP", unitID);
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx();
  } else {
    // Wenn keine Vibration mehr festgestellt wird, Buzzer ausschalten
    digitalWrite(BUZZER_PIN, LOW);
    sleepNow();
  }
}

void sleepNow() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  attachInterrupt(VIBRATION_SENSOR_PIN, wakeUp, LOW);
  sleep_mode();
  sleep_disable();
}

void wakeUp() {
  // Code zum Aufwachen
  detachInterrupt(VIBRATION_SENSOR_PIN);
}

Der t85 hat nur einen Hardwareinterrupt, auf pin 2.
Oder?

weis nicht. Pinoutbilder im Netz zeigen INT0 auf PB0 und es ist Bein 5 am DIP8 Gehäuse.

Mein Datenblatt sagt:
image

Bin mal gespannt wie sich das auflöst......

was heisst das auf Deutsch?

Dass es wie in deinem Vorschlag richtig ist! (nur eben der Pin falsch ?)
LOW und HIGH werden Interrupts im Tiefschlaf auslösen.
Rising, Falling und Change nicht. (die benötigen einen Takt zur Auswertung)
Die tuns nur im Normalbetrieb.

HIGH in diesem Fall scheint nicht anwendbar

Verstehe ich nicht.
Aber mir fehlt auch der Schaltplan.

Sorry einen Schaltplan habe ich nur im Kopf. Eigentlich wird nur ein Vibrationssensor KY-027 mit einem aktiven Buzzer und einen 433mhz (WL102-341) verbunden und am Attiny85 angeschlossen. Vom Aufbau sehr simpel. Die Schaltung funktioniert auch gut. Sobald ich allerdings den Sleep Mode einfüge, geht der Attiny zwar von 8 mA auf ca. 4,5mA, aber er wacht nicht auf wenn der Sensor vibriert.

@kolaha: dein sketch funktioniert auch nicht!

ein defekt am attiny liegt auch nicht vor, den habe ich schon gewechselt.

heißt das dass Spannung am Auslösepin ist nicht konstant ?
hast du ohne "Sensor" aber mit Taster probiert?

hast du pins getauscht oder nur Sketch hochgeladen?
hast du beachtet das Auslösen passiert wenn SensorPin LOW ist?

@kolaha Ich habe natürlich die pins auch getauscht. wenn ich den attiny mit 3v Spannung (AA Batterie) sehe ich das er 4,86mA zieht. Bewege ich den Vibrationssensor zieht er 4,56mA. er wacht aber nicht auf, es piept kein buzzer und es wird auch kein signal über 433mhz zu einem anderen attiny geschickt.

ich gehe davon aus das die Spannung am Pin nicht konstant ist. Der Vibrationssensor ist eine kleine Glasröhre mit einer Quecksilberkugel.

während des Aufwachens sollte Pin konsequent LOW bleiben. so ist die Frage gültig: "wenn man manuell den pin erdet, reagiert MCU darauf ? vermutlich sollte man vorher pull-up implementieren.

Vielleicht noch einmal kurz der Hinweis: Der Pin für externe Interrups (INT0) ist PB2, IDE Pin 2 und nicht PB0 PCINT0 (IDE Pin 0).

Wenn der INT0-Interrupt aktiviert ist und als level triggered" konfiguriert ist, wird der Interrupt ausgelöst, solange der Pin auf low gehalten wird. Beachten Sie, dass die Erkennung von Interrupts mit fallender oder steigender Flanke Interrupts auf INT0 das Vorhandensein eines E/A-Takts erfordert.

Nur um das noch einmal kurz erwähnt zu haben.

Ich kann der Sache leider geistig nicht mehr ganz folgen. Sehe ich das jetzt richtig das ich den attiny mit dem Vibrationssensor nicht aufwecken kann, oder ist an dem code etwas falsch?

Ich habe mal im WWW gesucht und habe meinen Fund etwas verändert, so daß er bei mir gut funktioniert.

Deep Sleep und Wecken mittels Interrupt
// Quelle: https://github.com/blevien/attiny85-sleep/blob/master/attiny85-sleep.ino
#include <avr/interrupt.h>
#include <avr/sleep.h>

int ledPinLoop = 0;        // LED connected to digital pin 0
int ledPinWakeUp = 4;      // LED to show the action of a interrupt
int wakePin = 2;           // active LOW, ground this pin momentary to wake up


void setup()
{
  pinMode(ledPinLoop, OUTPUT);     // sets the digital pin as output
  pinMode(ledPinWakeUp, OUTPUT);   // sets the digital pin as output
  pinMode(wakePin, INPUT_PULLUP);  // sets the digital pin as input
  digitalWrite(wakePin, HIGH);
}


void sleepNow()
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
  sleep_enable();                        // enables the sleep bit in the mcucr register so sleep is possible
  attachInterrupt(0, wakeUpNow, LOW);    // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW
  digitalWrite(ledPinLoop, LOW);

  sleep_mode();                          // here the device is actually put to sleep!!

  sleep_disable();                       // first thing after waking from sleep: disable sleep...
  detachInterrupt(0);                    // disables interrupton pin 3 so the wakeUpNow code will not be executed during normal running time.
  delay(250);                            // wait 2 sec. so humans can notice the interrupt LED to show the interrupt is handled
  digitalWrite (ledPinWakeUp, LOW);      // turn off the interrupt LED
}

void wakeUpNow()        // here the interrupt is handled after wakeup
{
  //execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
  digitalWrite(ledPinWakeUp, HIGH);
}

void loop()
{
  digitalWrite(ledPinLoop, HIGH);   // sets the LED on
  delay(5000);                      // waits for a second
  sleepNow();                       // sleep function called here
}

Funktioniert dieses Beispiel auch bei Dir?

Alternativ ist auch Schlafmodus mit Wecken durch Pin Change Interrupt (PCI) möglich.

entschuldigung, anscheinend PCINT0 und INT0 sind ganz andere Bezeichnungen. also doch PB2. jetzt ist geklärt. danke.