Skip to content

Commit ba0230b

Browse files
authored
Support for MPR121 Capacitive Touch Sensor
1 parent 7188e44 commit ba0230b

File tree

4 files changed

+145
-0
lines changed

4 files changed

+145
-0
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,10 @@ jobs:
497497
- sed -r -i 's/\/\/(#include <sensors\/SensorCCS811.h>)/\1/' $SKETCH
498498
- eval $OTA_CONFIGURATION
499499
- eval $COMPILE
500+
- name: "SensorMPR121"
501+
script:
502+
- arduino --install-library "Adafruit MPR121"
503+
- sed -r -i 's/\/\/(SensorMPR121 .+)/\1/' $SKETCH
504+
- sed -r -i 's/\/\/(#include <sensors\/SensorMPR121.h>)/\1/' $SKETCH
505+
- eval $OTA_CONFIGURATION
506+
- eval $COMPILE

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ SensorPca9685Rgbw | 2 | Generic RGBW-dimmer sensor (S_RGBW_LIGHT) use
150150
SensorDSM501A | 1 | Dust sensor module DSM501A for PM1.0 and PM2.5 particles | -
151151
SensorPN532 | 1 | PN532 NFC RFID Module | https://github.com/elechouse/PN532
152152
SensorCCS811 | 1 | CCS811 gas/Air Quality sensor. Measure VOC and eCO2 | https://github.com/adafruit/Adafruit_CCS811
153+
SensorMPR121 | 1 | MPR121-based capacitive touch control sensor | https://github.com/adafruit/Adafruit_MPR121
153154

154155
Those sensors requiring a pin to operate would take it as an argument in the constructor.
155156
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
@@ -964,6 +965,16 @@ Each sensor class may expose additional methods.
964965
void setTemperatureSensor(bool value);
965966
~~~
966967
968+
* SensorMPR121
969+
~~~c
970+
// set the passcode length. Passcode will be sent to the controller only after this number of digits have been pressed (default: 4)
971+
void setPasscodeLength(int value);
972+
// [101] wait for a valid code for the given amount of seconds. Useful when battery powered (default: 0)
973+
void setWaitCodeForSeconds(int value);
974+
// return true if the code was recognized successfully, false otherwise. Useful when a hook function needs to act upon the result
975+
bool getCodeIsValid();
976+
~~~
977+
967978
### OTA Configuration
968979

969980
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.

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,4 @@ SensorPca9685W KEYWORD1
218218
SensorDSM501A KEYWORD1
219219
SensorPN532 KEYWORD1
220220
SensorCCS811 KEYWORD1
221+
SensorMPR121 KEYWORD1

sensors/SensorMPR121.h

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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 SensorMPR121_h
20+
#define SensorMPR121_h
21+
22+
#include <Wire.h>
23+
#include "Adafruit_MPR121.h"
24+
25+
#ifndef _BV
26+
#define _BV(bit) (1 << (bit))
27+
#endif
28+
29+
/*
30+
SensorMPR121: capacitive Touch control sensor
31+
*/
32+
33+
class SensorMPR121: public Sensor {
34+
protected:
35+
Adafruit_MPR121 *_cap = new Adafruit_MPR121();
36+
List<int> _passcode;
37+
int _passcode_length = 4;
38+
uint8_t _i2c_addr = 0x5A;
39+
int _wait_code_for_seconds = 0;
40+
bool _code_is_valid = false;
41+
uint16_t _lasttouched = 0;
42+
uint16_t _currtouched = 0;
43+
44+
public:
45+
SensorMPR121(uint8_t child_id = 0): Sensor(-1) {
46+
_name = "MPR121";
47+
children.allocateBlocks(1);
48+
new Child(this,INT,nodeManager.getAvailableChildId(child_id),S_INFO,V_TEXT,_name);
49+
};
50+
51+
// set the passcode length. Passcode will be sent to the controller only after this number of digits have been pressed (default: 4)
52+
void setPasscodeLength(int value) {
53+
_passcode_length = value;
54+
};
55+
56+
// [101] wait for a valid code for the given amount of seconds. Useful when battery powered (default: 0)
57+
void setWaitCodeForSeconds(int value) {
58+
_wait_code_for_seconds = value;
59+
};
60+
61+
// return true if the code was recognized successfully, false otherwise. Useful when a hook function needs to act upon the result
62+
bool getCodeIsValid() {
63+
return _code_is_valid;
64+
};
65+
66+
// define what to do during setup
67+
void onSetup() {
68+
// do not average the value
69+
children.get()->setValueProcessing(NONE);
70+
// report immediately
71+
setReportTimerMode(IMMEDIATELY);
72+
if (!_cap->begin(_i2c_addr)) debug(PSTR(LOG_SENSOR "%s: KO\n"),_name);
73+
// setup passcode array
74+
_passcode.allocateBlocks(_passcode_length);
75+
};
76+
77+
// define what to do during loop
78+
void onLoop(Child* child) {
79+
_code_is_valid = false;
80+
// start the timer
81+
long start_millis = millis();
82+
while(true) {
83+
// if a timer is set, leave the cycle if over
84+
if (_wait_code_for_seconds > 0 && ((millis() - start_millis) > (unsigned long)_wait_code_for_seconds*1000)) break;
85+
86+
// Get the currently touched pads
87+
_currtouched = _cap->touched();
88+
for (uint8_t i=0; i<12; i++) {
89+
if ((_currtouched & _BV(i)) && !(_lasttouched & _BV(i)) ) {
90+
// pad i touched
91+
debug(PSTR(LOG_SENSOR "%s(%d):READ v=%d\n"),_name,child->getChildId(),i);
92+
// add the value to the passcode array
93+
_passcode.push(i);
94+
// time to send the passcode back
95+
if (_passcode.size() == _passcode_length) {
96+
int passcode = 0;
97+
// build up the passcode
98+
for (int i = 1; i <= _passcode.size(); i++) {
99+
passcode *= 10;
100+
passcode += (int) _passcode.get(i);
101+
}
102+
// store it in the child so it will be sent back
103+
child->setValue(passcode);
104+
// clear the passcode array
105+
_passcode.clear();
106+
break;
107+
}
108+
}
109+
}
110+
// reset state
111+
_lasttouched = _currtouched;
112+
wait(100);
113+
}
114+
};
115+
116+
#if NODEMANAGER_OTA_CONFIGURATION == ON
117+
// define what to do when receiving an OTA configuration request
118+
void onOTAConfiguration(ConfigurationRequest* request) {
119+
switch(request->getFunction()) {
120+
case 101: setWaitCodeForSeconds(request->getValueInt()); break;
121+
default: return;
122+
}
123+
};
124+
#endif
125+
};
126+
#endif

0 commit comments

Comments
 (0)