Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ fp-info-cache
# Exported BOM files
*.xml
*.csv
NewDoorController/data/Network.json
206 changes: 206 additions & 0 deletions NewDoorController/NewDoorController.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
//SWINDON MAKERSPACE THING CONTROLLER
// DOOR V0.1

//change board version to match what is printed on the thing controller board get most GPIO correct automatically
// needs to be a string
#define ThingControllerBoardRev 1

//DEFINE IF IN WIRED OR WIFI MODE (ONLY 1 define at a time!!!)
#define WIFIMODE //UNCOMMENT TO ENABLE WIFI MODE - BOARD SELECTION MUST BE Pi PICO W
//#define WIREDMODE //UNCOMMENT TO ENABLE WIRED MODE - BOARD SELECTION MUST BE Pi PICO or WIZnet W5500-EVB-Pico


//local files
//#define ENABLE_BUILTIN_BADGES
#ifdef ENABLE_BUILTIN_BADGES
#include "builtinBadges.h"
#endif

// #ifdef WIFIMODE
// #include "ThingControllerWifi.h"
// ThingControllerWifi controller;
// #endif
// #ifdef WIREDMODE
// #include "ThingControllerWired.h"
// ThingControllerWired controller;
// #endif
#include "ThingControllerBase.h"
ThingControllerBase controller;

//Door connection defines
#define EXIT_BUTTON 12 //INPUT digital GPIO expansion connector pin
#define DOOR_SENSOR 13 //INPUT digital GPIO expansion connector pin
#define LCD_ON 11 //use BTN0 as a toggle to turn on the LCD screen
#define VERBOSITY 10 //use BTN1 as a toggle for verbosity

enum statemach {
SM_IDLE, //waiting for someone swiping to the door
SM_UNLOCK, //door access granted or door unlock pressed
SM_RESPONSE, //door access denied
SM_REMAINS_OPEN //door has been left open
};

statemach thingState = SM_IDLE;


void setup() {


int msg_pos = 0;

Serial.begin(9600);

//GPIO setup
pinMode(EXIT_BUTTON, INPUT_PULLUP);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
pinMode(VERBOSITY, INPUT_PULLUP);
pinMode(LCD_ON, INPUT_PULLUP);

controller.initLcd();

// for(size_t i = 0; i < UniqueIDsize; i++){
// Serial.println(UniqueID[i], HEX);
// int tmp = UniqueID[i];
// controller.printMsgln(String(tmp), VERB_ALL);
// }
// printMsgln(msg, VERB_ALL);
controller.printMsgln("Setting up", VERB_ALL);

//start up little fs to get the config file
controller.configDevice();

delay(1000); //delay so can be read



// printMsgln("", VERB_ALL);
//setup wifi
controller.setupNetwork();



controller.printMsgln("Setting up PN532", VERB_ALL);
//connecting to PN532 rfid reader
nfc.begin();
nfc.setPassiveActivationRetries(0xFF);
nfc.SAMConfig();
//msg = String(nfc.getFirmwareVersion());
//printMsg(msg, VERB_ALL);
uint32_t versiondata = nfc.getFirmwareVersion();
controller.printMsgln("Firmware ver. ", VERB_ALL);
controller.printMsg(String((versiondata >> 16) & 0xFF), VERB_ALL);
controller.printMsg(".", VERB_ALL);
controller.printMsg(String((versiondata >> 8) & 0xFF), VERB_ALL);
controller.printMsgln("PN532 Set up", VERB_ALL);
controller.colorPattern = PATTERN_ORANGE;
delay(5000);//delay needed to allow wifi to finish its own thing
controller.sendLogMsg(controller.Thing_Name + " device started up sucessfully");
verbosity = VERB_LOW;
rp2040.wdt_begin(8000);
controller.showLogo();
}

