Hardware.pin1.write(1) randomly causes imp to drop off line

I’m using my Imp to control a garage door opener. When I originally wrote the code, everything worked. Now, when I execute this code, pin1 writes, then the device may drop offline and I have to power cycle to bring it back. I’ve tried with both the “for” loop and the imp.sleep command (currently commented out). In both cases, when it fails, the door will move but the log never shows “checkpoint 8.” Usually it will work fine for 10 minutes or so after a reboot and then fail, but occasionally it will fail following the first execution after restart.

`
function pressbutton(buttonState) {
buttonState=0;
server.log(“checkpoint3”);
hardware.pin1.write(1);
server.log(“checkpoint7”);
for(local a=0;a<5000;a+=1);
//imp.sleep(0.5);
server.log(“checkpoint8”);
hardware.pin1.write(0);
server.log(“checkpoint4”);
}

hardware.pin1.configure(DIGITAL_OUT);
`

Any ideas???

Could you provide more information? Was the device functioning with the same code and hardware for a long time? days or weeks or months? and then out of the blue stopped? What does pin 1 do? Could you be having interference from a garage door motor or a power brown-out?

The device was functioning for a long time…but I also don’t use the open/close door function often. My initial thought was that something changed with the latest firmware change, but I have no way of actually verifying that.

Pin1 is wired to the switch of a remote for the garage door. When the agent triggers the “pressbutton” function, pin1 puts 3.3v on the control side of the controller button. The power for the controller is provided from the 3.3v output on the breakout board rather than by battery to prevent floating voltages.

My current thought is that I’m experiencing the pin1 problems that the early imps and boards suffered or that when I trigger pin1, I’m putting enough of a power draw on the system to cause the board to drop offline. I tried changing my 1 amp usb power supply to a 2 amp, but that made no difference. My next troubleshooting step is going to be moving the wire over to pin2, updating the code, and trying again…unless someone else has a better idea.

The only other applicable code on the device side is:

agent.on("button", pressbutton);

and on the agent side:
`
function requestHandler(request, response) {
try {
if (“button” in request.query) {
server.log(“checkpoint1”);
if (request.query.button == “2”){
server.log(“checkpoint2”);
device.send(“button”,2);
response.send(200, “received”);
server.log(“checkpoint6”);
}
}
}
catch (ex) {
response.send(500, "Internal Server Error: " + ex);
}

}
`

I can see some busy looping in there. If the imp is busy-looping (vs using callbacks) then it will get marked offline because it has not responded to the server.

Can you post the entire device-side code here?

Here it is:
`
//Garage door status monitor, alarm, and opener

//Identify the output ports
//Status reports “Open” or “Closed”
//Alarm reports “Normal” or “Alarmed”

//push the button connected to pin 1 on agent call
//the for loop holds the button down before it is released
function pressbutton(buttonState) {
buttonState=0;
server.log(“checkpoint3”);
hardware.pin1.write(1);
server.log(“checkpoint7”);
for(local a=0;a<5000;a+=1);

//imp.sleep(0.5);
server.log("checkpoint8");
hardware.pin1.write(0);
server.log("checkpoint4");

}
server.log(“checkpoint5”);

//Pin5 is connected to a magnetic reed switch that monitors the door status

//Debounce digital status of pin5
ignore <- false;
function debounce() {
ignore = false;
check_state();
}

//Function to watch the state of the door and to send outputs when the stats changes
function check_state() {
//Check state of the door
local doorstatus=hardware.pin5.read();
//Check date (required to find the current time)
local d = date();
//Set current GMT hour
local hournow = d.hour;
//Preset alarm status
local alarmstatus = false;
//If statements set the times for alarm
if (hournow >= 4)
if (hournow <= 11)
//Check to see if door is open
if (doorstatus == 1)
//If door is open during hours of concern, set alarm
alarmstatus = true;
//Report status of door to output 1
// out1.set(doorstatus?“Open”:“Closed”);
agent.send(“DoorState”, doorstatus?“Open”:“Closed”);
//Log door status
server.log(doorstatus?“open”:“closed”);
//Log alarm status
server.log(alarmstatus?“Alarmed”:“Normal”);
//Report status of alarm to output 2
// out2.set(alarmstatus?“Alarmed”:“Normal”);
agent.send(“AlarmState”, alarmstatus?“Alarmed”:“Normal”);
//Show door status on planner
server.log(doorstatus?“open”:“closed”);
}

//Continues debounce procedures
function switched () {
if(!ignore) {
check_state();
ignore = true;
// imp.wakeup(0.05, debounce);
}
}

//Configure the digital pins
hardware.pin5.configure(DIGITAL_IN_PULLUP, switched);
hardware.pin1.configure(DIGITAL_OUT);

//Check to see if the door has opened or closed
check_state();

//watchdog keep alive–necessary to continually update COSM and Sen.se streams
function watchdog() {
imp.wakeup(60, watchdog);
server.log(“watchdog”);
check_state();
}

agent.on(“button”, pressbutton);

// start sending something every ~1 minutes
watchdog();

`

