Help with SPIN Code! - Progress Update for Spinneret Contest - An RFID Access System
lazer luke
Posts: 27
Greetings,
So here is the current code from our RFID access development project and Spinneret competition submission. I need some more help and advice with the SPIN code. This is my first Spinneret (and Propeller) project. I have both the Propeller Manual and Programming and Customizing the Multicore Propeller Micro-controller and they have been great for getting the ball rolling. So far I think it is going well. Although I do need some help moving on from this current iteration.
Just to recap a few things about the status of and conditions surrounding this project. I am a member an instructor at the 3rd Ward Incubator for Innovation in Brooklyn http://www.3rdward.com/ . We are developing an RFID door access system for the shop and studio doors and ultimately some of the shop equipment. Below (before the code) I have some more details about the development and a Road-map to finishing it. I need to have a working networked prototype by this Friday and finished install by the first of July.
What the system does is: take the scanned the RFID card data and via a POST command submit it to a Filemaker based system. That query returns either a 1 or a 0 and the door ether opens or it doesn't. The parts of the hardware circuit are working. Each part of the system has been tested independently with simple test programs. This is the current progress with putting the pieces together.
Mike G pointed out that I should be using memory locks. Thanks.
So this afternoon I reworked the code. I am not sure if I have implemented the memory locks correctly. Also, I am curious if my usage of cognew is correct. I was getting a compile error when trying to use the included parameter list. I switched from using Parameterlist to adding another locked variable to the memory lock routine.
Is this alright. Is it better for some reason to have the variables go through the cognew ParameterList vs managing that with memory locks?
Other questions and concerns that have arisen:
I am setting the pin that triggers the Door Strike to LOW as part of the initialization. Is that necessary?
Do I need to specify that the program waits for each step in the DHCPClient routine in the ServeComMode method? OR is that innate in using the drivers? (I guess I should implement some kind of time out if the server doesn't respond)
I noticed that the RFID module resets from the card read mode to just normal powered up mode after about 25 seconds. So I need to resend that command periodically. That is why I have a waitcnt at the end of the Listen Mode Loop. Is this the best way to achieve this?
During the Listen Mode Loop - if the card is scanned I want to set the variable cardread (read as "card read" and not "car dread") to 1. Does the if Result <> 0 in the Listen Mode Loop achieve that?
Do I need to Stop (or should I) either the Door Access Mode and Listen Mode Loop methods?
Please point out any other issues that you may notice. I am knuckling down to meet this Friday deadline; So thanks in advance for your feed back.
Networked RFID Door and Equipment Access System
Development Road-map for RFID Access System
Phase 1 - Completed May 2011
A Stand Alone Un-Networked RFID Card system for access to Think Tank and Media Lab @ The 3rd Ward Incubator for Innovation.
Built using an Arduino Decimia, a handmade Proto Sheild (made by Kimio Kosaka), Sparkfun Relay Board,
Parallax and Grand Design Studios RFID Read and Write Module and an existing preinstalled 12 Volt
Door Strike and a door bell style button. The system is enclosed in a series of enclosures custom built on a Makerbot
Thingomatic.
This first prototype system is installed in the Lobby's Think Tank Door @ The 3rd Ward. It has been working with uninterrupted service for approximately one month.
It will be replaced by the Phase 2 iteration of the system which is based on the Parallax Spineret Web Server.
Phase 2 - Deadline June 10, 2011
A Networked RFID Door Access Node that is integrated with the networked database and member system.
Built using the Parallax Spinneret Module, Proto Daughter board, Parallax and Grand Design Studios RFID Read and Write Module,
Sparkfun Relay Board, 12 volt door strike and door bell style button.
Phase 3 - Deadline July 1, 2011
Installation of 3 Networked RFID Nodes into The 3rd Ward Incubator for Innovation
Will be very similar to the Phase 2 version but will contain indicator lights and redesigned enclosures.
Phase 4 - 2012
Module based on the RFID Door Access System that can be retrofitted into a variety of Shop Tools, other equipment, computers and cabinets.
Technical Specifications and Code
Based on the following drivers and code examples:
Easy WebServer DEMO2 (build 01_28_2011) v1
RFID RFID Read/Write Object Wrapper
WIZnet W5100 SPI Driver Ver. 00.14
So here is the current code from our RFID access development project and Spinneret competition submission. I need some more help and advice with the SPIN code. This is my first Spinneret (and Propeller) project. I have both the Propeller Manual and Programming and Customizing the Multicore Propeller Micro-controller and they have been great for getting the ball rolling. So far I think it is going well. Although I do need some help moving on from this current iteration.
Just to recap a few things about the status of and conditions surrounding this project. I am a member an instructor at the 3rd Ward Incubator for Innovation in Brooklyn http://www.3rdward.com/ . We are developing an RFID door access system for the shop and studio doors and ultimately some of the shop equipment. Below (before the code) I have some more details about the development and a Road-map to finishing it. I need to have a working networked prototype by this Friday and finished install by the first of July.
What the system does is: take the scanned the RFID card data and via a POST command submit it to a Filemaker based system. That query returns either a 1 or a 0 and the door ether opens or it doesn't. The parts of the hardware circuit are working. Each part of the system has been tested independently with simple test programs. This is the current progress with putting the pieces together.
Mike G pointed out that I should be using memory locks. Thanks.
So this afternoon I reworked the code. I am not sure if I have implemented the memory locks correctly. Also, I am curious if my usage of cognew is correct. I was getting a compile error when trying to use the included parameter list. I switched from using Parameterlist to adding another locked variable to the memory lock routine.
Is this alright. Is it better for some reason to have the variables go through the cognew ParameterList vs managing that with memory locks?
Other questions and concerns that have arisen:
I am setting the pin that triggers the Door Strike to LOW as part of the initialization. Is that necessary?
Do I need to specify that the program waits for each step in the DHCPClient routine in the ServeComMode method? OR is that innate in using the drivers? (I guess I should implement some kind of time out if the server doesn't respond)
I noticed that the RFID module resets from the card read mode to just normal powered up mode after about 25 seconds. So I need to resend that command periodically. That is why I have a waitcnt at the end of the Listen Mode Loop. Is this the best way to achieve this?
During the Listen Mode Loop - if the card is scanned I want to set the variable cardread (read as "card read" and not "car dread") to 1. Does the if Result <> 0 in the Listen Mode Loop achieve that?
Do I need to Stop (or should I) either the Door Access Mode and Listen Mode Loop methods?
Please point out any other issues that you may notice. I am knuckling down to meet this Friday deadline; So thanks in advance for your feed back.
Networked RFID Door and Equipment Access System
Development Road-map for RFID Access System
Phase 1 - Completed May 2011
A Stand Alone Un-Networked RFID Card system for access to Think Tank and Media Lab @ The 3rd Ward Incubator for Innovation.
Built using an Arduino Decimia, a handmade Proto Sheild (made by Kimio Kosaka), Sparkfun Relay Board,
Parallax and Grand Design Studios RFID Read and Write Module and an existing preinstalled 12 Volt
Door Strike and a door bell style button. The system is enclosed in a series of enclosures custom built on a Makerbot
Thingomatic.
This first prototype system is installed in the Lobby's Think Tank Door @ The 3rd Ward. It has been working with uninterrupted service for approximately one month.
It will be replaced by the Phase 2 iteration of the system which is based on the Parallax Spineret Web Server.
Phase 2 - Deadline June 10, 2011
A Networked RFID Door Access Node that is integrated with the networked database and member system.
Built using the Parallax Spinneret Module, Proto Daughter board, Parallax and Grand Design Studios RFID Read and Write Module,
Sparkfun Relay Board, 12 volt door strike and door bell style button.
Phase 3 - Deadline July 1, 2011
Installation of 3 Networked RFID Nodes into The 3rd Ward Incubator for Innovation
Will be very similar to the Phase 2 version but will contain indicator lights and redesigned enclosures.
Phase 4 - 2012
Module based on the RFID Door Access System that can be retrofitted into a variety of Shop Tools, other equipment, computers and cabinets.
Technical Specifications and Code
Based on the following drivers and code examples:
Easy WebServer DEMO2 (build 01_28_2011) v1
RFID RFID Read/Write Object Wrapper
WIZnet W5100 SPI Driver Ver. 00.14
}} CON _clkfreq = 80_000_000 _clkmode = xtal1 + pll16x socket = 0 listenPort = 80 RFID_TX = 25 ' Connects to RFID R/W Module SIN RFID_RX = 26 ' Connects to RFID R/W Module SOUT OBJ DHCPClient : "DHCP_GBSbuild_01_28_2011.spin" RTC : "s-35390A_GBSbuild_01_23_2011" PST : "Parallax Serial Terminal" Host : "FullDuplexSerial" RFID : "RFID.Reader.Writer.Driver" VAR long IP, SubnetMask, GatewayIP, DNS_Server ,destIP byte MAC_Address[6], data[DHCPClient#BUFFER_SIZE] VAR byte TestBuffer[ 12 ] byte CardDataBuffer[ 32 * 4 ] byte OldPwdBuffer[ 4 ] byte NewPwdBuffer[ 4 ] byte HostDataBuffer[ 10 ] long scsstack[ 6 ] byte token[ 4 ] byte access[ 1 ] long lml [ 128 ] 'stack for cog listen mode loop - set to 128 per Prop manual - Page 80 long dam [ 128 ] 'stack for cog door access mode byte AccessLockID byte CardDataBufferLock byte cardread [ 1 ] VAR 'byte ButtonSelected 'byte Stringbuffer[100] PUB Intializer 'Initialize Wiznet 5100 chip DHCPClient.Wiznet5100(socket, @MAC_Address, @GatewayIP, @SubnetMask, @IP, @destIP, listenPort) RTC.start 'Initialize On board RTC XXXXXX This was from the webserver demo. Mabye I don't need it. Unless it would be 'usefull for calculating time in seconds. Should this possibly happen earlier in the program? ' RTC.SetDateTime(month, day, year, dayOfWeek, hour, minutes, seconds) '<- Just do this once to set time '2.1 - Open Socket to web server PST.start(115200) 'Initialize Parallax Serial Terminal ' Network Settings DHCPClient.IPs(@IP,192,168,1,110) ' IP ; a static address of the router DHCPClient.IPs(@SubnetMask,255,255,255,255) ' SubnetMask ; see: www.subnet-calculator.com DHCPClient.IPs(@GatewayIP,192,168,1,10) ' GatewayIP ; your local router's address DHCPClient.IPs(@DNS_Server,192,168,1,10) ' DNS_Server ; usually same as Gateway DHCPClient.IPs(@destIP,0,0,0,0) ' Dest IP can be all zero's DHCPClient.MAC(@MAC_Address,$00,$08,$DC,$16,$F1,$3C) ' MAC address located on spinneret RFID.Start( RFID_RX, RFID_TX ) 'Start Serial to RFID R/W Module 'Do I need to set this low? Since by default the Pin Will be low. What is the best practice? DIRA[24] := 0 'Pin 24 Low - Door Lock State OUTA[24] := 0 cardread := 0 PUB ServerComMode cognew (ListenModeLoop, @lml) cognew (DoorAccessMode, @dam ) 'locknew if (CardDataBuffer := locknew) == -1 '<error no locks availible> else if (access := locknew) == -1 '<error no locks availible> else if (cardread := locknew) == -1 '<error no locks availible> else ' Infinite loop of the server ; listen on the TCP socket 'CardBufferData :=1 'This line was in the example I started with. repeat if @cardread := 1 'DHCPClient.HTMLReady(@data)==0 'Is connection ready to send HTML? 'Thinking this could and should be changed 'to check if the card data buffer is loaded? 'PST.Char(0) ' PST.str(@data) 'ParseDATA(@x) ' '2.2 - TX - HTTP POST - Request Session Tolken DHCPClient.StringSend(socket, @TokenRequestHeader) '2.3 - RX - Recive Session Token DHCPClient.rxTCP(socket, @token) '2.4 - Tolken and RFID Data Buffers. Combine or send sequentially? 'This might not need to exist as when AccessRequestHeader is called 'it will just be taken care of in the POST. 'combine into a string or just as POST elements@token, @CardBufferData '2.5 - TX - HTTP POST - Send Token and RFID Data DHCPClient.StringSend(socket, @AccessRequestHeader) '2.6 - RX - Recieve Server respose and stores it in buffer DHCPClient.rxTCP(socket, @access) '2.7 - Close Socket connection DHCPClient.NoPersistanceAllowed(socket) PUB ListenModeLoop '| ErrCheck, CmdByte, LoopCounter, IndexCounter, Offset LISTEN MODE LOOP Repeat Repeat until not lockset(CardDataBuffer) lockclr (CardDataBuffer) Repeat until not lockset(cardread) lockclr (cardread) ' 'pub startRFIDread 'REPEAT 'until @TestDataBuffer <> 1 '1.3 - Send RFID R/W module Hexadeciamal Read command 0X01 'Host.str( string( "Trying to read all card data...", 13 ) ) bytefill( @CardDataBuffer, 0, 128 ) Result := RFID.TryToReadCardData( @CardDataBuffer, 0, 32, 5 ) if Result <> 0 cardread := 1 'waitcnt ( 50_00_000 + cnt ) waitcnt ( 1_600_000_000 + cnt ) PUB DoorAccessMode Repeat until not lockset(access) lockclr (access) if @access := 1 '3.1.2 - Server responded 1 'DIRA[??] := 1 '3.1.2.1 - Access Granted Indicator LED 'OUTA[??] := 1 DIRA[24] := 1 '3.1.2.2 - Door Strike Unlock - PIN 24 High OUTA[24] := 1 waitcnt ( 400_000_000 + cnt ) '3.1.2.3 - Wait 5 Seconds 'DIRA[??] := 0 '3.1.2.1 - Access Granted Indicator LED 'OUTA[??] := 0 DIRA[24] := 0 '3.1.2.2 - Door Strike Unlock - PIN 24 High OUTA[24] := 0 '3.1.2.4 - Start Listen Mode Loop if @access := 0 '3.1.1 - Sever reponded 0 This is commented out but ultimatley it will bw 'DIRA[??] := 1 '3.1.1.1 - Access Deined Indicator LED - 'Commented out for now as the LED part of the circuit 'will be implemented in next version. 'OUTA[??] := 1 'waitcnt ( 20_000_000 + cnt ) 'listenMODEloop.start 'or 'cognew DAT TokenRequestHeader byte "<POST / HTTP/1.1>" byte "< Host: 192.168.1.1>" byte "<Connection: close>" byte "<User-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)>" byte "<Accept-Encoding: gzip>" byte "<Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7>" byte "<Cache-Control: no-cache>" byte "<Accept-Language: de,en;q=0.7,en-us;q=0.3>" byte "<Referer: http://web-sniffer.net/>" byte "<Content-type: application/x-www-form-urlencoded>" byte "<Content-length: 1>" byte "<Tokenreqyest: (@tokenrequest)>" AccessRequestHeader byte "<POST / HTTP/1.1>" byte "< Host: 192.168.1.1>" byte "<Connection: close>" byte "<User-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)>" byte "<Accept-Encoding: gzip>" byte "<Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7>" byte "<Cache-Control: no-cache>" byte "<Accept-Language: de,en;q=0.7,en-us;q=0.3>" byte "<Referer: http://web-sniffer.net/>" byte "<Content-type: application/x-www-form-urlencoded>" byte "<Content-length: 34>" byte "<Token: (@token)>" byte "<RFID Data: (@CardBufferData)>" OBJ {{ ┌───────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├───────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and │ │associated documentation files (the "Software"), to deal in the Software without restriction, │ │including without limitation the rights to use, copy, modify, merge, publish, distribute, │ │sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is │ │furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or │ │ substantial portions of the Software. │ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT │ │NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ │NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, │ │DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ │SOFTWARE. │ └───────────────────────────────────────────────────────────────────────────────────────────────────┘ }}
Comments
DHCPClient.Wiznet5100(...) is invoked before the argument list is filled with data. The web server is not initialized properly.
PUB Intializer is the application entry point. Intializer does not call any other methods. When you reach the end of Intializer, your program stops; ServerComMode is never called. Chapters 5 and 6 in the PE kit covers methods and COGs. You can find the PE kit in the Spin Tool Help dropdown menu.
The use of memory locks is way off. The idea is to allow only one process to access memory at one time. A memory lock is either in the locked or unlocked state. Processes are not allowed to touch memory that is in a locked state. Read pages 120, 122, 125, and 126 in the Propeller Manual.
Honestly I wasn't sure about the @ beginning of those variables. I am really piecing this together from a medley of sources and and that is what happened along the way. I cut the extraneous @.
As for cardread. I think I got what you meant with regard to the it not being the same as 123 and the @ address vs the actual variable. (after awhile it all just looks like pixels)
But to clarify what cardread was supposed to be and do. Cardread is not the actual card value just a 1 or 0. Indicating if the CardDataBuffer had data or not. I was thinking that the following line would be the real problem. I am not sure comparison of the Result to 0 would be a legitimate comparison.
So the idea for cardread would be set to 0 in Initialization and then 1 when the CardDataBuffer was filled. I realize now ...... I never set it back to zero after DoorAccessMode. Making note.
OK. I see the initialization and the variables in the web-server were out of order. How did that happen? Oh yeah I did it.
With regards to the locks. I read over those pages and instances of memory lock in the forum. I get the concept of how the locks work and why to use them. But have yet to really digest how to incorporate them. Going to look at it with fresh eyes in the morning!
Thanks again for the feedback. Will be working on it again tomorrow and updating as circumstances progress.
Luke