Added analog keypad function @TODO: configuration of the Pin on Website.
Changed some delay behaviour in favor to Ticker async procedures.
This commit is contained in:
parent
f2145f98b6
commit
6435550e29
@ -25,6 +25,7 @@ bool SettingsManager::loadAppSettings() {
|
|||||||
appSettings.sensorPin = preferences.getString("sensorPin", "00000000");
|
appSettings.sensorPin = preferences.getString("sensorPin", "00000000");
|
||||||
appSettings.sensorPairingCode = preferences.getString("pairingCode", "");
|
appSettings.sensorPairingCode = preferences.getString("pairingCode", "");
|
||||||
appSettings.sensorPairingValid = preferences.getBool("pairingValid", false);
|
appSettings.sensorPairingValid = preferences.getBool("pairingValid", false);
|
||||||
|
appSettings.chosenPin = preferences.getString("chosenPin", "123456");
|
||||||
preferences.end();
|
preferences.end();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -52,6 +53,7 @@ void SettingsManager::saveAppSettings() {
|
|||||||
preferences.putString("sensorPin", appSettings.sensorPin);
|
preferences.putString("sensorPin", appSettings.sensorPin);
|
||||||
preferences.putString("pairingCode", appSettings.sensorPairingCode);
|
preferences.putString("pairingCode", appSettings.sensorPairingCode);
|
||||||
preferences.putBool("pairingValid", appSettings.sensorPairingValid);
|
preferences.putBool("pairingValid", appSettings.sensorPairingValid);
|
||||||
|
preferences.putString("chosenPin", appSettings.chosenPin);
|
||||||
preferences.end();
|
preferences.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ struct AppSettings {
|
|||||||
String ntpServer = "pool.ntp.org";
|
String ntpServer = "pool.ntp.org";
|
||||||
String sensorPin = "00000000";
|
String sensorPin = "00000000";
|
||||||
String sensorPairingCode = "";
|
String sensorPairingCode = "";
|
||||||
|
String chosenPin = "123456";
|
||||||
bool sensorPairingValid = false;
|
bool sensorPairingValid = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/***************************************************
|
/***************************************************
|
||||||
Main of FingerprintDoorbell
|
Main of FingerprintDoorbell
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
#define MQTT_SOCKET_TIMEOUT 2
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -12,8 +12,9 @@
|
|||||||
#include "FingerprintManager.h"
|
#include "FingerprintManager.h"
|
||||||
#include "SettingsManager.h"
|
#include "SettingsManager.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "Ticker.h"
|
||||||
|
|
||||||
enum class Mode { scan, enroll, wificonfig, maintenance };
|
enum class Mode { scan, enroll, wificonfig, maintenance, cooldown };
|
||||||
|
|
||||||
const char* VersionInfo = "0.4";
|
const char* VersionInfo = "0.4";
|
||||||
|
|
||||||
@ -27,7 +28,10 @@ IPAddress WifiConfigIp(192, 168, 4, 1); // IP of access point in wifi config m
|
|||||||
const long gmtOffset_sec = 0; // UTC Time
|
const long gmtOffset_sec = 0; // UTC Time
|
||||||
const int daylightOffset_sec = 0; // UTC Time
|
const int daylightOffset_sec = 0; // UTC Time
|
||||||
const int doorbellOutputPin = 5; // pin connected to the doorbell (when using hardware connection instead of mqtt to ring the bell)
|
const int doorbellOutputPin = 5; // pin connected to the doorbell (when using hardware connection instead of mqtt to ring the bell)
|
||||||
const int doorOpenerOutputPin = 6; // pin connected to the door opener (when using hardware connection instead of mqtt to open the door)
|
const int doorOpenerOutputPin = 8; //USE 6 HERE pin connected to the door opener (when using hardware connection instead of mqtt to open the door)
|
||||||
|
const int KeyboardPin = 4; //pin connected to an analog keyboard (see voltage ranges for the nubers in seperate array)
|
||||||
|
const int KEY_POLLING_MS = 25;
|
||||||
|
const uint8_t NUM_PIN_DIGITS = {6};
|
||||||
#ifdef CUSTOM_GPIOS
|
#ifdef CUSTOM_GPIOS
|
||||||
const int customOutput1 = 18; // not used internally, but can be set over MQTT
|
const int customOutput1 = 18; // not used internally, but can be set over MQTT
|
||||||
const int customOutput2 = 26; // not used internally, but can be set over MQTT
|
const int customOutput2 = 26; // not used internally, but can be set over MQTT
|
||||||
@ -51,6 +55,11 @@ FingerprintManager fingerManager;
|
|||||||
SettingsManager settingsManager;
|
SettingsManager settingsManager;
|
||||||
bool needMaintenanceMode = false;
|
bool needMaintenanceMode = false;
|
||||||
|
|
||||||
|
Ticker keyboardTick;
|
||||||
|
Ticker openDoorTick;
|
||||||
|
Ticker ringBellTick;
|
||||||
|
Ticker cooldownTick;
|
||||||
|
|
||||||
const byte DNS_PORT = 53;
|
const byte DNS_PORT = 53;
|
||||||
DNSServer dnsServer;
|
DNSServer dnsServer;
|
||||||
AsyncWebServer webServer(80); // AsyncWebServer on port 80
|
AsyncWebServer webServer(80); // AsyncWebServer on port 80
|
||||||
@ -66,6 +75,9 @@ bool mqttConfigValid = true;
|
|||||||
|
|
||||||
Match lastMatch;
|
Match lastMatch;
|
||||||
|
|
||||||
|
void timeDoorOpener(uint8_t _state = HIGH);
|
||||||
|
void timeBellRing(uint8_t _state= HIGH);
|
||||||
|
|
||||||
void addLogMessage(const String& message) {
|
void addLogMessage(const String& message) {
|
||||||
// shift all messages in array by 1, oldest message will die
|
// shift all messages in array by 1, oldest message will die
|
||||||
for (int i=logMessagesCount-1; i>0; i--)
|
for (int i=logMessagesCount-1; i>0; i--)
|
||||||
@ -555,6 +567,45 @@ void connectMqttClient() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void timeDoorOpener(uint8_t _state){
|
||||||
|
digitalWrite(doorOpenerOutputPin, _state);
|
||||||
|
openDoorTick.once(1,timeDoorOpener,(uint8_t) LOW); //switch back off after one second
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeBellRing(uint8_t _state){
|
||||||
|
digitalWrite(doorbellOutputPin, _state);
|
||||||
|
ringBellTick.once(1,timeBellRing,(uint8_t) LOW); //switch back off after one second
|
||||||
|
}
|
||||||
|
|
||||||
|
void openDoor(Match _match){
|
||||||
|
String mqttRootTopic = settingsManager.getAppSettings().mqttRootTopic;
|
||||||
|
timeDoorOpener();
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "off");
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), String(_match.matchId).c_str());
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), _match.matchName.c_str());
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), String(_match.matchConfidence).c_str());
|
||||||
|
Serial.println("MQTT message sent: Open the door!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ringBell(void){
|
||||||
|
String mqttRootTopic = settingsManager.getAppSettings().mqttRootTopic;
|
||||||
|
timeBellRing();
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "on");
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), "-1");
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), "");
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), "-1");
|
||||||
|
Serial.println("MQTT message sent: ring the bell!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void continueScanMode(void){
|
||||||
|
currentMode = Mode::scan;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCooldown(uint16_t time){
|
||||||
|
currentMode = Mode::cooldown;
|
||||||
|
cooldownTick.once_ms(time,continueScanMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void doScan()
|
void doScan()
|
||||||
{
|
{
|
||||||
@ -566,43 +617,31 @@ void doScan()
|
|||||||
// standard case, occurs every iteration when no finger touchs the sensor
|
// standard case, occurs every iteration when no finger touchs the sensor
|
||||||
if (match.scanResult != lastMatch.scanResult) {
|
if (match.scanResult != lastMatch.scanResult) {
|
||||||
Serial.println("no finger");
|
Serial.println("no finger");
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "off");
|
if(mqttClient.connected()){
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), "-1");
|
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "off");
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), "");
|
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), "-1");
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), "-1");
|
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), "");
|
||||||
|
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), "-1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ScanResult::matchFound:
|
case ScanResult::matchFound:
|
||||||
notifyClients( String("Match Found: ") + match.matchId + " - " + match.matchName + " with confidence of " + match.matchConfidence );
|
notifyClients( String("Match Found: ") + match.matchId + " - " + match.matchName + " with confidence of " + match.matchConfidence );
|
||||||
if (match.scanResult != lastMatch.scanResult) {
|
if (match.scanResult != lastMatch.scanResult) {
|
||||||
if (checkPairingValid()) {
|
if (checkPairingValid()) {
|
||||||
digitalWrite(doorOpenerOutputPin, HIGH);
|
openDoor(match);
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "off");
|
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), String(match.matchId).c_str());
|
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), match.matchName.c_str());
|
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), String(match.matchConfidence).c_str());
|
|
||||||
Serial.println("MQTT message sent: Open the door!");
|
|
||||||
delay(1000);
|
|
||||||
digitalWrite(doorOpenerOutputPin, LOW);
|
|
||||||
} else {
|
} else {
|
||||||
notifyClients("Security issue! Match was not sent by MQTT because of invalid sensor pairing! This could potentially be an attack! If the sensor is new or has been replaced by you do a (re)pairing in settings page.");
|
notifyClients("Security issue! Match was not sent by MQTT because of invalid sensor pairing! This could potentially be an attack! If the sensor is new or has been replaced by you do a (re)pairing in settings page.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delay(3000); // wait some time before next scan to let the LED blink
|
setCooldown(4000);
|
||||||
break;
|
break;
|
||||||
case ScanResult::noMatchFound:
|
case ScanResult::noMatchFound:
|
||||||
notifyClients(String("No Match Found (Code ") + match.returnCode + ")");
|
notifyClients(String("No Match Found (Code ") + match.returnCode + ")");
|
||||||
if (match.scanResult != lastMatch.scanResult) {
|
if (match.scanResult != lastMatch.scanResult) {
|
||||||
digitalWrite(doorbellOutputPin, HIGH);
|
ringBell();
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "on");
|
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), "-1");
|
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), "");
|
|
||||||
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), "-1");
|
|
||||||
Serial.println("MQTT message sent: ring the bell!");
|
|
||||||
delay(1000);
|
|
||||||
digitalWrite(doorbellOutputPin, LOW);
|
|
||||||
} else {
|
} else {
|
||||||
delay(1000); // wait some time before next scan to let the LED blink
|
setCooldown(4000); // wait some time before next scan to let the LED blink
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ScanResult::error:
|
case ScanResult::error:
|
||||||
@ -634,6 +673,7 @@ void doEnroll()
|
|||||||
|
|
||||||
void reboot()
|
void reboot()
|
||||||
{
|
{
|
||||||
|
digitalWrite(doorOpenerOutputPin, LOW);
|
||||||
notifyClients("System is rebooting now...");
|
notifyClients("System is rebooting now...");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
@ -645,10 +685,83 @@ void reboot()
|
|||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void keyboardPoller(void){
|
||||||
|
uint8_t key = 99;
|
||||||
|
static uint8_t lastKey = 99, lastlastKey = 99, pinpos = 0, resetTimer = 0;
|
||||||
|
static uint8_t pin[NUM_PIN_DIGITS] = {0};
|
||||||
|
bool pinOK = true;
|
||||||
|
uint16_t keyVal = analogRead(KeyboardPin);
|
||||||
|
if(keyVal < 15)
|
||||||
|
key = 3;
|
||||||
|
else if(keyVal < 55)
|
||||||
|
key = 6;
|
||||||
|
else if(keyVal < 110)
|
||||||
|
key = 9;
|
||||||
|
else if(keyVal < 200)
|
||||||
|
key = 10;
|
||||||
|
else if(keyVal < 300)
|
||||||
|
key = 2;
|
||||||
|
else if(keyVal < 400)
|
||||||
|
key = 5;
|
||||||
|
else if(keyVal < 500)
|
||||||
|
key = 8;
|
||||||
|
else if(keyVal < 700)
|
||||||
|
key = 0;
|
||||||
|
else if(keyVal < 900)
|
||||||
|
key = 1;
|
||||||
|
else if(keyVal < 1300)
|
||||||
|
key = 4;
|
||||||
|
else if(keyVal < 1800)
|
||||||
|
key = 7;
|
||||||
|
else if(keyVal < 2600)
|
||||||
|
key = 11;
|
||||||
|
|
||||||
|
if(key == 99 && lastKey != key && lastlastKey == lastKey){ //take the second last pressed value that was read before keyboard was released.
|
||||||
|
Serial.print("Keyboard: ");
|
||||||
|
Serial.println(lastKey);
|
||||||
|
resetTimer = 0;
|
||||||
|
pin[pinpos++] = lastKey;
|
||||||
|
}
|
||||||
|
if(pinpos){
|
||||||
|
resetTimer++;
|
||||||
|
if(resetTimer > 4000/KEY_POLLING_MS){
|
||||||
|
resetTimer = 0;
|
||||||
|
pinpos = 0;
|
||||||
|
Serial.println("RESET");
|
||||||
|
}
|
||||||
|
if(pinpos == NUM_PIN_DIGITS){
|
||||||
|
pinpos = 0;
|
||||||
|
resetTimer = 0;
|
||||||
|
String PinStr = settingsManager.getAppSettings().chosenPin;
|
||||||
|
uint8_t chosenPin[NUM_PIN_DIGITS];
|
||||||
|
|
||||||
|
for(uint8_t i=0;i< NUM_PIN_DIGITS;i++){
|
||||||
|
uint8_t coosenPinDigit = PinStr.charAt(i)-0x30;
|
||||||
|
if(pin[i] != coosenPinDigit){
|
||||||
|
pinOK= false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pinOK){
|
||||||
|
Serial.println("OPEN!!");
|
||||||
|
Match match;
|
||||||
|
match.matchName = "KEYPAD";
|
||||||
|
openDoor(match);
|
||||||
|
}else{
|
||||||
|
Serial.println("WRONG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastlastKey = lastKey;
|
||||||
|
lastKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
keyboardTick.attach_ms(KEY_POLLING_MS,keyboardPoller);
|
||||||
// open serial monitor for debug infos
|
// open serial monitor for debug infos
|
||||||
|
pinMode(4,ANALOG);
|
||||||
|
pinMode(doorOpenerOutputPin,OUTPUT);
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
//while (!Serial); // For Yun/Leo/Micro/Zero/...
|
//while (!Serial); // For Yun/Leo/Micro/Zero/...
|
||||||
//delay(2000);
|
//delay(2000);
|
||||||
@ -709,7 +822,7 @@ void setup()
|
|||||||
fingerManager.setLedRingError();
|
fingerManager.setLedRingError();
|
||||||
} else {
|
} else {
|
||||||
fingerManager.setLedRingError();
|
fingerManager.setLedRingError();
|
||||||
shouldReboot = true;
|
//shouldReboot = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -724,6 +837,7 @@ void loop()
|
|||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reconnect handling
|
// Reconnect handling
|
||||||
if (currentMode != Mode::wificonfig)
|
if (currentMode != Mode::wificonfig)
|
||||||
{
|
{
|
||||||
@ -750,6 +864,9 @@ void loop()
|
|||||||
// do the actual loop work
|
// do the actual loop work
|
||||||
switch (currentMode)
|
switch (currentMode)
|
||||||
{
|
{
|
||||||
|
case Mode::cooldown:
|
||||||
|
|
||||||
|
break;
|
||||||
case Mode::scan:
|
case Mode::scan:
|
||||||
if (fingerManager.connected)
|
if (fingerManager.connected)
|
||||||
doScan();
|
doScan();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user