void loop() {
rp2040.wdt_reset();
TOKEN_CACHE_ITEM* tag = controller.lookForCard(); //check if there is a card present

//unlock door if tag is valid
if (tag != NULL){//if something got scanned
if (tag->flags && TOKEN_ACCESS){
thingState = SM_UNLOCK;
actionTimer = millis();
controller.colorWipe(tag->colour);
controller.printMsgln("Unlocking by Tag", VERB_MED);
isUnlocked = true;
controller.sendLogMsg("Access granted to " + String(controller.tokenStr));
controller.unlockDevice();
//unlock door
//set door color
//set door timeout
}else{ //access denied but there was still data so got an error in response
thingState = SM_RESPONSE;
actionTimer = millis();
controller.colorWipe(tag->colour);
controller.printMsgln("Denied", VERB_ALL);
isUnlocked = false;
actionTimer = millis();
controller.sendLogMsg("Access denied to " +String( controller.tokenStr));
//set colour
//lock door
}
} else {
switch (thingState){
case SM_IDLE:
if (!digitalRead(DOOR_SENSOR)){//if door is open for no reason
thingState = SM_REMAINS_OPEN;
controller.colorWipe(PATTERN_PINK);
}
if (!digitalRead(EXIT_BUTTON)){
thingState = SM_UNLOCK;
controller.colorWipe(PATTERN_PINK);
controller.printMsgln("Unlocking by Button", VERB_MED);
controller.unlockDevice();
actionTimer = millis();
}
break;
case SM_UNLOCK:
if(actionTimer + (controller.Unlock_Seconds*1000) < millis()){//if door has stayed open long enough
if (!digitalRead(DOOR_SENSOR)){ //door still open
thingState = SM_REMAINS_OPEN;
controller.printMsgln("Door kept open", VERB_HIGH);
controller.colorWipe(PATTERN_PINK);
}else{ //door closed go to idle
thingState = SM_IDLE;
controller.colorWipe(PATTERN_ORANGE);
controller.printMsgln("setting idle", VERB_HIGH);
isUnlocked = false;
controller.lockDevice();
}
}
break;
case SM_RESPONSE:
if(actionTimer + (controller.Unlock_Seconds*1000) < millis()){//if door has stayed open long enough
thingState = SM_IDLE;
controller.colorWipe(PATTERN_ORANGE);
controller.printMsgln("setting idle", VERB_HIGH);
controller.lockDevice();
//lock door
//set colour
}
break;
case SM_REMAINS_OPEN:
if (digitalRead(DOOR_SENSOR)){
thingState = SM_IDLE;
controller.colorWipe(PATTERN_ORANGE);
controller.lockDevice();//lock door only once closed
}
break;
}
}
delay(25);

//check if verbostiy should change
if (!digitalRead(VERBOSITY)){
controller.changeVerbosity();
delay (200);
while (!digitalRead(VERBOSITY)) {
delay(1);
rp2040.wdt_reset(); //if dont put this here then presing the button for 8 seconds resets the device
}
delay (200);
}
//toggle LCD screen on/off
if (!digitalRead(LCD_ON)) {
digitalWrite(LCD_BACKLIGHT, !digitalRead(LCD_BACKLIGHT));
delay (200);
while (!digitalRead(LCD_ON)) {
delay(1);
rp2040.wdt_reset(); //if dont put this here then presing the button for 8 seconds resets the device
}
delay (200);
}
controller.animation(); //update the LED pattern thats currently showing
//checkDoorStatus(); //check door statis
}


64 changes: 64 additions & 0 deletions NewDoorController/ReadMe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
GUIDE TO NEW DOOR CONTROLLER

NOTE CURRENTLY REQURIES Adafruit PN532 library to be on version 1.2.3 (1.3.0 doesnt work for some reason and cant tell why right now)

DOOR COLOUR CODES REFERENCE
Normal colours
YELLOW - Idle waiting for tag, door is locked
RED - Tag not recognised as anyone
PINK - Door open or unlocked by exit button
GREEN - Access granted to member


HALF RED/YELLOW - Member found but hasnt paid
HALF RED/BLUE - Weekend member trying to access on week day
WHITE - Network Issue - attempt multple times reset device and it might regain connection after reset
HALF RED/PURPLE - Member doesnt have permission (shouldnt happen on door but may on tools)
HALF RED/PINK - Tag is associated to more than 1 account - please talk to directors as there is a mistake in database
HALF RED/GREEN - Unknown error - please let directors know as this shouldnt happen (if repeatable please take video of what how its caused)



PINOUT
NFC reader IRQ Pin to Pin 17 (defined in code)
LCD ON/OFF toggle SW0 (defined in code)
verbostiy toggle SW1 (defined in code)
Door sensor SW2 (defined in code) - Check that active low is correct behaviour
Exit button SW3 (defined in code) - Check that active low is correct behaviour
Door unlock Pin8 (defined in config json)

