Improve Keypad reading (let the pullup some time to charge the keys before sampling)

--And improve documentation to not be dependant from external sources.
This commit is contained in:
Moirtz Wagner 2025-09-29 18:42:03 +02:00
parent 3c940cc6b6
commit 868d555681
7 changed files with 50 additions and 30 deletions

View File

@ -85,7 +85,7 @@ void Keypad::scanKeys() {
for (byte r=0; r<sizeKpd.rows; r++) { for (byte r=0; r<sizeKpd.rows; r++) {
pin_mode(rowPins[r],INPUT_PULLUP); pin_mode(rowPins[r],INPUT_PULLUP);
} }
delayMicroseconds(1); // Let pins settle.
// bitMap stores ALL the keys that are being pressed. // bitMap stores ALL the keys that are being pressed.
for (byte c=0; c<sizeKpd.columns; c++) { for (byte c=0; c<sizeKpd.columns; c++) {
pin_mode(columnPins[c],OUTPUT); pin_mode(columnPins[c],OUTPUT);

View File

@ -40,7 +40,7 @@ Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
enum class Mode { scan, enroll, wificonfig, maintenance, cooldown }; enum class Mode { scan, enroll, wificonfig, maintenance, cooldown };
const char* VersionInfo = "0.4"; const char* VersionInfo = "0.5";
// =================================================================================================================== // ===================================================================================================================
// Caution: below are not the credentials for connecting to your home network, they are for the Access Point mode!!! // Caution: below are not the credentials for connecting to your home network, they are for the Access Point mode!!!
@ -69,6 +69,8 @@ String logMessages[logMessagesCount]; // log messages, 0=most recent log message
bool shouldReboot = false; bool shouldReboot = false;
unsigned long wifiReconnectPreviousMillis = 0; unsigned long wifiReconnectPreviousMillis = 0;
unsigned long mqttReconnectPreviousMillis = 0; unsigned long mqttReconnectPreviousMillis = 0;
uint32_t sunrise = 0;
uint32_t sunset = 0;
String enrollId; String enrollId;
String enrollName; String enrollName;
@ -125,7 +127,7 @@ String getTimestampString(){
} }
char buffer[25]; char buffer[25];
strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S %Z", &timeinfo); strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S", &timeinfo);
String datetime = String(buffer); String datetime = String(buffer);
return datetime; return datetime;
} }
@ -266,7 +268,9 @@ bool initWifi() {
return false; return false;
} }
Serial.println("Connected!"); Serial.println("Connected!");
setenv("TZ", TZ_INFO, 1); // Zeitzone muss nach dem reset neu eingestellt werden
tzset();
configTzTime(TZ_INFO, settingsManager.getAppSettings().ntpServer.c_str(), "pool.ntp.org"); // ESP32 Systemzeit mit NTP Synchronisieren
// Print ESP32 Local IP Address // Print ESP32 Local IP Address
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
@ -505,9 +509,7 @@ void startWebserver(){
// Start server // Start server
webServer.begin(); webServer.begin();
// Init time by NTP Client // Init time by NTP Client
setenv("TZ", TZ_INFO, 1); // Zeitzone muss nach dem reset neu eingestellt werden
tzset();
configTzTime(TZ_INFO, settingsManager.getAppSettings().ntpServer.c_str()); // ESP32 Systemzeit mit NTP Synchronisieren
notifyClients("System booted successfully!"); notifyClients("System booted successfully!");
} }
@ -611,18 +613,22 @@ void timeBellRing(uint8_t _state){
switch(_state){ switch(_state){
case 1: case 1:
io.digitalWrite(doorbellOutputPin, HIGH); io.digitalWrite(doorbellOutputPin, HIGH);
ringBellTick.once(0.3,timeBellRing,(uint8_t) 2); //switch back off after one second io.digitalWrite(buzzerOutputPin, HIGH);
ringBellTick.once(0.2,timeBellRing,(uint8_t) 2); //switch back off after one second
break; break;
case 2: case 2:
io.digitalWrite(doorbellOutputPin, LOW); io.digitalWrite(doorbellOutputPin, LOW);
io.digitalWrite(buzzerOutputPin, LOW);
ringBellTick.once(0.5,timeBellRing,(uint8_t) 3); //switch back off after one second ringBellTick.once(0.5,timeBellRing,(uint8_t) 3); //switch back off after one second
break; break;
case 3: case 3:
io.digitalWrite(doorbellOutputPin, HIGH); io.digitalWrite(doorbellOutputPin, HIGH);
ringBellTick.once(0.3,timeBellRing,(uint8_t) 4); //switch back off after one second io.digitalWrite(buzzerOutputPin, HIGH);
ringBellTick.once(0.2,timeBellRing,(uint8_t) 4); //switch back off after one second
break; break;
case 4: case 4:
io.digitalWrite(doorbellOutputPin, LOW); io.digitalWrite(doorbellOutputPin, LOW);
io.digitalWrite(buzzerOutputPin, LOW);
break; break;
} }
@ -814,6 +820,24 @@ void keyboardPoller(void){
} }
} }
void checkForNight(void){
bool night = true;
tm timeinfo;
if(getLocalTime(&timeinfo)){
if(timeinfo.tm_min + timeinfo.tm_hour*60 > sunrise && timeinfo.tm_min + timeinfo.tm_hour*60 < sunset){
night = false;
mqttClient.publish((String(settingsManager.getAppSettings().mqttRootTopic) + "/night").c_str(), "false",true);
}else{
night = true;
mqttClient.publish((String(settingsManager.getAppSettings().mqttRootTopic) + "/night").c_str(), "true",true);
}
fingerManager.setNightMode(night);
}else{
mqttClient.publish((String(settingsManager.getAppSettings().mqttRootTopic) + "/night").c_str(), "N/A",true);
fingerManager.setNightMode(true);
}
}
void setup() void setup()
{ {
@ -936,9 +960,7 @@ void setup()
} }
unsigned long lastSunsetCkeck = 0, lastNightCheck = 0; unsigned long lastSunsetCkeck = 0, lastNightCheck = 0;
bool night = true;
uint32_t sunrise = 0;
uint32_t sunset = 0;
void loop() void loop()
{ {
unsigned long currentMillis = millis(); unsigned long currentMillis = millis();
@ -959,19 +981,12 @@ void loop()
mqttClient.publish((String(settingsManager.getAppSettings().mqttRootTopic) + "/sunset").c_str(), buff,true); mqttClient.publish((String(settingsManager.getAppSettings().mqttRootTopic) + "/sunset").c_str(), buff,true);
} }
} }
if(currentMillis - lastNightCheck > 10*60*1000){ //check every 10 minutes if(currentMillis - lastNightCheck > 10*60*1000 || lastNightCheck == 0){ //check every 10 minutes
lastNightCheck = currentMillis; if(!WiFi.isConnected() && currentMode != Mode::wificonfig && lastNightCheck != 0) {
tm timeinfo; shouldReboot = true;
if(getLocalTime(&timeinfo)){
if(timeinfo.tm_min + timeinfo.tm_hour*60 > sunrise && timeinfo.tm_min + timeinfo.tm_hour*60 < sunset){
night = false;
}else{
night = true;
}
fingerManager.setNightMode(night);
}else{
fingerManager.setNightMode(true);
} }
lastNightCheck = currentMillis;
checkForNight();
} }
// Reconnect handling // Reconnect handling
@ -1001,7 +1016,10 @@ void loop()
{ {
case Mode::cooldown: case Mode::cooldown:
if(openingDoor){ if(openingDoor){
io.digitalWrite(buzzerOutputPin, HIGH);
fingerManager.setLedRingOk(); fingerManager.setLedRingOk();
delay(300);
io.digitalWrite(buzzerOutputPin, LOW);
openingDoor = false; openingDoor = false;
} }
break; break;

View File

@ -6,9 +6,9 @@ Dieses Projekt nutzt einen **ESP32C3 Super Mini**, einen **R503 Fingerabdrucksen
## 📦 Komponenten ## 📦 Komponenten
- [ESP32-C3 Super Mini Board](https://de.aliexpress.com/item/1005005097410991.html) - [ESP32-C3 Super Mini Board (Aliexpress EstarDyn)](https://de.aliexpress.com/item/1005007446928015.html?spm=a2g0o.order_list.order_list_main.49.48d35c5fCRylRE&gatewayAdapt=glo2deu)
- [R503 Fingerabdrucksensor](https://datasheet.lcsc.com/lcsc/1811141221_FPM-Fingerprint-R503_C83050.pdf) - [R503 Fingerabdrucksensor ](https://datasheet.lcsc.com/lcsc/1811141221_FPM-Fingerprint-R503_C83050.pdf)
- [3x4 Matrix Keypad (Tastenfeld)](https://www.handsontec.com/dataspecs/module/Keypad%203x4.pdf) - [3x4 Matrix Keypad (Tastenfeld Aliexpress EstarDyn)](https://de.aliexpress.com/item/1005007728795501.html?spm=a2g0o.order_list.order_list_main.50.1c895c5fVEI011&gatewayAdapt=glo2deu)
- Jumper-Kabel, Stromversorgung (5V oder USB), Gehäuse etc. - Jumper-Kabel, Stromversorgung (5V oder USB), Gehäuse etc.
--- ---
@ -64,11 +64,13 @@ Dieses Projekt nutzt einen **ESP32C3 Super Mini**, einen **R503 Fingerabdrucksen
| bell | GPIO10 | Glocke innen | | bell | GPIO10 | Glocke innen |
--- ---
## 📸 ESP32C3 Super Mini Pinout ## 📸 Pinouts und Datenblätter
![ESP32C3 Super Mini Pinout](https://github.com/SENTHILRAJ-K/ESP32-C3-SuperMini/raw/main/images/esp32-c3-supermini-pinout.png) ![ESP32C3 Super Mini Pinout](https://gitea.nas.el-wa.org/admin/Doorbell/src/branch/main/doku/azci_esp32-c3-super-mini-pinout.jpg)
Quelle: [SENTHILRAJ-K/ESP32-C3-SuperMini (GitHub)](https://github.com/SENTHILRAJ-K/ESP32-C3-SuperMini) ![Keypad Pinout](https://gitea.nas.el-wa.org/admin/Doorbell/src/branch/main/doku/raspberry_pi_PID3845_pinout.jpg)
[R503 Datasheet](https://gitea.nas.el-wa.org/admin/Doorbell/src/branch/main/doku/R503_datasheet.pdf)
--- ---

BIN
doku/R503_datasheet.pdf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB