Cat Flap - Curiosity

I’m running through the cat flap example and have a question. 


Upon creating the cat flap instance, several variables are passed, but they don’t seem to match what is required in the class:

It is called with (hardware.uart2, hardware.pin1, hardware.pin2, hardware.pin8, hardware.pin9.  

However the class seems to require:  (output, input, rfid, detect, prog, power, latch)

Using the diagram provided, latch is on pin 9 so that’s good.  and power on pin 8 for the rfid reader.  detect will be on port 1 (the IR ldr)  but the input / output seem to be only left with hardware.uart2  does that provide enough to cover both, and if so , what is it saying?  since the rfid scanner is wired to pin 7 , the rfid scanner output / input being on uart2 confuses me a bit.   Thoughts? 


thisCatFlap <- catFlap(hardware.uart2, hardware.pin1, hardware.pin2, hardware.pin8, hardware.pin9);
<pre class="code c" style="padding: 0.5em; margin-top: 0px; font-family: monospace, serif; border: 1px dashed rgb(140, 172, 187); overflow: auto; background-color: rgb(247, 249, 250); text-align: justify; "><span class="sy0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">class catFlap
{
    output = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;          <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Output for reporting feline ingress activity</span>
    input = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;           <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Input for accepting lock override commands</span>
&nbsp;
    rfid = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;            <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// RFID device</span>
&nbsp;
    detect = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;          <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Cat proximity detect input pin, 1 = beam broken</span>
    prog   = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;          <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Program button input pin, 0 = pressed</span>
    power  = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;          <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// RFID power control output pin, 1 = power on</span>
    latch  = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">null</span>;          <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Solenoid latch control output pin, 1 = latch released</span>
&nbsp;
    lockMode = <span class="nu0" style="padding: 0px; margin: 0px; color: rgb(204, 102, 204); ">0</span>;           <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Lock mode: 0 = Normal, 1 = Force Unlocked, 2 = Force Locked</span>
    programMode = <span class="kw2" style="padding: 0px; margin: 0px; font-weight: bold; ">false</span>;    <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Program mode flag</span>
    state = <span class="nu0" style="padding: 0px; margin: 0px; color: rgb(204, 102, 204); ">0</span>;              <span class="co1" style="padding: 0px; margin: 0px; color: rgb(128, 128, 128); font-style: italic; ">// Current state: 0 = Idle, 1 = Scanning</span></span>

First a disclaimer, this is the one example that hasn’t been tested for real as a) I haven’t built it yet and b) there’s no persistent storage yet.  I plan to have it running for real by the time persistent storage is finalised, for now it’s more a reference for how to use the serial port and suchlike.


However your question above, luckily, happens not to be a bug in the code.  You’re confusing member variables with constructor parameters. The list you quote are just a bunch of variable declarations - like free (top level) variables, but you don’t need to put “local” in front because they’re automatically in the scope of that class. The parameters passed in to construct the class are those of the function “constructor” (which is a special purpose function called when a new instance of the class is constructed - like C++). In this case:

    constructor(rfidDev, detectDev, progDev, powerDev, latchDev)
</div><div>So you see, those parameters match the ones we pass when we make an instance of the class:</div><div><br></div><div><pre class="code c" style="padding: 0.5em; margin-top: 0px; font-family: monospace, serif; border: 1px dashed rgb(140, 172, 187); overflow: auto; background-color: rgb(247, 249, 250); text-align: justify; ">catFlap<span class="br0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">(</span>hardware.<span class="me1" style="padding: 0px; margin: 0px; color: rgb(0, 102, 0); ">uart2</span><span class="sy0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">,</span> hardware.<span class="me1" style="padding: 0px; margin: 0px; color: rgb(0, 102, 0); ">pin1</span><span class="sy0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">,</span> hardware.<span class="me1" style="padding: 0px; margin: 0px; color: rgb(0, 102, 0); ">pin2</span><span class="sy0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">,</span> hardware.<span class="me1" style="padding: 0px; margin: 0px; color: rgb(0, 102, 0); ">pin8</span><span class="sy0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">,</span> hardware.<span class="me1" style="padding: 0px; margin: 0px; color: rgb(0, 102, 0); ">pin9</span><span class="br0" style="padding: 0px; margin: 0px; color: rgb(102, 204, 102); ">)</span>
The constructor function stores some of those parameters in member variables, passes some to the base class (rfidDevice) and does other useful initialisation kind of things.

Rob
Fen Consultants

I am also running through this example, though I’m doing it for just one cat… so to speak.  I almost have it working with a motion detector, specifically this one from Adafruit.  When I turn the power on and place a cup over the motion detector, no power goes to the RFID antenna.  When I pull the cup off boom… power to the RFID sensor and I’m (sort of) off to the races.  However, when I put the cup back over the motion detector, the Imp does not seem to detect the new “low” state.  I stuck an LED in to the circuit to confirm that the motion detector was going in to a low state and, indeed, it is.


As an aside, the program logic in the example is wrong.  The outer conditional in detectEvent() only looks for a “high” state of 1 after reading the input so it will miss when the input goes low.  Here is the corrected code -

// Handle user proximity event
function detectEvent()
{
// Get beam state
local beam = detect.read();
 
if(beam == 1) { // We have cat potential
server.log(“Motion detected”);
// Check for a new beam break
if(state == 0) {
// New state: Scanning
state = 1;
// Enable the RFID scanner
rfid.enable();
}
} else if(beam == 0 && state == 1) {
// Cat has departed, disable the RFID scanner
rfid.disable();
            
// New state: Idle
            state = 0;
        }
}

Despite the correct code once the state goes high the Imp never seems to detect the new low state.  Ideas?

Thanks for spotting the error, I’ve corrected the wiki.


Have you put some logging after the detect.read() call?  That should show up whether the event is triggering or not.  If it isn’t then are you sure you have the pin configured with an appropriate pull up or pull down?  If the device drives both ways you probably want a floating input.

Rob
Fen Consultants, UK

So, I connected a multimeter to the motion sensor and it goes to zero when there is no motion and ~3.3V when there is.  I do have logging statements in the code. I have attached the Squirrel code which is a simplified derivative of the original, designed to simply read an RFID tag when motion is detected and post the value to the server.  I have also uploaded a picture of the device.


Note that the Arduino is there to power the Imp, run an RFID antenna, and give me some more debugging capabilities.  I will replace this with an independent antenna once I have the rig working.  The output line from the motion detector is running to pin #1 on the Imp.  I have an LED on pin #9 that I eventually run to an RFID antenna but for now is just there to let me know that the Imp turned the power on in response to a signal from the motion detector.  When I power up the Imp for the very first time that  LED is dark until I move.  The wire from digital pin #6 from the Arduino is the output from the RFID antenna that I am driving using the Software Serial library.

One other interesting thing to note is that I only ever get logging in the constructors.  When I move I expected to see a message in the log but I don’t, despite the fact that the light goes on. Also, the logging is a little flaky.  Sometimes I have to refresh my browser to see the log messages other times it just shows up.

release-2 has issues with server.log() output not always coming out when you expect it. If you use server.error() instead, the output is immediately pushed and also shows up in a rather fetching red :wink:


Looking at that PIR chip datasheet, it’s not immediately obvious if the output is driven low when inactive. The example schematic has it feeding a transistor base, which wouldn’t need a pull-down whereas a CMOS input would.

Can you try configuring the input pin as DIGITAL_IN_PULLDOWN vs DIGITAL_IN?

The red is rather fetching!  Which is also to say that the logging is also working more reliably now.  Here is are the log entries after I changed DIGITAL_IN_PULLUP to DIGITAL_IN_PULLDOWN as you requested -

