Skip to content

Commit

Permalink
Add support for FPM10A fingerprint sensor (mysensors#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
user2684 authored May 13, 2018
1 parent a054cf0 commit 4ec433c
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 1 deletion.
3 changes: 3 additions & 0 deletions NodeManager.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions NodeManagerLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@
#ifdef USE_SDS011
#include <SDS011.h>
#endif
#ifdef USE_FPM10A
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
#endif

// include third party libraries for enabled features
#ifdef MY_GATEWAY_SERIAL
Expand Down Expand Up @@ -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
*/
Expand Down
114 changes: 113 additions & 1 deletion NodeManagerLibrary.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 4ec433c

Please sign in to comment.