Changed to pin2. Still having the same problem. The system seems to work well for the first 10 minutes or so after a restart. The failures mostly seem to occur a long period of inactivity. The log shows no other failures after the long inactivity and the watchdog and feed timers continue to update right up until the system is commanded to pull pin2 (or pin1 in the code above) high.

And here is the log file:

2014-09-27 14:42:40 UTC-6 [Device] checkpoint3
2014-09-27 14:42:43 UTC-6 [Agent] checkpoint1
2014-09-27 14:42:43 UTC-6 [Agent] checkpoint2
2014-09-27 14:42:43 UTC-6 [Agent] checkpoint6
2014-09-27 14:43:10 UTC-6 [Status] Device disconnected

I also seem to have caused a memory error during one of the attempts: 2014-09-27 15:11:10 UTC-6 [Agent] https://api.xively.com/v2/feeds/126309.csv
2014-09-27 15:11:10 UTC-6 [Exit Code] imp restarted, reason: memory error
2014-09-27 15:11:10 UTC-6 [Status] Device Booting; 4.45% program storage used

My suspicion is that the circuit connected to that pin is upsetting the imp’s power supply in some way, or drawing a large amount of power.

One thing is that if you want to drive a pin for 0.5s then the best way is to use a wakeup to change the state, eg:

hardware.pin1.write(1); imp.wakeup(0.5, funtion() { hardware.pin1.write(0); });

…then you need no arbitrary delays.

The code, as posted, will only work for the first state change on pin5, because on the first press ignore is set to true (which will cause all subsequent activity to be ignored) but the debounce() function which resets ignore never gets queued to run.

The memory error is unusual though. I’ve queued 30.17 for your imp which will give us a tiny bit more info on that, see if you can get it to happen again :slight_smile:

Willis,

I assume you’re powering your Imp with a 5VDC USB wall-wart?
Doing that will provide enough voltage to switch a 5VDC relay with contacts.
The relay normally open contact will be across your garage door pushbutton you have on the wall.

Here is a circuit that is safe for the Imp …

The relay can be like one of these:
http://www.mouser.com/ProductDetail/Omron/G5V-1-DC5/?qs=Pjd0UV7BHP%2FGqZ0zy8DG3Q%3D%3D&gclid=CKyskp_lhMECFVFgMgoduRYAcg

@mlseim–I appreciate the circuit (and actually looked at your garage program code), but due to the layout of my garage, it isn’t practical for me to wire into the pushbutton. I had an extra garage remote that I can power using the 3 volt out from the sparkfun card. The remote was previously powered by 2 AAA batteries, so using the 3 volts from the card shouldn’t be too much of a draw. Since I’m using the same power source, I only have to pull one side of the remote button up to 3V to trigger the remote to open/close the door. This circuit worked for a while, but just recently stopped.

I’m not sure if the weather affected my soldering, if a firmware update to the Imp changed things, if the shaking of the door identified a short, or if something else is going on.

I’ve tightened the soldering and made sure nothing is currently shorting…so I’m going to see if this works. If not, I’ll add capacitors across the 3V output and 5V input to limit the affect of any voltage drops to see if that helps.

Thanks for the help.

Hugo–

Haven’t seen the memory error repeat yet.

I pulled the debounce code–wasn’t really needed but was a holdover from code I copied early in the development of the software.

I don’t understand the concern with that loop or why the imp sleep or wakeup commands would be any better. I just need to have a ~.25-.5 second pause with pin1 held high to simulate holding the button down. It is such a short time period, and only called when I want to open/close the garage, that there should be no affect on server connection.

Updated/cleaned code (with switchover to pin2) for those of you following along at home:

