Skip to content

Commit 5bb2ce1

Browse files
authored
Support for PN532 NFC RFID module
1 parent f574dfb commit 5bb2ce1

File tree

6 files changed

+136
-4
lines changed

6 files changed

+136
-4
lines changed

.travis.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,4 +481,12 @@ jobs:
481481
- sed -r -i 's/\/\/(SensorDSM501A .+)/\1/' $SKETCH
482482
- sed -r -i 's/\/\/(#include <sensors\/SensorDSM501A.h>)/\1/' $SKETCH
483483
- eval $OTA_CONFIGURATION
484-
- eval $COMPILE
484+
- eval $COMPILE
485+
- name: "SensorPN532"
486+
script:
487+
- wget https://github.com/elechouse/PN532/archive/PN532_HSU.zip && unzip PN532_HSU.zip
488+
- sudo cp -r PN532-PN532_HSU/* /usr/local/share/arduino/libraries
489+
- sed -r -i 's/\/\/(SensorPN532 .+)/\1/' $SKETCH
490+
- sed -r -i 's/\/\/(#include <sensors\/SensorPN532.h>)/\1/' $SKETCH
491+
- eval $OTA_CONFIGURATION
492+
- eval $COMPILE

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ SensorPH | 1 | PH ( SKU SEN161 ) sensor, measure the analog
147147
SensorPca9685W | 2 | Generic dimmer sensor (S_DIMMER) used to drive a single channel pwm output of PCA9685 | https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
148148
SensorPca9685Rgb | 2 | Generic RGB-dimmer sensor (S_RGB_LIGHT) used to drive RGB resp. 3-channel pwm output of PCA9685 | https://github.com/adafruit/Adafruit-PWM-Servo- Driver-Library
149149
SensorPca9685Rgbw | 2 | Generic RGBW-dimmer sensor (S_RGBW_LIGHT) used to drive RGBW resp. 4-channel pwm output of PCA9685| https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
150-
SensorDSM501A | 1 | ust sensor module DSM501A for PM1.0 and PM2.5 particles | -
150+
SensorDSM501A | 1 | Dust sensor module DSM501A for PM1.0 and PM2.5 particles | -
151+
SensorPN532 | 1 | PN532 NFC RFID Module | https://github.com/elechouse/PN532
151152

152153
Those sensors requiring a pin to operate would take it as an argument in the constructor.
153154
NodeManager automatically creates all the child_ids, assigning an incremental counter. If you need to set your own child_id, pass it as the last argument to the constructor
@@ -946,6 +947,14 @@ Each sensor class may expose additional methods.
946947
void setTemperature(int value);
947948
~~~
948949
950+
* SensorPN532
951+
~~~c
952+
// [101] wait for a valid card for the given amount of seconds. Useful when battery powered (default: 0)
953+
void setWaitCardForSeconds(int value);
954+
// return true if the card was recognized successfully, false otherwise. Useful when a hook function needs to act upon the result
955+
bool getCardIsValid();
956+
~~~
957+
949958
### OTA Configuration
950959

951960
When `NODEMANAGER_OTA_CONFIGURATION` is set to ON the API presented above can be also called remotely through `SensorConfiguration`, which is automatically added to NodeManager. SensorConfiguration exposes by default 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.

examples/Template/Template.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,9 @@ NodeManager. Just uncomment the settings you need and the sensors you want to ad
358358
//#include <sensors/SensorDSM501A.h>
359359
//SensorDSM501A DSM501A;
360360

361+
//#include <sensors/SensorPN532.h>
362+
//SensorPN532 pn532;
363+
361364
/***********************************
362365
* Main Sketch
363366
*/

keywords.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,5 @@ SensorPH KEYWORD1
215215
SensorPca9685Rgb KEYWORD1
216216
SensorPca9685Rgbw KEYWORD1
217217
SensorPca9685W KEYWORD1
218-
SensorDSM501A KEYWORD1
218+
SensorDSM501A KEYWORD1
219+
SensorPN532 KEYWORD1

nodemanager/Child.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ void Child::setValue(double value) {
9898
}
9999
void Child::setValue(const char* value) {
100100
_value_string = value;
101+
_samples = 1;
102+
debug(PSTR(LOG_LOOP "%s(%d):SET t=%d v=%s\n"),_description,_child_id,_type,_value_string);
101103
}
102104

103105
// store a new value and update the total
@@ -194,8 +196,8 @@ void Child::reset() {
194196
if (_persist_value) saveValue();
195197
#endif
196198
}
197-
_samples = 0;
198199
} else _value_string = "";
200+
_samples = 0;
199201
}
200202

201203
#if NODEMANAGER_CONDITIONAL_REPORT == ON