Device configuration
The device configuration is defined by the LitteFS file stored on the Pi Pico called config.json
This includes settings which should vary per THING such as :
How long the device is unlocked for (5 seconds for door)
Thing name - door
Thing UUID - UUID needed for server ping

Network configuration
The network configuration is defined by the LittleFS file stored on the pi Pico called network.json
If you want to swap between WIFI and WIRED then you will need to comment/uncomment the define in the main code
#define WIFIMODE //uncomment for WIFI MODE
#define WIREDMODE //uncomment for WIRED MODE (NOT YET IMPLEMENTED!)

To change the config files you need the older Arduino software with the littleFS plug in to upload to the Pi Pico
Set Pi Pico flash size to 2Mb with FS 64Kb


Verbosity System
The display is used only for debug messages right now
To prevent too much text being displayed at times and missing the useful stuff or wanting more info there are 3 verbosity levels to the messages
Low/Med/High
SW1 switches between these settings and each message has an assigned verbosity level
High shows all messages (low, med and high)
Medium shows some messages (low and med)
Low shows limited messages


Code implementation
The bulk of the code is done by ThingControllerBase.h
It has an class that is instaniated by ThingControllerWifi/Wired.h depending on defines
ThingControllerBase.h has no network functions as they are library specific based on hardware config, wifi/wired fills this gap with override functions
Most actions are in this class and you just call its functions to save code rewrite
The Top file should create an object from this, set it up and have a statemachine that defines how the thing unlocks/locks the thing
As each tool or door might have different behaviour then each one requires its own logic for when to unlock

8 changes: 8 additions & 0 deletions NewDoorController/data/Config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Thing_Name": "Door",
"UUID": "1A9E3D66-E90F-11E5-83C1-1E346D398B53",
"ThingControllerBoardRev" : 1,
"UnlockSeconds" : 5,
"ThingPin" : 8,
"ThingOnState" : 1
}
Binary file added NewDoorController/data/MS5050.bmp
Binary file not shown.
8 changes: 8 additions & 0 deletions NewDoorController/data/Network.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"NETWORK_SSID": "swindon-makerspace",
"NETWORK_PASSWORD": "makeallthethings",
"SERVER_HOST": "82.71.33.178",
"SERVER_PORT": 80,
"SERVER_URLPREFIX": "/accesssystem/",
"DeviceAddress": "192.168.1.200"
}z
31 changes: 31 additions & 0 deletions ThingControllerLibrary/ThingControllerBase/ReadMe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Readme for the thingcontroller Library

//How to setup
) Copy this folder "ThingControllerBase" into your arduino library
) For windows this in in Documents\Arduino\libraries

//Useage
) This library contains an object to instansiate called ThingControllerBase
) It is designed to run specifically on the Pi Pico 2040 Wifi or with Ethernet Controller
) To swap between Wifi and Wired you need to #define WIFIMODE or WIREDMODE in your program otherwise you will get compiling errors
) This Library is designed to cover the base functions that all controllers might need.
) Not all controllers will need every function but the majority like contacting the server and getting the response back is there
) The actual locking/unlocking rules of each "thing" is left to the user with the main script that calls this library

Supporting files
) This library relies on LittleFS to read in critical files regarding each thingcontrollers properties
) These must be stored in a folder called data in the project directory and use the old arduino software (1.8.X) with the littleFS plug in to flash to the pi pico
) This requires "flash size" under tools set to "2MB (Sketch: 1984KB, FS:64KB)"
) Required files - should be in github repo
) Config.json - properties like thing name, ID and pinout - thing specific
) Network.json - network settings (both wifi and wired) - should be common across things on the same network, should contain all settings for wifi and wired to make swapping easier
) MS5050.bmp - makerspace logo bitmap shown in corner

Required Libraries - newer version may work but listed version has been tested and known to work ok
) Adafruit GFX Library - 1.11.5
) Adafruit IL9341 - 1.5.12
) Wifi - installed when installing Pi Pico board manager
) Adafruit Neopixel - 1.11.0
) Adafruit PN532 - 1.2.3 - newer versions have issues right now - need to look into more
) ArduinoJson - 6.20.1
) littleFs - 2.6.0 @ https://github.com/earlephilhower/arduino-esp8266littlefs-plugin/releases
Loading