`//Garage door status monitor, alarm, and opener

//Identify the output ports
//Status reports “Open” or “Closed”
//Alarm reports “Normal” or “Alarmed”
//out1 <- OutputPort(“status”);
//out2 <- OutputPort(“alarm”);

//push the button connected to pin 1 on agent call
//the for loop holds the button down before it is released
function pressbutton(buttonState) {
server.log(“Pre Button Press”);
hardware.pin2.write(1);
server.log(“Button Pressed”);
for(local a=0;a<5000;a+=1);
server.log(“Button Timer Complete”);
hardware.pin2.write(0);
server.log(“Button Released”);
}

//Pin5 is connected to a magnetic reed switch that monitors the door status

//Function to watch the state of the door and to send outputs when the stats changes
function check_state() {
//Check state of the door
local doorstatus=hardware.pin5.read();
//Check date (required to find the current time)
local d = date();
//Set current GMT hour
local hournow = d.hour;
//Preset alarm status
local alarmstatus = false;
//If statements set the times for alarm
if (hournow >= 4)
if (hournow <= 11)
//Check to see if door is open
if (doorstatus == 1)
//If door is open during hours of concern, set alarm
alarmstatus = true;
//Report status of door to output 1
agent.send(“DoorState”, doorstatus?“Open”:“Closed”);
//Log door status
server.log(doorstatus?“open”:“closed”);
//Log alarm status
server.log(alarmstatus?“Alarmed”:“Normal”);
//Report status of alarm to output 2
agent.send(“AlarmState”, alarmstatus?“Alarmed”:“Normal”);
//Show door status on planner
server.log(doorstatus?“open”:“closed”);
}

agent.on(“button”, pressbutton);

//Configure the digital pins
hardware.pin5.configure(DIGITAL_IN_PULLUP);
hardware.pin2.configure(DIGITAL_OUT,0);

//Check to see if the door has opened or closed
check_state();

//watchdog keep alive–necessary to continually update COSM and Sen.se streams
function watchdog() {
imp.wakeup(120, watchdog);
server.log(“watchdog”);
check_state();
}
watchdog();
`

One other question–I’ve seen conflicting info on this–if my Imp were suffering from the Pin1 connection problems that were seen in some early boards, could Pin2 have the same issue? Should I try connecting to another pin?

I bought the Imp and sparkfun breakout board in Nov 2012, so I think I’m in the era where the Pin1 problem occurred.

We never saw any issues on anything except pin 1 on the sparkfun boards, but if you have spare pins, give one a try? The issue there is just a bad connection, so it wouldn’t cause a crash or reboot, it’s just like the pin isn’t wired up at all.

The pause is indeed short enough to not cause issues with the server connection, my comment was more one on the elegance of the solution :slight_smile:

So I’m a bit concerned about how the imp is connected to the transmitter. Can you explain it again? Are you powering the transmitter through the GPIO pin directly? (many of these remotes use the momentary pushbutton to actually pass the operational current of the transmitter, as this means there’s zero power draw when the button is not pressed).

Hugo–

From the Sparkfun board, the +3V connects to the transmitter’s positive battery terminal. The ground connects to the negitive terminal. The button on the transmitter has two connections–one side that is +3V and one that controls the transmission when the button is pressed. Imp Pin1 in the original code (now Pin2) is wired to the control side. When the code fires, the Imp puts 3V on the control side of the button, the transmitter transmits, and the door opens.

Here is what I am now seeing for failures:

If I reset the Imp or load new code, the Imp will work perfectly as long as I keep interacting with it–open/closing the door (transmitter receive light on the garage door flashes a single time and the door moves). If I let the Imp run without providing any input for 20 minutes or so, when I send the “push button” command, the button (pin1) seems to stick high (transmitter receive light on the garage door flashes for 30-45 seconds and the door moves) and then the Imp drops offline forcing me to unplug it for a reset.

It does sound very much like there’s something about what is connected that causes the problem.

If you disconnect everything from the imp, and run the same code, does it happen?

I tried running your code on an imp here, with the device code unchanged but using this for the agent code:

server.log("agent"); imp.wakeup(60*20, function() { server.log("agent sends"); device.send("button", 0); });

…to send a button press after 20 minutes of connected time, and the device didn’t go offline for me. Obviously, no hardware connected, powered differently, etc.

This is the logging from that point in time:

2014-09-29 07:37:14 UTC-7 [Agent] agent sends 2014-09-29 07:37:14 UTC-7 [Device] Pre Button Press 2014-09-29 07:37:14 UTC-7 [Device] Button Pressed 2014-09-29 07:37:14 UTC-7 [Device] Button Timer Complete 2014-09-29 07:37:14 UTC-7 [Device] Button Released

Thanks for trying that. I’m going to make some wiring changes later this week and I’ll let you know what happens.

I’m still a bit confused about the “hardware” aspect of the remote control.

If your garage is within range of your remote control (eg. in your house), would it not be in range for your Imp? I can walk about 150 feet from my house and still get WiFi reception on the Imp. I think that’s further than my garage remote control.

You mentioned the layout of your garage not being able to use the pushbutton …
But what about the door opener itself? Is it on the ceiling, plugged into an outlet?

I put my Imp (April board) in a little plastic box and stuck it to the side of my opener. Since there is already an outlet on the ceiling (for the opener), I just plugged in my USB supply (5V) for the April board.

Does your WiFi reach your garage?
And if not, you should make it reach. Nice having WiFi in the garage for working on stuff. Internet access at your fingertips.