sensors/SensorPN532.h

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* The MySensors Arduino library handles the wireless radio link and protocol
3+
* between your home built sensors/actuators and HA controller of choice.
4+
* The sensors forms a self healing radio network with optional repeaters. Each
5+
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
6+
* network topology allowing messages to be routed to nodes.
7+
*
8+
* Created by Henrik Ekblad <[email protected]>
9+
* Copyright (C) 2013-2017 Sensnology AB
10+
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
11+
*
12+
* Documentation: http://www.mysensors.org
13+
* Support Forum: http://forum.mysensors.org
14+
*
15+
* This program is free software; you can redistribute it and/or
16+
* modify it under the terms of the GNU General Public License
17+
* version 2 as published by the Free Software Foundation.
18+
*/
19+
#ifndef SensorPN532_h
20+
#define SensorPN532_h
21+
22+
/*
23+
SensorPN532
24+
*/
25+
26+
#include <Wire.h>
27+
#include <PN532_I2C.h>
28+
#include <PN532.h>
29+
#include <NfcAdapter.h>
30+
31+
class SensorPN532: public Sensor {
32+
protected:
33+
PN532_I2C* _pn532i2c = new PN532_I2C(Wire);
34+
PN532* _nfc = new PN532(*_pn532i2c);
35+
bool _card_is_valid = false;
36+
int _wait_card_for_seconds = 0;
37+
38+
public:
39+
SensorPN532(uint8_t child_id = 0): Sensor(-1) {
40+
_name = "PN532";
41+
children.allocateBlocks(1);
42+
new Child(this,STRING,nodeManager.getAvailableChildId(child_id), S_CUSTOM, V_CUSTOM, _name);
43+
};
44+
45+
// [101] wait for a valid card for the given amount of seconds. Useful when battery powered (default: 0)
46+
void setWaitCardForSeconds(int value) {
47+
_wait_card_for_seconds = value;
48+
};
49+
50+
// return true if the card was recognized successfully, false otherwise. Useful when a hook function needs to act upon the result
51+
bool getCardIsValid() {
52+
return _card_is_valid;
53+
};
54+
55+
// define what to do during setup
56+
void onSetup() {
57+
// initialize the library
58+
_nfc->begin();
59+
uint32_t versiondata = _nfc->getFirmwareVersion();
60+
if (! versiondata) debug(PSTR(LOG_SENSOR "KO\n"));
61+
else debug(PSTR(LOG_LOOP "PN5%x v=%d.%d\n"),(versiondata>>24) & 0xFF,(versiondata>>16) & 0xFF,(versiondata>>8) & 0xFF);
62+
// Set the max number of retry attempts to read from a card. This prevents us from waiting forever for a card, which is the default behaviour of the PN532.
63+
_nfc->setPassiveActivationRetries(0xFF);
64+
// configure board to read RFID tags
65+
_nfc->SAMConfig();
66+
// report immediately
67+
setReportTimerMode(IMMEDIATELY);
68+
};
69+
70+
// define what to do during loop
71+
void onLoop(Child* child) {
72+
// Buffer to store the returned UID
73+
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
74+
// Length of the UID (4 or 7 bytes depending on ISO14443A card type)
75+
uint8_t uid_length;
76+
_card_is_valid = false;
77+
// start the timer
78+
long start_millis = millis();
79+
while(true) {
80+
// if a timer is set, leave the cycle if over
81+
if (_wait_card_for_seconds > 0 && ((millis() - start_millis) > (unsigned long)_wait_card_for_seconds*1000)) break;
82+
// read the card
83+
if (_nfc->readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uid_length)) {
84+
// card read successfully, send the UID back
85+
_card_is_valid = true;
86+
String uid_string = String(uid[0], HEX);
87+
for (uint8_t i = 1; i < uid_length; i++) uid_string = uid_string + String(uid[i], HEX);
88+
char* uid_value = new char[9];
89+
for (int j = 0; j < 8; j++) uid_value[j] = uid_string[j];
90+
uid_value[8] = 0;
91+
child->setValue(uid_value);
92+
// leave the loop so we can report back
93+
break;
94+
}
95+
wait(500);
96+
}
97+
};
98+
99+
#if NODEMANAGER_OTA_CONFIGURATION == ON
100+
// define what to do when receiving an OTA configuration request
101+
void onOTAConfiguration(ConfigurationRequest* request) {
102+
switch(request->getFunction()) {
103+
case 101: setWaitCardForSeconds(request->getValueInt()); break;
104+
default: return;
105+
}
106+
};
107+
#endif
108+
};
109+
#endif

0 commit comments

Comments
 (0)