Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mpr121.cpp
00001 /* 00002 Copyright (c) 2011 Anthony Buckton (abuckton [at] blackink [dot} net {dot} au) 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 #include <mbed.h> 00024 #include <sstream> 00025 #include <string> 00026 #include <list> 00027 00028 #include <mpr121.h> 00029 00030 Mpr121::Mpr121(I2C *i2c, Address i2cAddress) 00031 { 00032 this->i2c = i2c; 00033 00034 address = i2cAddress; 00035 00036 // Configure the MPR121 settings to default 00037 this->configureSettings(); 00038 } 00039 00040 00041 void Mpr121::configureSettings() 00042 { 00043 // Put the MPR into setup mode 00044 this->write(ELE_CFG,0x00); 00045 /* 00046 this->write(AUTO_CFG_U,201); 00047 this->write(AUTO_CFG_T,181); 00048 this->write(AUTO_CFG_L,131); 00049 this->write(AUTO_CFG_0,0x09); 00050 */ 00051 // Electrode filters for when data is > baseline 00052 unsigned char gtBaseline[] = { 00053 0x01, //MHD_R 00054 0x01, //NHD_R 00055 0x00, //NCL_R 00056 0x00 //FDL_R 00057 }; 00058 00059 writeMany(MHD_R,gtBaseline,4); 00060 00061 // Electrode filters for when data is < baseline 00062 unsigned char ltBaseline[] = { 00063 0x01, //MHD_F 00064 0x01, //NHD_F 00065 0xFF, //NCL_F 00066 0x02 //FDL_F 00067 }; 00068 00069 writeMany(MHD_F,ltBaseline,4); 00070 00071 // Electrode touch and release thresholds 00072 unsigned char electrodeThresholds[] = { 00073 E_THR_T, // Touch Threshhold 00074 E_THR_R // Release Threshold 00075 }; 00076 00077 for(int i=0; i<12; i++){ 00078 int result = writeMany((ELE0_T+(i*2)),electrodeThresholds,2); 00079 } 00080 00081 // Proximity Settings 00082 unsigned char proximitySettings[] = { 00083 0xff, //MHD_Prox_R 00084 0xff, //NHD_Prox_R 00085 0x00, //NCL_Prox_R 00086 0x00, //FDL_Prox_R 00087 0x01, //MHD_Prox_F 00088 0x01, //NHD_Prox_F 00089 0xFF, //NCL_Prox_F 00090 0xff, //FDL_Prox_F 00091 0x00, //NHD_Prox_T 00092 0x00, //NCL_Prox_T 00093 0x00 //NFD_Prox_T 00094 }; 00095 writeMany(MHDPROXR,proximitySettings,11); 00096 00097 unsigned char proxThresh[] = { 00098 PROX_THR_T, // Touch Threshold 00099 PROX_THR_R // Release Threshold 00100 }; 00101 writeMany(EPROXTTH,proxThresh,2); 00102 00103 this->write(FIL_CFG,0x04); 00104 00105 // Set the electrode config to transition to active mode 00106 this->write(ELE_CFG,0x0c); 00107 00108 00109 00110 00111 } 00112 00113 void Mpr121::setElectrodeThreshold(int electrode, unsigned char touch, unsigned char release){ 00114 00115 if(electrode > 11) return; 00116 00117 // Get the current mode 00118 unsigned char mode = this->read(ELE_CFG); 00119 00120 // Put the MPR into setup mode 00121 this->write(ELE_CFG,0x00); 00122 00123 // Write the new threshold 00124 this->write((ELE0_T+(electrode*2)), touch); 00125 this->write((ELE0_T+(electrode*2)+1), release); 00126 00127 //Restore the operating mode 00128 this->write(ELE_CFG, mode); 00129 } 00130 00131 00132 unsigned char Mpr121::read(int key){ 00133 00134 unsigned char data[2]; 00135 00136 //Start the command 00137 i2c->start(); 00138 00139 // Address the target (Write mode) 00140 int ack1= i2c->write(address); 00141 00142 // Set the register key to read 00143 int ack2 = i2c->write(key); 00144 00145 // Re-start for read of data 00146 i2c->start(); 00147 00148 // Re-send the target address in read mode 00149 int ack3 = i2c->write(address+1); 00150 00151 // Read in the result 00152 data[0] = i2c->read(0); 00153 00154 // Reset the bus 00155 i2c->stop(); 00156 00157 return data[0]; 00158 } 00159 00160 00161 int Mpr121::write(int key, unsigned char value){ 00162 00163 //Start the command 00164 i2c->start(); 00165 00166 // Address the target (Write mode) 00167 int ack1= i2c->write(address); 00168 00169 // Set the register key to write 00170 int ack2 = i2c->write(key); 00171 00172 // Read in the result 00173 int ack3 = i2c->write(value); 00174 00175 // Reset the bus 00176 i2c->stop(); 00177 00178 return (ack1+ack2+ack3)-3; 00179 } 00180 00181 00182 int Mpr121::writeMany(int start, unsigned char* dataSet, int length){ 00183 //Start the command 00184 i2c->start(); 00185 00186 // Address the target (Write mode) 00187 int ack= i2c->write(address); 00188 if(ack!=1){ 00189 return -1; 00190 } 00191 00192 // Set the register key to write 00193 ack = i2c->write(start); 00194 if(ack!=1){ 00195 return -1; 00196 } 00197 00198 // Write the date set 00199 int count = 0; 00200 while(ack==1 && (count < length)){ 00201 ack = i2c->write(dataSet[count]); 00202 count++; 00203 } 00204 // Stop the cmd 00205 i2c->stop(); 00206 00207 return count; 00208 } 00209 00210 00211 bool Mpr121::getProximityMode(){ 00212 if(this->read(ELE_CFG) > 0x0c) 00213 return true; 00214 else 00215 return false; 00216 } 00217 00218 void Mpr121::setProximityMode(bool mode){ 00219 this->write(ELE_CFG,0x00); 00220 if(mode){ 00221 this->write(ELE_CFG,0x30); //Sense proximity from ALL pads 00222 } else { 00223 this->write(ELE_CFG,0x0c); //Sense touch, all 12 pads active. 00224 } 00225 } 00226 00227 00228 int Mpr121::readTouchData(){ 00229 return this->read(0x00); 00230 }
Generated on Fri Jul 15 2022 06:50:41 by
1.7.2