Wednesday, August 15, 2012 18:30:56: ERROR: RFID Device configured<br><code class="errormessage" style="color: rgb(255, 0, 0); font-weight: bold; cursor: pointer; ">Wednesday, August 15, 2012 18:30:56: ERROR: Ready for swipes...
Wednesday, August 15, 2012 18:31:06: ERROR: Motion detected`
<pre class="font-12" id="logwindow" style="background-color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); font-family: Arial, Verdana; font-size: 13.600000381469727px; white-space: normal; ">But I never see the "Motion Stopped" log message. Note from my last post that I had tested it with a multimeter and saw 3.3 volts when I was moving and 0 when I stopped. &nbsp;To illustrate this I installed an LED back in to the circuit. &nbsp;Take a look at the two pictures I attached. &nbsp;The first one is the device while I stay very still</span><span style="font-family: Arial, Verdana; white-space: normal; "><font color="#222222" size="2">. The second pictures is of the device after I moved. &nbsp;The LED is faint in the picture but it is lit. &nbsp;In both pictures, though, the Imp is sending power through pin #9, never detecting the return to 0 voltage from the motion sensor.</font></span>

Think I’d like to see a log message right at the point of reading the pin, even though obviously state should be 1.


How about also printing what the imp thinks the pin state is in the serial poll loop, just for giggles?

So, I think I may have worked it out.

You are configuring pin 1, then it's possibly getting reconfigured when you configure the UART - this could be a bug as I've seen strange behavior sometimes even with NO_CTSRTS specified.

(btw "uart2" is deprecated, you should be referring to it as "uart1289"). 

Try moving the pin1 configure to after the UART configure line?

This makes a bit more sense.  I was going to mention that I had already done the first part of what you had asked in your second to last comment above.  I was outputting the value to the server so that I could watch the value change in the planner.  As expected. it started out at 0 and when I moved it would change to 1 but would never change back.  I’ll make the modifications first thing tomorrow morning when I’m back in the lab.

I have good news.  I have bad news.  First the bad news.  I tried your suggestions and they did not work.  The Imp is still behaving in the same way.  So, I added a ton of logging and think I may be zeroing in on the problem area.  I have attached the complete code below.  Here is what I see in the logs -

Thursday, August 16, 2012 08:16:32: ERROR: Constructing RFID device<br><code class="errormessage" style="color: rgb(255, 0, 0); font-weight: bold; cursor: pointer; ">Thursday, August 16, 2012 08:16:32: ERROR: RFID device disabled
Thursday, August 16, 2012 08:16:32: ERROR: RFID Device configured<br><code class="errormessage" style="color: rgb(255, 0, 0); font-weight: bold; cursor: pointer; ">Thursday, August 16, 2012 08:16:32: ERROR: Configuring motion detector
Thursday, August 16, 2012 08:16:32: ERROR: Ready for swipes…<br><code class="errormessage" style="color: rgb(255, 0, 0); font-weight: bold; cursor: pointer; ">Thursday, August 16, 2012 08:16:33: ERROR: detectEvent fired! Here is the beam value - 0
Thursday, August 16, 2012 08:16:49: ERROR: detectEvent fired! Here is the beam value - 1<br><code class="errormessage" style="color: rgb(255, 0, 0); font-weight: bold; cursor: pointer; ">Thursday, August 16, 2012 08:16:49: ERROR: Motion detected
Thursday, August 16, 2012 08:16:49: ERROR: RFID device enabled<br><code class="errormessage" style="color: rgb(255, 0, 0); font-weight: bold; cursor: pointer; ">Thursday, August 16, 2012 08:16:49: ERROR: Polling for RFID tag
</div><div style="font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; ">Notice that everything look great all the way to the bit where the code polls for the RFID tag. &nbsp;Then, it appears to just hang in this function -</div><div style="font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "><br></div><div><div><font color="#222222" face="arial, sans-serif" size="2">// Poll for data from RFID reader</font></div><div><font color="#222222" face="arial, sans-serif" size="2">function poll()</font></div><div><font color="#222222" face="arial, sans-serif" size="2">{</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">	</span>if(enabled)&nbsp;</font><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: small; ">{</span></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>// Schedule the next poll in 100ms</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>imp.wakeup(0.1, poll.bindenv(this));</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>server.error("Polling for RFID tag");&nbsp;</font></div><div><font color="#222222" face="arial, sans-serif" size="2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>// Read a byte</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>local byte = serPort.read();</font></div><div><font color="#222222" face="arial, sans-serif" size="2">&nbsp;</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>// Continue reading while data is available and we remain enabled</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>while(byte &amp;&amp; enabled)&nbsp;</font><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: small; ">{</span></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">			</span>rxData += byte;</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">			</span>byte = serPort.read();</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">		</span>}</font></div><div><font color="#222222" face="arial, sans-serif" size="2"><span class="Apple-tab-span" style="white-space:pre">	</span>}</font></div><div><font color="#222222" face="arial, sans-serif" size="2">}</font></div></div><div style="font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "><br></div><div style="font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; ">So the problem could be the way that the imp.wakeup function is being used. &nbsp;I must admit that I do not really understand how this function works. I pulled it from the Cat Flap example, which is where I also got the uart2 function so you should update that example and replace the uart2 function with the uart1289 function.</div><div style="font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "><br></div>
while(byte && enabled) {
rxData += byte;
byte = serPort.read();
}

The serial port read function returns -1 on no data, not zero (which might be a valid data byte). Also, there's no way for "enabled" to get unset inside that loop: Squirrel can't interrupt other Squirrel. So I think the loop should be:

while(byte != -1) 
{
rxData += byte;
byte = serPort.read();
}

Peter

Poof… problem fixed!  That was it Peter.  Golden Imp award for you :wink:


I have attached the working code.  The Cat Flap example on the web should also be corrected.


Thanks ctcreel!  And, yes, Peter is indeed a “Golden Imp.”

So… one last comment here and I’m going to call this example done. In order to communicate with the RFID antenna shown in the attached picture I had to use hardware.uart57.  This picture shows an RFID/NFC Arduino Shield from Adafruit.  In the Arduino code I’m using the SoftwareSerial library to configure pin #7 as an RX pin and pin #6 as a TX pin. I’m then using the Adafruit RFID/NFC library from Github to read the tag ID and then write that to the Imp.  In the attached picture note that I am running pin #5 (TX) from the imp to pin #7 (RX) on the shield, and pin #7 from the Imp (RX) to pin #6 (TX) on the shield.


I have attached the correct code, a picture of the device, and a picture from the planner showing the result.

Are you planning to remove the arduino and just talk I2C to the NFC chip? That would seem a lot less complex in the long run :slight_smile: (though, looking at the adafruit library, non-zero effort to start with!)

Hi


Congrats on getting your code working.

The wiki example code is correct - more or less.

            while(byte != -1 && enabled)
</div><div>It correctly checks for -1 as the read result. Peter is right that the enabled check is pointless because the script runs on a single thread, but it won't cause any logical problems. I'll remove that from the example now.</div><div><br></div><div>Rob</div><div>Fen Consultants, UK</div></div><div><br></div>

Yes, long term I could hook a 13.56 Mhz RFID antenna directly up to the Imp and power it (though I’m not sure yet how to power a 5V antenna with the 3.3 volt Imp pin… a relay with an extra battery I suppose).  The device I am building also has some buttons and LED’s.  I think I could hook them all up to the Imp without a shift register.  The bigger problem is that I need to drive a big honkin’ LCD display that updates every second (scrolling text).  Driving an LCD from the Imp without a library would be a monstrous pain and in the ass so I will still need a local microcontroller.


If I have to pay for a local microcontroller then I might as well use it to coordinate all the local hardware.  This raises some interesting design questions that I have been struggling with.  What I was contemplating was designing a very simple Zigbee-like protocol that I could use to interact with local hardware using a microcontroller as the coordinator / interpreter.

So my long term goal is to move the majority of the 52K of C code off of the current device and in to a vImp.  I would still use a local microcontroller to process commands sent from the vImp to the Imp to work with the device hardware.  My solution also makes heavy use of REST services (POST & GET) to several Internet accessible resources. Unfortunately it appears that the vImp and accessing REST services is a weak spot for the Electric Imp at the moment.  While I am waiting I plan to build working prototypes of each piece of the puzzle.