[SOLVED]ATTiny 85 Sleep... MCP79410 unable to wake it up

Hello. I know: yet another thread on sleep mode.
I tried and searched the web/ the forum for a solution, but I don’t think I found anything suitable for me… maybe I’m missing something important.
Premises
I’m using an arduino as ISP. It’s connected to my computer via usb and also provides power to the project.

I’m using an ATTiny85 for prototyping a project that will probably go on a 25V (maybe 45V). It basically has to talk via I2C/TWI (integration provided via TinyWire master library) to an RTC. In this prototype I’m just trying to put the tiny to sleep and wake it whenever the RTC alarm is triggered. So I’m trying to use the pin level change as a wake trigger.

I’m using MCP79410 as an RTC (datasheet). I programmed an alarm to trigger basically each minute (I don’t bothe you with the details) The MCP79410 has a multifunctional pin already programmed to raise a flag whenever the alarm is triggered. This pin is an open-drain connected to VCC via a 10kOhm resistor.

Please also note that:

  • The RTC works fine, tested it via arduino before and after connecting it to the tiny
  • The Tiny and the RTC can “talk” to each other pretty well, i cross-checked with the arduino directly connected to the RTC

Problem
I start the project, taking the voltage of PIN3 (the pin which has to wake the tiny) during the whole experiment. The tiny is successfully put to sleep, but when the alarm is triggered the tiny won’t wake up. Note that:

  • If I set that the alarm has to be triggered with a “HIGH”, the voltage (alarm not triggered) is 2.7V; when triggered is ~4.8V
  • If I set that the alarm has to be triggered with a “LO”, the voltage (alarm not triggered) is viceversa
  • In normal conditions (i.e. not sleep) the values are correctly read by the tiny (I did some testing before this)

code

#include <inttypes.h>
#include<TinyWireM.h>
#include <TinyRTC.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

#define MPF_PIN 1
#define DELAY 6000


TinyRTC rtc(MPF_PIN);
void setup() {
delay(5*DELAY);

  DDRB |= (1<<DDB3);
  DDRB &= ~(1<<DDB1);
  PORTB |= (1<<PORTB3);
  DDRB &= ~(1<<DDB4);
flashpin();
flashpin();
rtc.alarmFlagReset(TinyRTC::RTC_ALM0); //reset the alarm if it's been triggered
rtc.setAlarmLevel(TinyRTC::RTC_ALM0, 0);//sets the alarm to trigger with a LOW logic level
delay(1000);
}

void flashpin(){
 PORTB |= (1<<PORTB4);
 delay(1000);
 PORTB &= ~(1<<PORTB4);
 delay(1500);
}
void sleep(){
 GIMSK |= (1<<PCIE);
PCMSK |= (1<<PCINT3);
 flashpin();
ADCSRA &= ~(1<<ADEN);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
sei();
sleep_cpu();
cli();
PCMSK&= ~(1<<PCINT3); 
sleep_disable(); 
ADCSRA |=(1<<ADEN); 
sei(); 
}

ISR(PCINT0_vect){
  
}
void loop() {
          PORTB |=(1<<PORTB1);
          rtc.alarmFlagReset(TinyRTC::RTC_ALM0);
          PORTB &= ~(1<<PORTB1);
        sleep();
}

Question
What am I doing wrong? Is there anything you think I’m missing?

Thanks a lot!

Just a thought . I'm working with an ESP8266 -12 . It has an XPD pin which is used to reset the device after deep sleep . What I didn't realise was it was connected via a small capacitor so it only gets a pulse to trigger it .

b-james: Just a thought . I'm working with an ESP8266 -12 . It has an XPD pin which is used to reset the device after deep sleep . What I didn't realise was it was connected via a small capacitor so it only gets a pulse to trigger it .

I'm sorry, but I don't understand what you mean... do I have to plug in a capacitor? Ah one other thing: if I manually connect (even very briefly) the tiny pin with gnd (when normally high) o vcc (when normally low), the chip wakes up just fine

Once you prepare to sleep you should probably disable interrupts. You seem to be doing it in an odd sequence.

void sleep(){
  cli ();   // don't want interrupts right now
  GIMSK |= (1<<PCIE);
  PCMSK |= (1<<PCINT3);
  flashpin();
  ADCSRA &= ~(1<<ADEN);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sei();
  sleep_cpu();

Without that, you may get the interrupt before you sleep, so when you eventually sleep, the interrupt has gone.

Thanks for your reply but… that did not do it... it's kinda like the tiny thinks that the 2,7V signal is always high, thus never detecting the change on the pin. Unfortunately I don't actually have a clue on this; can I give you any more details? Thanks a lot, you're doing already so much!

If you look at the datasheet, the input high voltage, if you are running at 5V, is 0.6 * Vcc (ie. 3 volts and above) and input low voltage is 0.3 * Vcc (ie. 1.5 volts and below) thus 2.7 volts is in the range of "unsure".

[quote author=Nick Gammon link=msg=2250614 date=1432759959] If you look at the datasheet, the input high voltage, if you are running at 5V, is 0.6 * Vcc (ie. 3 volts and above) and input low voltage is 0.3 * Vcc (ie. 1.5 volts and below) thus 2.7 volts is in the range of "unsure". [/quote] Ok… it seems strange to me that the MCP79410 is unable to give a "proper" low signal (I couldn't find anything regarding the output low signal). I think there must be something wrong in what I do/enable via software, I mean: everything works fine with arduino and used to work fine with the tiny too, before meddling with the code and inserting the sleep function. Probably the problem is not there.

Have you checked the value of your pull-up resistor?

Martin-X: Have you checked the value of your pull-up resistor?

10k Ohms EDIT: but let me explain: the breadboard part related to the RTC (ie pullup resistors and pin connections) hasn't changed since my arduino tests (when the values were read correctly) So I think either for the Tiny I need something different or something in my sketch is blatantly wrong. It must be something so simple that I missed it easily... I'm still clueless

Ok… instead of using something like

DDRB |= (1<<DDB3);

I went for the less-fancy-more-pratical

 pinMode(3,INPUT);

and the tiny wakes up! :o
What did I wrong? I think my noobness here has done me something wrong :confused:

Also there is still a tiny problem: now, whenever the tiny wakes, blinks the led correctly, but then goes through the whole setup+loop thing, but I would like it just to restart from where it ended (ie: the sleep function of course, then continue the loop).
Is there anything else I’m missing?

Thanks a lot for your kind support, without you I would’ve probably already given up!

DDRB |= (1<<DDB3);

That sets it to output, not input.

I went for the less-fancy-more-pratical …

Indeed. Don’t use the fancy stuff if you don’t need to. You (and everyone else) wastes time then checking that you are using the right operation (or rather than and) whether it is really DDRB and whether it is really DDB3 that needs to be shifted. Lots of things to go wrong there.

Thanks a lot, indeed I learned a valuable lesson…
Right now all of the doubts are gone, and everything seem to work fine, thanks to you all.