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.sensorPairingCode = preferences.getString("pairingCode", "");
|
||||
appSettings.sensorPairingValid = preferences.getBool("pairingValid", false);
|
||||
appSettings.chosenPin = preferences.getString("chosenPin", "123456");
|
||||
preferences.end();
|
||||
return true;
|
||||
} else {
|
||||
@ -52,6 +53,7 @@ void SettingsManager::saveAppSettings() {
|
||||
preferences.putString("sensorPin", appSettings.sensorPin);
|
||||
preferences.putString("pairingCode", appSettings.sensorPairingCode);
|
||||
preferences.putBool("pairingValid", appSettings.sensorPairingValid);
|
||||
preferences.putString("chosenPin", appSettings.chosenPin);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ struct AppSettings {
|
||||
String ntpServer = "pool.ntp.org";
|
||||
String sensorPin = "00000000";
|
||||
String sensorPairingCode = "";
|
||||
String chosenPin = "123456";
|
||||
bool sensorPairingValid = false;
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/***************************************************
|
||||
Main of FingerprintDoorbell
|
||||
****************************************************/
|
||||
|
||||
#define MQTT_SOCKET_TIMEOUT 2
|
||||
#include <WiFi.h>
|
||||
#include <DNSServer.h>
|
||||
#include <time.h>
|
||||
@ -12,8 +12,9 @@
|
||||
#include "FingerprintManager.h"
|
||||
#include "SettingsManager.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";
|
||||
|
||||
@ -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 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 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
|
||||
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
|
||||
@ -51,6 +55,11 @@ FingerprintManager fingerManager;
|
||||
SettingsManager settingsManager;
|
||||
bool needMaintenanceMode = false;
|
||||
|
||||
Ticker keyboardTick;
|
||||
Ticker openDoorTick;
|
||||
Ticker ringBellTick;
|
||||
Ticker cooldownTick;
|
||||
|
||||
const byte DNS_PORT = 53;
|
||||
DNSServer dnsServer;
|
||||
AsyncWebServer webServer(80); // AsyncWebServer on port 80
|
||||
@ -66,6 +75,9 @@ bool mqttConfigValid = true;
|
||||
|
||||
Match lastMatch;
|
||||
|
||||
void timeDoorOpener(uint8_t _state = HIGH);
|
||||
void timeBellRing(uint8_t _state= HIGH);
|
||||
|
||||
void addLogMessage(const String& message) {
|
||||
// shift all messages in array by 1, oldest message will die
|
||||
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()
|
||||
{
|
||||
@ -566,43 +617,31 @@ void doScan()
|
||||
// standard case, occurs every iteration when no finger touchs the sensor
|
||||
if (match.scanResult != lastMatch.scanResult) {
|
||||
Serial.println("no finger");
|
||||
if(mqttClient.connected()){
|
||||
mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "off");
|
||||
mqttClient.publish((String(mqttRootTopic) + "/matchId").c_str(), "-1");
|
||||
mqttClient.publish((String(mqttRootTopic) + "/matchName").c_str(), "");
|
||||
mqttClient.publish((String(mqttRootTopic) + "/matchConfidence").c_str(), "-1");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ScanResult::matchFound:
|
||||
notifyClients( String("Match Found: ") + match.matchId + " - " + match.matchName + " with confidence of " + match.matchConfidence );
|
||||
if (match.scanResult != lastMatch.scanResult) {
|
||||
if (checkPairingValid()) {
|
||||
digitalWrite(doorOpenerOutputPin, HIGH);
|
||||
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);
|
||||
openDoor(match);
|
||||
} 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.");
|
||||
}
|
||||
}
|
||||
delay(3000); // wait some time before next scan to let the LED blink
|
||||
setCooldown(4000);
|
||||
break;
|
||||
case ScanResult::noMatchFound:
|
||||
notifyClients(String("No Match Found (Code ") + match.returnCode + ")");
|
||||
if (match.scanResult != lastMatch.scanResult) {
|
||||
digitalWrite(doorbellOutputPin, HIGH);
|
||||
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);
|
||||
ringBell();
|
||||
} 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;
|
||||
case ScanResult::error:
|
||||
@ -634,6 +673,7 @@ void doEnroll()
|
||||
|
||||
void reboot()
|
||||
{
|
||||
digitalWrite(doorOpenerOutputPin, LOW);
|
||||
notifyClients("System is rebooting now...");
|
||||
delay(1000);
|
||||
|
||||
@ -645,10 +685,83 @@ void reboot()
|
||||
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()
|
||||
{
|
||||
keyboardTick.attach_ms(KEY_POLLING_MS,keyboardPoller);
|
||||
// open serial monitor for debug infos
|
||||
pinMode(4,ANALOG);
|
||||
pinMode(doorOpenerOutputPin,OUTPUT);
|
||||
Serial.begin(115200);
|
||||
//while (!Serial); // For Yun/Leo/Micro/Zero/...
|
||||
//delay(2000);
|
||||
@ -709,7 +822,7 @@ void setup()
|
||||
fingerManager.setLedRingError();
|
||||
} else {
|
||||
fingerManager.setLedRingError();
|
||||
shouldReboot = true;
|
||||
//shouldReboot = true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -724,6 +837,7 @@ void loop()
|
||||
reboot();
|
||||
}
|
||||
|
||||
|
||||
// Reconnect handling
|
||||
if (currentMode != Mode::wificonfig)
|
||||
{
|
||||
@ -750,6 +864,9 @@ void loop()
|
||||
// do the actual loop work
|
||||
switch (currentMode)
|
||||
{
|
||||
case Mode::cooldown:
|
||||
|
||||
break;
|
||||
case Mode::scan:
|
||||
if (fingerManager.connected)
|
||||
doScan();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user