Using a button with DIGITAL_IN_WAKEUP

Hi,

I’m wanting to create a simple push button device that allows me to track button interactions but at the same time use the sleep function to conserve battery power. Looking at the documentation I can use the DIGITAL_IN_WAKEUP command. But if I’m using a standard button, do I need to add an extra resistor and a power line to the button to get it to work with the WAKEUP. As it looks like the DIGITAL_IN_WAKEUP uses a pull-down resistor rather than a pull-up one?

The code:
`
function pin1changed() {
local buttonState = hardware.pin1.read();

// if buttonState is 0, the button is pushed
if (buttonState == 0) {
    server.show("Button Pressed!");
    server.log("Button Pressed");
} else {
    server.show("Button Released!");
    server.log("Button Released");
}

}

// Configure Pin1 to be wake up pin
hardware.pin1.configure(DIGITAL_IN_WAKEUP, pin1changed);

server.log(“Test sleep started”);

imp.configure(“Pin1 Waker”, [], []);

// Enter deep sleep
server.sleepfor(3600);
`

Any help much appreciated

Benjamin:-)

Hi all you need to do is connect one side of the switch 3v3 on the April (if thats what you are using) and the other to pin one. I do this with a PIR sensor (it’s a switch) which sleeps all the time. You might consider a bit of denounce in the handler imp.sleep(0.05);

You should also use
imp.onidle(function() {server.sleepfor(3600);});

Thanks ControlCloud,

Will give it a go tonight and see if it works

Thanks

Benjamin:-)

I’d like to understand why we need that 2nd line controlCloud? What processes need to complete before sleeping?

see example para on http://devwiki.electricimp.com/doku.php?id=electricimpapi:imp:onidle

Hi all,

I tried this:

`

function pin1changed() {
// declare a local variable
local buttonState = hardware.pin1.read();

if (buttonState == 0) {
    server.show("Button Pressed!");
    server.log("Button Pressed");
    imp.sleep(0.05);
} else {
    server.show("Button Released!");
    server.log("Button Released");
    imp.sleep(0.05);
}

}

// Configure Pin1 to be wake up pin
hardware.pin1.configure(DIGITAL_IN_WAKEUP, pin1changed);

imp.configure(“Pin1 Waker”, [], []);

// Enter deep sleep
server.log(“Test sleep started”);
imp.onidle(function() { server.sleepfor(120.0); } );
`

The sleep part now works which is great, but now I’m not getting the button reading. Is this because by the time it’s woken up from sleep, it’s stopped reading the button function? Is there a way to read the button state at the same time as waking it up? And also is there a way to keep it awake for 5 mins then go back to deep sleep?

Best wishes

Benjamin:-)

Release 23 has hardware.wakereason() which will tell you if you were woken by pin 1.

I will try your code, but you might just have to change the to Digital_in the top of handler to get it’s state then at the end revert to Digital_in_wakeup. When the sleepfor timer expires the imp does a warm boot and runs all the code again but the handler should run when it sees the rising edge of your switch. Some folk have reported issues with Sparkfun board pin1 not triggering think you need to push the imp card holder and that does the trick

Hi Hugo,

Sorry for the noob question but how do I know what version of the firmware my imp is running?

Best wishes

Benjamin:-)

Hi your code works
Tue May 21 2013 09:24:47 GMT+0100 (GMT Daylight Time): Test sleep started
Tue May 21 2013 09:24:47 GMT+0100 (GMT Daylight Time): Button Pressed
Tue May 21 2013 09:24:47 GMT+0100 (GMT Daylight Time): sleeping until 1369124810000

You won’t catch the button Release though the imp sleeeps after pin1changed() finished the code flow is this
pin1-high
warm boot - runs main code
pin1changed() - pin handler called
deepSleep

You can’t find out what firmware not in API

Hi ControlCloud,

Thanks for your feedback, weird though as when I run it, it doesn’t show the button pressed unless I press it twice:

5/20/2013 11:04:04 PM: Power state: asleep=>online 5/20/2013 11:04:04 PM: Device booting 5/20/2013 11:04:05 PM: Device configured to be "Pin1 Waker" 5/20/2013 11:04:05 PM: Test sleep started 5/20/2013 11:04:05 PM: sleeping until 1369093448000 5/20/2013 11:04:05 PM: Power state: online=>asleep 5/20/2013 11:04:31 PM: Power state: asleep=>online 5/20/2013 11:04:31 PM: Device booting 5/20/2013 11:04:31 PM: Device configured to be "Pin1 Waker" 5/20/2013 11:04:31 PM: Test sleep started 5/20/2013 11:04:31 PM: sleeping until 1369093475000 5/20/2013 11:04:31 PM: Power state: online=>asleep 5/20/2013 11:04:40 PM: Power state: asleep=>online 5/20/2013 11:04:40 PM: Device booting 5/20/2013 11:04:40 PM: Device configured to be "Pin1 Waker" 5/20/2013 11:04:40 PM: Test sleep started 5/20/2013 11:05:00 PM: Power state: online=>offline

How have you wired the button? I’ve got 1 line going to +3.3v and the other to pin 1. Maybe I’m not pressing the button for long enough?

Thanks for helping, much appreciated.

Benjamin:-)

I haven’t used wakeup on pinchange yet, but as I understand it, there should be no need to check the pinstate. The onchange function will only be called after a 0 to 1 transition on the pin, so if its called, it automatically implies that the pin was 1.
Only if you want to ignore very short pulses, which might just be noise spikes, you might want to check if the pin is still high after say 10ms. To do this, you could put just a imp.wakeup(0.01, checkPinState), in your onchange handler, and let the checkPinState() function decide if further action should be taken.

Still can’t get it to work :frowning:

hardware.pin1.configure(DIGITAL_IN_WAKEUP, pin1changed);
This doesn’t seem to trigger the function unless I press the button twice so have no way of triggering the first button press.

Ok have you tried it as a simple digital in no sleep? Is your April from sparkfun? As I said previously there is a mechanical issue with some boards.

Hi ControlCloud,

Yes I have a sparkfun board but it does work nicely with DIGITAL_IN_PULLDOWN. I think looking at some of the other posts, that unless the button is pressed for a few seconds, the function will get skipped. Hugo mentioned about a new version of the firmware which gives us hardware.wakereason() to use. Not sure when this will be released though.

Thanks for your help controlCloud

Benjamin:-)

Benjamin you might want to wait for rel 23 as it tells you what woke the imp up. I have monitor imp when it wakes from pin I don’t go back to deep sleep but stay in Shallow sleep for period. If there is no pin IO I go back to deep sleep. I can share this code but based on current API it will be a lot simpler with rel 23.

The only reason to hold the button high for 2 secs to allow the imp to connect and run code and read pins. In rel 23 you can wake and process in about 60ms if your in wifi off mode. You can then do some counting then send to cloud at a given point.

Hi ControlCloud,

Thanks for helping I started to use:
imp.wakeup(30, function(){server.sleepfor(6000.0)});
in the root which helped, but would be nice to be able to keep adding to the wakeup call if there any interactions detected on the pin.

Slowly getting my head around the nuances of Squirrel and Imp :-p I finally worked out how to declare a global var last night :slight_smile:

Benjamin:-)

The imp is different it runs a event loop and uses call backs. I’ve done some diagrams that have helped others
Imp State
Agent State

Thanks ControlCloud, much appreciated :slight_smile: