Spark-bouncer - Cloud+RFID based door access control - configure rules via cloud calls, handle >3000 keys on flash storage, live logging via publish, RFID OTP read/write/compares, bling!


#2

this is AWESOME. thanks for sharing! want to make a hackster page??


#3

Dude, that’s so RAD! :smile: Congrats on completing a very cool project and thanks for sharing!

The days of one file applications are back as well, haha… pretty sweet man. Even though there’s not much to see, I’d like to see a video of it in action.


#4

Glad you guys like it :wink:

The system is already deployed in a local citizen movement’s HQ with 80 keys circulating, running pretty stable and smooth. We got an Android app to scan the keys (NFC for the win), assign a name + hours to them, store it all in a MongoDB with the server pushing the keys to the spark-bouncer as soon as a user’s data got updated.

Will create a small video of the installation in a few days - look forward to the musical harmony of a buzzing AC electric strike! :dancers: :dancer: :smiley:


#5

@rastapasta,

Do you have some photos? I’m intending to share about your project so pictures will be awesome! :smiley:


#6

@kennethlimcp

Awww, proud blushing happening here :blush:
Will upload some to this thread in the next 24h, crazily distracted with a beautiful project right now :sweat_smile:


#7

Actually… :slight_smile: We got an introduction for volunteers of our Transition Town Give-away shop featuring it:

Enjoy the German! :smiley: :sunflower:

Will upload some pictures of the tech soon…


#8

Is this project still active?

Thinking of resurrecting my SparkCore for this project and remember how to use it!

Does it play nicely with the cloud compiler “out of the box”?

Does it work if it looses Internet connectivity?


#9

One more question… If I had two separate setups would the same rfid tag work in both or would the OTP then not be in sync?


#10

@gorstj, as @rastapasta points out in the github repo:

The code is currently optimized to locally compile outside of the cloud.

Also, from the looks of it, it may not work without Cloud connectivity as it runs in SYSTEM_MODE(AUTOMATIC) which will “hang” the user app while the firmware attempts to reconnect to the Cloud. The code would have to be modified to take advantage of the SEMI_AUTOMATIC and MANUAL system modes to allow the code to work with Cloud connectivity.

As for the OTP, looking at the code, once a card is scanned, a unique OTP is written to it. If you use the card on another setup, then the OTP will get overwritten. Ideally, you would duplicate the stored key data to the second setup which would then not see the card as new. :smile:


#11

Thanks peekay.

Spark has changed a lot since I used it last… the libraries structure etc. wasn’t there last time I was around!

I think I am having problems with it compiling due to the libraries? When I compile in the WebIDE I get the following error. Any ideas? I have changed the include statements to the following when I added the libraries to the project in the WebIDE:

#include "flashee-eeprom/flashee-eeprom.h"
#include "MFRC522/MFRC522.h"
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from MFRC522/MFRC522.h:77,
from MFRC522/MFRC522.cpp:8:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
MFRC522/MFRC522.cpp: In member function 'bool MFRC522::MIFARE_UnbrickUidSector(bool)':
MFRC522/MFRC522.cpp:1629:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
MFRC522/MFRC522.cpp: In member function 'byte MFRC522::PCD_CommunicateWithPICC(byte, byte, byte*, byte, byte*, byte*, byte*, byte, bool)':
MFRC522/MFRC522.cpp:379:20: warning: '_validBits' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (*backLen < 2 || _validBits != 0) {
^
MFRC522/MFRC522.cpp: In member function 'void MFRC522::PICC_DumpMifareClassicSectorToSerial(MFRC522::Uid*, MFRC522::MIFARE_Key*, byte)':
MFRC522/MFRC522.cpp:1362:4: warning: 'invertedError' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (invertedError) {
^
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from flashee-eeprom/flashee-eeprom.h:22,
from flashee-eeprom/flashee-eeprom.cpp:17:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from spark-bouncer.cpp:33:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
spark-bouncer.cpp:41:17: error: 'user_t' was not declared in this scope
int checkAccess(user_t &user);
^
spark-bouncer.cpp:41:25: error: 'user' was not declared in this scope
int checkAccess(user_t &user);
^
spark-bouncer.cpp:42:15: error: variable or field 'saveUser' declared void
void saveUser(user_t &user, uint16_t keyId);
^
spark-bouncer.cpp:42:15: error: 'user_t' was not declared in this scope
spark-bouncer.cpp:42:23: error: 'user' was not declared in this scope
void saveUser(user_t &user, uint16_t keyId);
^
spark-bouncer.cpp:42:38: error: expected primary-expression before 'keyId'
void saveUser(user_t &user, uint16_t keyId);
^
spark-bouncer.cpp:43:1: error: 'user_t' does not name a type
user_t readUser(uint16_t keyId);
^
spark-bouncer.cpp:44:15: error: variable or field 'dumpUser' declared void
void dumpUser(user_t &user);
^
spark-bouncer.cpp:44:15: error: 'user_t' was not declared in this scope
spark-bouncer.cpp:44:23: error: 'user' was not declared in this scope
void dumpUser(user_t &user);
^
spark-bouncer.cpp:112:25: error: 'int checkAccess(user_t&)' redeclared as different kind of symbol
} user_t;
^
spark-bouncer.cpp:41:5: error: previous declaration of 'int checkAccess'
int checkAccess(user_t &user);
^
spark-bouncer.cpp: In function 'void rfidIdentify()':
spark-bouncer.cpp:466:31: error: 'checkAccess' cannot be used as a function
if (debugMode) {
^
spark-bouncer.cpp: In function 'int checkAccess(user_t&)':
spark-bouncer.cpp:524:29: error: 'int checkAccess(user_t&)' redeclared as different kind of symbol
memcpy(target, buffer, 16);
^
spark-bouncer.cpp:41:5: error: previous declaration of 'int checkAccess'
int checkAccess(user_t &user);
^
make: *** [spark-bouncer.o] Error 1

Error: Could not compile. Please review your code.

#12

p.s. does anyone have a the name of the software this forum runs on so I can find some instructions… I can’t seem to be able to quote code without some of the text being huge as above.


#13

Look for discourse forum :wink:


#14

Have a look in this thread

The “huge” font comes from the use of # outside of a dedicated code block.


#15

Very odd… I have got it to compile without modification using the Spark Dev app on a Mac by just adding the libraries into the same folder.

Using the Web IDE creates the errors above… very odd… don’t they both use the same Cloud compiler backend?

Just waiting for my RFID reader to turn up from ebay!


#16

@gorstj, the web IDE requires a different path statement for libraries. Using Spark CLI or DEV leverages the cloud compiler but without the path issues. I pretty well only use CLI/DEV or a local toolchain for compiling now. :smile:

BTW: I totally forgot I have a bunch of these readers and I will be trying out this project as well :stuck_out_tongue:


#17

Just for future information what should the path statement be for the library?

I tried this (as inserted by the web IDE when I added the library):

#include "flashee-eeprom/flashee-eeprom.h"
#include "MFRC522/MFRC522.h"

#18

@gorstj, both these libraries are available on the web IDE so including them will automatically generate the correct #include statement which you can then replace the original (non-working) one with. Nonetheless, you syntax looks correct. :smile:


#19

When you give it a whirl would you try the Web IDE to see if you can get it working.
I’m hoping my RFID readers arriving today.

I am not overly convinced that running my own local cloud will be any more reliable than Spark’s cloud even when accounting for internet outages.

If I use SYSTEM_MODE(SEMI_AUTOMATIC) my understanding is that as soon as I try and connect to the cloud it will lock the user program until it connects? Even SYSTEM_MODE(MANUAL) will lockup e.g. if there is no internet connection?


#20

Received my RC522 and all works good straight away!!

What really surprised me is that if I disconnected my internet the program still ran! I only tested for a couple of minutes so far.

The only problem I have now is that when the Spark Core powers up the I/O ports go transiently high… this would cause my garage door to open! (it only needs a transient completion of the circuit to cause an open/close cycle) Is there any way to stop the I/O transiently going high on powering up?

The only way I could think of was have two relays… one relay would be ‘normally open’ the other ‘normally closed’ and have the garage door wire running through BOTH relays. This way one of the relays has to be powered on and the other powered off for the circuit to complete which shouldn’t happen on powering up the Core. I would need to modify the code to control two output pins accordingly when I did want the door to activate.

Does anyone have any better suggestions?


#21

If you read this post there seem to be some sugestions

In short, you might try an A pin rather than a D.
I only browsed over the thread and haven’t tested it, but it might still be worth a try.