Having trouble using Sleep() with wakeUpPin

No since it is ENTER_STOP_Mode() via Spark.sleep() that sets the pinMode() used for waking which is ONLY set when the sleep mode is entered. :smile:

I'm not involved enough to answer this and I'm not going to read into the bootloader/powerup firmware to provide hard facts, but in theory (again :wink: - and I have been proven wrong before :blush: ):
While on power-up - I think @mdma said - all variables declared global and/or static will get initialzed by the Spark "framework", this was not said explicitly for wake-up too, so there could still be some difference in code paths.
The only thing that I remember being said for wake-up is that your user code will definetly go through setup().
So I'm not saying it is that way, but concluding from the fact that something does work at power-up, it would have to be the same on wake-up, might not actually have to be true.

I don't know! @peekay123 can say things better and in less words, so I'm always second :smile: I should maybe stop reading philosophy.

But back to work: If you want a less hacky approach for this, you could think up a way to have both - the wake and the servo - interrupts trigger on the same edge , circumventing my suspected pull-resistor-switching problem. Edit: Ridiculous suspicions on my side :blush:

@ScruffR and @mnetwork, let’s review please:

  1. Setting a pinMode for the pin used by Spark.sleep(pin, mode, time) PRIOR to calling Spark.sleep() does nothing since it will get set to pinMode(pin, INPUT) for mode==CHANGE after Spark.sleep() causes the core to reset and go into STOP mode. This pinMode MAY cause false triggering due to noise.

  2. When the Core is awakened, it will act as if the RESET button was pressed

  3. Digital inputs MAY glitch on power up causing a false trigger when the Core resets to go into STOP mode.

  4. Using an analog pin for the wakeup pin may alleviate 3 above.

I will test different scenarios tonight and report my findings.

2 Likes

Thank you. i will also do some testing.

1 Like

OK, I’ve done some testing too, and proven myself partly wrong :blush: and partly (sort of) right :wink:

As for all the references to attachInterrupt() causing a change in pinMode, I got it wrong. As Paul said this doesn’t happen (I’ll add according comments to my previous posts - to punish myself, before others will :wink: )
But for Spark.sleep() with wake on interrupt my additional tests still suggest, that pinMode including pull resistors are set to match the trigger option (as mentioned above). But I still could have chosen unfit test scenarios, so I’m anxiously awaiting Paul’s results.

So, I’m fully agreeing with Paul’s statement 1. I even got the impression, that the false triggering is more likely to happen than not - with floating pin this is.

As for 2. this is what I see too, but my “philosophical” discourse above was rather targeted at the risk to get bitten by erronous conclusions based on wonky data.

I agree that 4. would be a good test for 3.

Wow, @ScruffR, that must have hurt just to write it! :stuck_out_tongue: So here is what we have learned from this so far:

  • Using Spark.sleep(pin, CHANGE, time) will put the wake pin in INPUT mode, leaving it susceptible to noise (IMO). So to use this mode, an external pull-up or pull-down resistor is recommended.

:smile:

2 Likes

You bet! :stuck_out_tongue_closed_eyes:

And yes, it was my first suspicion that CHANGE was the culprit and should be avoided (for wake-up) by any means, if you can't be sure that you have a clean signal at any time (either dedicated pull resistors or a reliable signal source).
If this had been taken up immediately, I would not have humiliated myself - again :wink:

1 Like

So, I did more testing today and found this…

If I set button pin to use a PULLUP (and wired it to ground) and set the sleep interrupt for FALLING the server flag would not get set on wake up. It seems there is some kind of cycle happening during wakeup.

This was the only time using FALLING for the sleep interrupt worked. It seems that sleep interrupt can’t be used when it is cycled? You can’t set the switch to be wired to a 3.3v and set the sleep interrupt to be FALLING. It seems it can only detect the initial change (LOW -> HIGH) and not a cycle (LOW -> HIGH -> LOW). I was only trying to use a pulldown because I’ve always just assumed that a PULLDOWN would use less power when sitting (not pressing the button) than a PULLUP. After some reading I learned that neither uses more power when sitting.

This code is working just fine. I removed the sleep button now. I only put that in for testing.

const int buttonpin = D0;
const int servopin = A0;

const int closepos = 1;
const int openpos = 180;

int servoflag = 0;
int currentpos = 0;

Servo myservo;

void setup() {
    pinMode(buttonpin, INPUT_PULLUP);

    currentpos = closepos;
    
    attachInterrupt(buttonpin, moveservo, RISING);
}

