MultiThreading

Brand new to Electric Imp and trying to figure out the best way to do a few things.

Specifically, I am dealing with REST calls to my Agent that I want to deal with to control the PINs - which is working great. However, since the Agent and Device are always ready to deal with inbound requests. I haven’t figured out how to deal with my Device initiated messages - I tried to use the sleep and wakeup functions but then the Device isn’t ready for an inbound REST call from the web. Normally, I would troll through forums and the web to find the answer but due to the recent changes in programming, I am finding few relevant examples.

Pin7, Pin8, Pin9 are LEDs based on the sample code - and I can turn them on and off via REST.
Pin2 is a push button that I want to initiate a call to my Agent (already have code that works just don’t know how to invoke it when the button is pressed).

My Pin2 code works when I put in a wakeup function. Seems like I could use the CancelWakeUp but would be happier if I could just use two threads, one to manage Pin2 functions and one for Pin7,8,9 functions.

Any guidance would be welcome.

Is your device running on battery and is maximizing battery life really important?

I have not ever done anything with putting an imp to sleep on purpose (low power modes). I do know that only pin1 can be used to wake up the imp device if you purposely put it down.

otherwise, each of the pins can be used to initiate an event.

pinout

configure pins

I don’t see a need for multiple threads and I am not sure how that would work. The imp is event driven so it deals with events that occur and I assume queues up other events that are to be run next.

You’ll want to configure a callback function for pin 2, as mentioned by mjkuwp94. When you press your button, have it pull Pin 2 to 3.3V or a “High” state. This will trigger the callback function. Of course, like any switch, you’ll need to debounce that in either hardware or software. Your callback function can handle whatever you want to happen when you press the button.

You wont want to sleep at all if you want the device to be responsive to incoming HTTP at the agent.

I am currently using USB supplied power so consumption is not an issue but your answer was exactly what I needed.

I missed the optional “function” in the pin.configure(DIGITAL_IN, function) that will allow me to monitor the PIN without manually checking it, which was exactly what I needed. Thank-you!! I guess that is one of the issues with learning from the sample code.

Appreciate the quick response!

@dannyh - what sample code were you looking at that didn’t include a callback function? Most, if not all of the examples I’ve seen use the callback function instead of manually checking DIGITAL_IN pins.

Ok, I am still having some issues, it is reading fine but only the initial. I have see ‘de-bounce’ code but think it is something more basic. I have stripped out all the extras… what is I have in the Device code:

BUTTON <- hardware.pin2; function sendSF(tmpData){ local buttonVal = BUTTON.read(); server.log("agent: get BUTTON value " + buttonVal); } agent.on("sendSF",sendSF); BUTTON.configure(DIGITAL_IN,sendSF(0));

From the documentation, I don’t expect to need to recall the:

BUTTON.configure(DIGITAL_IN,sendSF(0));

again? I tried some debounce code but didn’t seem to make a difference.

=====LOG ENTRY======
2014-01-06 18:01:32 UTC-5: [Status] Downloading new code; 1.87% program storage used
2014-01-06 18:01:32 UTC-5: [Device] agent: get BUTTON value

Again, I appreciate the guidance.

Your function “sendSF” is running when you load the code? I may be missing something but I don’t see why that should happen.

I suggest changing your function (just as a test) to one that takes no arguments by removing the tmpDATA from its definition.

Then configure your pin like this.

BUTTON.configure(DIGITAL_IN,sendSF);

Also, when you post code it is more readable if you click the “C” on the toolbar and put your code inside the tags.

and also a belated welcome!

I wrapped your code in a < code > </ code > tag :slight_smile:

@mjkuwp94 is correct. You’re BUTTON.configure should look how they wrote it:

BUTTON.configure(DIGITAL_IN, sendSF);

Your code (@dannyh) is executing the sendSF function once when you call BUTTON.configure (which is why it executes when the code starts running), and uses the return value of sendSF as the callback function. Since sendSF doesn’t return anything, you’re setting the callback function to null (do nothing).

The the following two lines of code are equivalent to what you’re doing:

local r = sendSF(0); BUTTON.configure(DIGITAL_IN, r);

If you want sendSF to be called with a parameter of 0 whenever BUTTON’s state changes, you’ll need something that looks like this:

`function sendSFWrapper() {
sendSF(0);
}

BUTTON.configure(DIGITAL_IN, sendSFWrapper);`

Hopefully that makes a bit of sense to you, if it doesn’t let me know and I’ll try explaining some more.

Got it working thanks! I will then embed my sendSF() logic into what you have helped me create. That will let me show off my little device to my coworkers.

I will need to spend some more time working with the language… a few things still seem odd, but that will just be getting use to the language/syntax.

=============================
`BUTTON <- hardware.pin2;

function buttonStateChange() {
server.log(“BUTTON:”+BUTTON.read());
}

BUTTON.configure(DIGITAL_IN_PULLUP, buttonStateChange);`

=========LOG ENTRY==========
2014-01-06 20:44:39 UTC-5: [Status] Device booting; 1.72% program storage used
2014-01-06 20:44:42 UTC-5: [Device] BUTTON:0
2014-01-06 20:44:46 UTC-5: [Device] BUTTON:1
2014-01-06 20:44:49 UTC-5: [Device] BUTTON:0
2014-01-06 20:44:54 UTC-5: [Device] BUTTON:1

Really appreciate your guidance and patience. Was able to get both the inbound REST calls and the button initiated outbound calls working.

Thank again!!