Skip to content

Commit

Permalink
Support for TTP226/TTP229 Touch control sensor (mysensors#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
user2684 authored Feb 25, 2018
1 parent 79fe3d8 commit 9a9c8e2
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 84 deletions.
4 changes: 3 additions & 1 deletion NodeManager.ino
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ SensorSHT31 | 2 | USE_SHT31 | SHT31 sensor, return temperat
SensorSI7021 | 2 | USE_SI7021 | SI7021 sensor, return temperature/humidity based on the attached SI7021 sensor | https://github.com/sparkfun/SparkFun_Si701_Breakout_Arduino_Library
SensorChirp | 3 | USE_CHIRP | Chirp soil moisture sensor (includes temperature and light sensors) | https://github.com/Apollon77/I2CSoilMoistureSensor
DisplayHD44780 | 1 | USE_HD44780 | Supports most Hitachi HD44780 based LCDs, by default displays values of all sensors and children | https://github.com/cyberang3l/NewLiquidCrystal
SensorTTP | 1 | USE_TTP | TTP226/TTP229 Touch control sensor | -
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 @@ -259,6 +260,7 @@ FEATURE_SD | OFF | allow for reading from and writing to SD
//#define USE_SI7021
//#define USE_CHIRP
//#define USE_HD44780
//#define USE_TTP

/***********************************
* NodeManager advanced settings
Expand Down Expand Up @@ -338,6 +340,7 @@ NodeManager node;
//SensorSI7021 si7021(node);
//SensorChirp chirp(node);
//DisplayHD44780 hd44780(node);
//SensorTTP ttp(node);

/***********************************
* Main Sketch
Expand All @@ -349,7 +352,6 @@ void before() {
Serial.begin(MY_BAUD_RATE);



/*
* Configure your sensors below
*/
Expand Down
94 changes: 67 additions & 27 deletions NodeManagerLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ template<typename T> class List {
if (position > _endPosition) position = _endPosition;
return _internalArray[position];
}
void clear() {
T* newArray = NULL;
if (_allocBlocks > 0) newArray = new T[_allocBlocks];
delete[] _internalArray;
_internalArray = newArray;
_endPosition = 0;
}
inline iterator begin() { return _internalArray; }
inline iterator end() { return _internalArray + _endPosition; }
inline bool empty() { return (_endPosition == 0); }
Expand Down Expand Up @@ -1478,33 +1485,6 @@ class DisplaySSD1306: public Display {
};
#endif

/*
* Hitachi HD44780 display
*/
#ifdef USE_HD44780
class DisplayHD44780: public Display {
public:
DisplayHD44780(NodeManager& node_manager, int child_id = -255);
// set i2c address (default: 0x38)
void setI2CAddress(uint8_t i2caddress);
// set the backlight (default: HIGH)
void setBacklight(uint8_t value);
// display specific functions
void printCaption(const char* value);
void print(const char* value);
void println(const char* value);
void printChild(Child* child);
void clear();
void setCursor(int col,int row);
// define what to do at each stage of the sketch
void onSetup();
protected:
LiquidCrystal_I2C* _lcd;
uint8_t _i2caddress = 0x38;
int _column = 0;
};
#endif

/*
SensorSHT31: temperature and humidity sensor
*/
Expand Down Expand Up @@ -1565,6 +1545,66 @@ class SensorChirp: public Sensor {
};
#endif

/*
* Hitachi HD44780 display
*/
#ifdef USE_HD44780
class DisplayHD44780: public Display {
public:
DisplayHD44780(NodeManager& node_manager, int child_id = -255);
// set i2c address (default: 0x38)
void setI2CAddress(uint8_t i2caddress);
// set the backlight (default: HIGH)
void setBacklight(uint8_t value);
// display specific functions
void printCaption(const char* value);
void print(const char* value);
void println(const char* value);
void printChild(Child* child);
void clear();
void setCursor(int col,int row);
// define what to do at each stage of the sketch
void onSetup();
protected:
LiquidCrystal_I2C* _lcd;
uint8_t _i2caddress = 0x38;
int _column = 0;
};
#endif

/*
SensorTTP: TTP226/TTP229 Touch control sensor
*/
#ifdef USE_TTP
class SensorTTP: public Sensor {
public:
SensorTTP(NodeManager& node_manager, int child_id = -255);
// set the passcode length. Passcode will be sent to the controller only after this number of digits have been pressed (default: 4)
void setPasscodeLength(int value);
// set the clock pin (default: 6)
void setClockPin(int value);
// set the SDO pin (default: 5)
void setSdoPin(int value);
// set the DV pin (default: 3)
void setDvPin(int value);
// set the RST pin (default: 4)
void setRstPin(int value);
// define what to do at each stage of the sketch
void onSetup();
void onLoop(Child* child);
void onInterrupt();
void onReceive(MyMessage* message);
protected:
int _clock_pin = 6;
int _sdo_pin = 5;
int _dv_pin = 3;
int _rst_pin = 4;
int _fetchData();
List<int> _passcode;
int _passcode_length = 4;
};
#endif

/***************************************
NodeManager: manages all the aspects of the node
*/
Expand Down
224 changes: 168 additions & 56 deletions NodeManagerLibrary.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3309,62 +3309,6 @@ void DisplaySSD1306::onSetup() {
}
#endif

/*
* Hitachi HD44780 display
*/
#ifdef USE_HD44780
// constructor
DisplayHD44780::DisplayHD44780(NodeManager& node_manager, int child_id): Display(node_manager, child_id) {
_name = "HD44780";
children.get(1)->description = _name;
}

// setter/getter
void DisplayHD44780::setI2CAddress(uint8_t i2caddress) {
_i2caddress = i2caddress;
}
void DisplayHD44780::setBacklight(uint8_t value) {
_lcd->setBacklight(value);
}

// display specific function
void DisplayHD44780::printCaption(const char* value) {
if (strlen(value) > 0) println(value);
}

void DisplayHD44780::print(const char* value) {
// print the string
_lcd->print(value);
}

void DisplayHD44780::println(const char* value) {
if (value != nullptr) print(value);
_column = _column + 1;
setCursor(0,_column);
}

void DisplayHD44780::printChild(Child* child) {
child->printOn(*_lcd);
}

void DisplayHD44780::clear() {
_column = 0;
_lcd->clear();
}

void DisplayHD44780::setCursor(int col,int row) {
_lcd->setCursor(col,row);
}

// what to do during setup
void DisplayHD44780::onSetup() {
_lcd = new LiquidCrystal_I2C(_i2caddress, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
_lcd->begin(16,2);
_lcd->home();
clear();
}
#endif

/*
SensorSHT31
*/
Expand Down Expand Up @@ -3589,10 +3533,178 @@ void SensorChirp::onLoop(Child* child) {

// what to do as the main task when receiving a message
void SensorChirp::onReceive(MyMessage* message) {
}
#endif

/*
* Hitachi HD44780 display
*/
#ifdef USE_HD44780
// constructor
DisplayHD44780::DisplayHD44780(NodeManager& node_manager, int child_id): Display(node_manager, child_id) {
_name = "HD44780";
children.get(1)->description = _name;
}

// setter/getter
void DisplayHD44780::setI2CAddress(uint8_t i2caddress) {
_i2caddress = i2caddress;
}
void DisplayHD44780::setBacklight(uint8_t value) {
_lcd->setBacklight(value);
}

// display specific function
void DisplayHD44780::printCaption(const char* value) {
if (strlen(value) > 0) println(value);
}

void DisplayHD44780::print(const char* value) {
// print the string
_lcd->print(value);
}

void DisplayHD44780::println(const char* value) {
if (value != nullptr) print(value);
_column = _column + 1;
setCursor(0,_column);
}

void DisplayHD44780::printChild(Child* child) {
child->printOn(*_lcd);
}

void DisplayHD44780::clear() {
_column = 0;
_lcd->clear();
}

void DisplayHD44780::setCursor(int col,int row) {
_lcd->setCursor(col,row);
}

// what to do during setup
void DisplayHD44780::onSetup() {
_lcd = new LiquidCrystal_I2C(_i2caddress, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
_lcd->begin(16,2);
_lcd->home();
clear();
}
#endif

/*
SensorTTP
*/
#ifdef USE_TTP
// contructor
SensorTTP::SensorTTP(NodeManager& node_manager, int child_id): Sensor(node_manager) {
_name = "TTP";
children.allocateBlocks(1);
new ChildInt(this,_node->getAvailableChildId(child_id),S_INFO,V_TEXT,_name);
}
// setter/getter
void SensorTTP::setPasscodeLength(int value) {
_passcode_length = value;
}
void SensorTTP::setClockPin(int value) {
_clock_pin = value;
}
void SensorTTP::setSdoPin(int value) {
_sdo_pin = value;
}
void SensorTTP::setDvPin(int value) {
_dv_pin = value;
}
void SensorTTP::setRstPin(int value) {
_rst_pin = value;
}

// what to do during setup
void SensorTTP::onSetup() {
// setup passcode array
_passcode.allocateBlocks(_passcode_length);
// initialize pins
pinMode(_dv_pin, INPUT);
pinMode(_sdo_pin, INPUT);
pinMode(_rst_pin, OUTPUT);
pinMode(_clock_pin, OUTPUT);
// set the interrupt on the DV pin
setInterrupt(_dv_pin,RISING,LOW);
// report immediately
_report_timer->unset();
digitalWrite(_rst_pin, LOW);
}

// what to do during loop
void SensorTTP::onLoop(Child* child) {
}

// what to do when receiving an interrupt
void SensorTTP::onInterrupt() {
Child* child = children.get(1);
// fetch the key pressed from the keypad
int value = _fetchData();
// invalid value, return
if (value == 0) return;
#ifdef NODEMANAGER_DEBUG
Serial.print(_name);
Serial.print(F(" I="));
Serial.print(child->child_id);
Serial.print(F(" D="));
Serial.println(value);
#endif
// add the value to the passcode array
_passcode.push(value);
Serial.println(_passcode.size());
// time to send the passcode back
if (_passcode.size() == _passcode_length) {
int passcode = 0;
// build up the passcode
for (int i = 1; i <= _passcode.size(); i++) {
passcode *= 10;
passcode += (int) _passcode.get(i);
}
#ifdef NODEMANAGER_DEBUG
Serial.print(_name);
Serial.print(F(" I="));
Serial.print(child->child_id);
Serial.print(F(" V="));
Serial.println(passcode);
#endif
// store it in the child so it will be sent back
((ChildInt*)child)->setValueInt(passcode);
// clear the passcode array
_passcode.clear();
}
}

// what to do as the main task when receiving a message
void SensorTTP::onReceive(MyMessage* message) {
Child* child = getChild(message->sensor);
if (child == nullptr) return;
if (message->getCommand() == C_REQ && message->type == child->type) onLoop(child);
}

// fetch data from the keypad
int SensorTTP::_fetchData() {
int Key = 0;
int Ziro = 0;
// Send 8 clock pulses and check each data bit as it arrives
for(int i = 1; i < 9; i++) {
digitalWrite(_clock_pin,1);
delayMicroseconds(1000);
// If data bit, high, then that key was pressed.
if(digitalRead(_sdo_pin) == HIGH)
Key=i;
else
Ziro++;
digitalWrite(_clock_pin,0);
// Don't use delay(1) as it will mess up interrupts
delayMicroseconds(1000);
}
if(Key>0 && Ziro==7) return Key;
return 0;
}
#endif


Expand Down
Loading

0 comments on commit 9a9c8e2

Please sign in to comment.