void loop() {
    
    if (servoflag == 1) {
        myservo.attach(servopin);
        
        if (currentpos == closepos) {
            myservo.write(1);
            delay(250);
            myservo.write(openpos);
            delay(1000);
            currentpos = openpos;
        } else if (currentpos == openpos) {
            myservo.write(1);
            delay(250);
            myservo.write(closepos);
            delay(1000);
            currentpos = closepos;
        }
        
        myservo.detach();
        servoflag = 0;
        
        delay(500);
        Spark.sleep(buttonpin,FALLING,20);
    }
}

void moveservo() {
    servoflag = 1;
}
2 Likes

Good to hear that you've sorted your problem :+1:

Just out of interest, what do you mean by this?

I especially don't get the meaning of "when it is cycled"?
Is it power cycle, sleep-wake cycle, reset, ...
And what do you mean with "sleep-interrupt"?
Your previous interrupt sleepmode() or the wake-on-interrupt?

Since when I tested wake-on-interrupt, I could use any pin and edge trigger combination just fine.

The only thing that would prevent a wake would be that wake-on FALLING does attach a pull-up implicitly, thus you can't produce a falling edge with your button wired to HIGH.
When pressing the button, the already HIGH pin just remains HIGH and when you release the button the pull-up takes over again and keeps the pin HIGH still, so there never occures a falling edge, which would wake the Core.

Just to stress this again: When setting wake-on triggers, whatever pinMode() you set your pin before going to sleep will be lost. The selected trigger type does set its own pull-resistors ("overwriting" your previous choice).

1 Like

Just to add to what @ScruffR said, the use of CHANGE interrupt is possible but ONLY if the selected pin is at a logic level and not floating. This means having an external pull-up or pull-down OR the device that is driving the pin must output a HIGH or LOW but not a tri-state (open-collector/drain) condition. :smile:

2 Likes

I mean when you put it so sleep and are expecting the Core to use a series of changes as the interrupt. If I have the switch wired to 3.3v, the initial change when pressed would be LOW or FALLING. It seems you cannot sleep using an interrupt that is the same as the sitting state. In this example you can't sleep with an interrupt of FALLING. The interrupt needs to be a state opposite of the state it is sitting at. Forgive me, I can't think of a better word at the moment than "sitting".

I am talking about the wake-on-interrupt, yes.

Ah, this explains what I was just saying.

Got it.

Haven't been trying to use CHANGE anymore, but I do know this now.

1 Like

Random question to put this to bed. I am converting a project of mine from RaspberryPi to Spark Core. In my old code I have a state variable that was just maintained by the code and not related to an actual external physical state. Upon reset it would just pretty much reset a few others things and default to a certain state. With the Core you get a reset after every deep sleep. Apart from moving to Photon or linking to another external physical state, is there any trick to maintaining a variable after a reset?

@mnetwork, in the Core you could store the variable in EEPROM. You could store a checksum along with your vars so you know when to initialize them the first time. :smile:

2 Likes

That's not entirely true.
If you've got an external pull resistor out-weighing the internal one in the opposite direction or a switch that feeds discrete HIGH/LOW signals to the pin rather than only one of these together with a float signal, you will be able to do this.
But the question is, is it worth the bother, just for the sake of doing it :wink:

In this connection the CHANGE trigger might be more appropriate.

Perfect, thank you!

True, but no sense in doing that. Everything I needed was accomplished. Thank you both for your help!

2 Likes

@peekay123 @ScruffR Bringing this back from the dead for an issue I ran into. I was using a wakeUpPin to wake from Sleep in a new project… The pin config was a NC switch wired to ground using an internal pull-up. The only way I could get it to wake up the Core was to set it to wake on FALLING because RISING wouldn’t work. It is weird because RISING would be the initial change and FALLING would be a two step change. I was forced to use an external pull-up resistor and now it works as expected. Why would this be?

The reason again, is the internal pull resistor that comes together with any of the edge triggers.

As frequently elaborated in the posts above.

If you want to trigger the rising edge the Core will attach a pull-down and when you then open your N/C switch it lets go of the switch allowing the pull resistor to take over, but since it is a pull-down, the pin will stay LOW - and you'll see no edge to wake the Core.

Please try to remember: You can't set the pull resistor independent of the wake-on-interrupt edge. So even if you set pinMode(pin, INPUT_PULLUP) it does not mean that wake-on-rising will have a pull-up attached.

And for this use I'd contradict this statement of yours

Exactly this use case would benefit of the CHANGE trigger :wink:

1 Like

Ah, ok… so:

sleep FALLING = internal pull-up
sleep RISING = internal pull-down?

2 Likes

Exactamente :+1:

2 Likes

@ScruffR @peekay123 I have a few questions on power consumption and pull-ups/pull-downs.

Does power consumption differ between a pull-up and pull-down?
Is more power used when the pull-up/pull-down is being bypassed or does it depend on the direction of the pull resistor?
Does power consumption change between using an internal or external pull-up/pull-down?