From 4ec433c7238da4f565e6c735a82ae412c251d120 Mon Sep 17 00:00:00 2001 From: user2684 Date: Sun, 13 May 2018 18:08:31 +0200 Subject: [PATCH] Add support for FPM10A fingerprint sensor (#360) --- NodeManager.ino | 3 ++ NodeManagerLibrary.h | 35 +++++++++++++ NodeManagerLibrary.ino | 114 ++++++++++++++++++++++++++++++++++++++++- README.md | 13 +++++ 4 files changed, 164 insertions(+), 1 deletion(-) diff --git a/NodeManager.ino b/NodeManager.ino index f05c9662..3b1ee752 100755 --- a/NodeManager.ino +++ b/NodeManager.ino @@ -97,6 +97,7 @@ SensorServo | 1 | USE_SERVO | Control a generic Servo SensorAPDS9960 | 1 | USE_APDS9960 | SparkFun RGB and Gesture Sensor | https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor SensorNeopixel | 1 | USE_NEOPIXEL | Control a Neopixel LED | https://github.com/adafruit/Adafruit_NeoPixel SensorSDS011 | 2 | USE_SDS011 | SDS011 air quality sensor, return concentrations of 2.5 and 10 micrometer particles. | https://github.com/ricki-z/SDS011 +SensorFPM10A | 1 | USE_FPM10A | FPM10A fingerprint sensor | https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library NodeManager provides useful built-in features which can be disabled if you need to save some storage for your code. To enable/disable a buil-in feature: @@ -289,6 +290,7 @@ FEATURE_HOOKING | OFF | allow custom code to be hooked in the ou //#define USE_APDS9960 //#define USE_NEOPIXEL //#define USE_SDS011 +//#define USE_FPM10A /*********************************** * NodeManager built-in features @@ -375,6 +377,7 @@ NodeManager node; //SensorAPDS9960 apds9960(node,3); //SensorNeopixel neopixel(node,6); //SensorSDS011 sds011(node,6,7); +//SensorFPM10A fpm10a(node,4,5); /*********************************** * Main Sketch diff --git a/NodeManagerLibrary.h b/NodeManagerLibrary.h index d26bc58c..d60ac1fe 100644 --- a/NodeManagerLibrary.h +++ b/NodeManagerLibrary.h @@ -255,6 +255,10 @@ #ifdef USE_SDS011 #include #endif +#ifdef USE_FPM10A + #include + #include +#endif // include third party libraries for enabled features #ifdef MY_GATEWAY_SERIAL @@ -1839,6 +1843,37 @@ class SensorNeopixel: public Sensor { }; #endif +/* + SensorFPM10A +*/ +#ifdef USE_FPM10A + class SensorFPM10A: public Sensor { + public: + SensorFPM10A(NodeManager& node_manager, int rxpin, int txpin, int child_id = -255); + // set the baud rate of the serial port for connecting to the sensor (default: 57600) + void setBaudRate(uint32_t value); + // set the password for connecting to the sensor (default: 0) + void setPassword(uint32_t value); + // [101] set the minimum confidence below which the match is not considered valid (default: 0) + void setMinConfidence(uint16_t value); + // [102] wait for a valid fingerprint for the given amount of seconds. Useful when battery powered (default: 0) + void setWaitFingerForSeconds(int value); + // define what to do at each stage of the sketch + void onSetup(); + void onLoop(Child* child); + protected: + Adafruit_Fingerprint* _finger; + SoftwareSerial* _serial; + int _rx_pin; + int _tx_pin; + Timer* _timer; + uint32_t _baud_rate = 57600; + uint32_t _password = 0; + uint16_t _min_confidence = 0; + int _readFingerprint(); + }; +#endif + /*************************************** NodeManager: manages all the aspects of the node */ diff --git a/NodeManagerLibrary.ino b/NodeManagerLibrary.ino index f4429e26..b4d331ad 100644 --- a/NodeManagerLibrary.ino +++ b/NodeManagerLibrary.ino @@ -4175,6 +4175,108 @@ void SensorSDS011::onReceive(MyMessage* message){ } #endif +/* + SensorFPM10A +*/ +#ifdef USE_FPM10A +SensorFPM10A::SensorFPM10A(NodeManager & node_manager, int rxpin, int txpin, int child_id): Sensor(node_manager, rxpin){ + _name = "FPM10A"; + _rx_pin = rxpin; + _tx_pin = txpin; + children.allocateBlocks(1); + new ChildInt(this, _node->getAvailableChildId(child_id), S_CUSTOM, V_CUSTOM, _name); + _timer = new Timer(_node); +} + +//setter/getter +// what to do during setup +void SensorFPM10A::setBaudRate(uint32_t value) { + _baud_rate = value; +} +void SensorFPM10A::setPassword(uint32_t value) { + _password = value; +} +void SensorFPM10A::setMinConfidence(uint16_t value) { + _min_confidence = value; +} +void SensorFPM10A::setWaitFingerForSeconds(int value) { + _timer->start(value,SECONDS); +} + +// what to do during setup +void SensorFPM10A::onSetup(){ + // setup software serial + _serial = new SoftwareSerial(_rx_pin,_tx_pin); + // setup fingerprint sensor + _finger = new Adafruit_Fingerprint(_serial,_password); + // connect to the sensor + _finger->begin(_baud_rate); + if (_finger->verifyPassword()) { + _finger->getTemplateCount(); + #if FEATURE_DEBUG == ON + Serial.print(_name); + Serial.print(F(" T=")); + Serial.println(_finger->templateCount); + #endif + } + else { + #if FEATURE_DEBUG == ON + Serial.print(_name); + Serial.println(F(" ERROR")); + #endif + } + // report immediately + _report_timer->unset(); +} + +// what to do during loop +void SensorFPM10A::onLoop(Child* child){ + // restart the timer if set + if (_timer->isRunning()) _timer->restart(); + while(true) { + if (_timer->isRunning()) { + // if a timer is set, leave the cycle if over + _timer->update(); + if (_timer->isOver()) break; + } + // read the fingerprint + int finger = _readFingerprint(); + if (finger > 0) { + // fingerprint match found, send the template ID back + ((ChildInt*)child)->setValueInt(finger); + // leave the loop so we can report back + break; + } + //don't need to run this at full speed + wait(50); + } +} + +// read the fingerprint from the sensor +int SensorFPM10A::_readFingerprint() { + // take image + uint8_t p = _finger->getImage(); + if (p != FINGERPRINT_OK) return -1; + // convert image + p = _finger->image2Tz(); + if (p != FINGERPRINT_OK) return -1; + // search for a fingerprint + p = _finger->fingerFastSearch(); + if (p != FINGERPRINT_OK) return -1; + // fingerprint found + #if FEATURE_DEBUG == ON + Serial.print(_name); + Serial.print(F(" T=")); + Serial.print(_finger->fingerID); + Serial.print(F(" C=")); + Serial.println(_finger->confidence); + #endif + // ignore the match if not confident enough + if (_finger->confidence < _min_confidence) return -1; + return _finger->fingerID; +} +#endif + #ifdef USE_CONFIGURATION /* SensorConfiguration @@ -4498,6 +4600,16 @@ void SensorConfiguration::onReceive(MyMessage* message) { } } #endif + #ifdef USE_FPM10A + if (strcmp(sensor->getName(),"FPM10A") == 0) { + SensorFPM10A* custom_sensor = (SensorFPM10A*)sensor; + switch(function) { + case 101: SensorFPM10A->setMinConfidence(request.getValueInt()); break; + case 102: SensorFPM10A->setWaitFingerForSeconds(request.getValueInt()); break; + default: return; + } + } + #endif } } _node->sendMessage(CONFIGURATION_CHILD_ID,V_CUSTOM,function); @@ -5089,7 +5201,7 @@ void NodeManager::_onInterrupt_2() { // send a message by providing the source child, type of the message and value void NodeManager::sendMessage(int child_id, int type, int value) { _message.clear(); - _message.set((uint32_t) value); + _message.set(value); _sendMessage(child_id,type); } void NodeManager::sendMessage(int child_id, int type, float value, int precision) { diff --git a/README.md b/README.md index 67b37799..57bfba4c 100755 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ SensorServo | 1 | USE_SERVO | Control a generic Servo SensorAPDS9960 | 1 | USE_APDS9960 | SparkFun RGB and Gesture Sensor | https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor SensorNeopixel | 1 | USE_NEOPIXEL | Control a Neopixel LED | https://github.com/adafruit/Adafruit_NeoPixel SensorSDS011 | 2 | USE_SDS011 | SDS011 air quality sensor, return concentrations of 2.5 and 10 micrometer particles. | https://github.com/ricki-z/SDS011 +SensorFPM10A | 1 | USE_FPM10A | FPM10A fingerprint sensor | https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library ### Built-in features @@ -748,6 +749,18 @@ Each sensor class exposes additional methods. void setColor(char* string); ~~~ +* SensorFPM10A +~~~c + // set the baud rate of the serial port for connecting to the sensor (default: 57600) + void setBaudRate(uint32_t value); + // set the password for connecting to the sensor (default: 0) + void setPassword(uint32_t value); + // [101] set the minimum confidence below which the match is not considered valid (default: 0) + void setMinConfidence(uint16_t value); + // [102] wait for a valid fingerprint for the given amount of seconds. Useful when battery powered (default: 0) + void setWaitFingerForSeconds(int value); +~~~ + ### Remote API If SensorConfiguration is added to NodeManager, the API can be also called remotely. SensorConfiguration exposes child id 200 that can be used to interact with the service by sending `V_CUSTOM` type of messages and commands within the payload. For each `REQ` message, the node will respond with a `SET` message if successful.