changed to component

This commit is contained in:
nopnop2002
2025-06-14 13:19:06 +09:00
parent 94eb38d483
commit 664a93ac09
8 changed files with 109 additions and 167 deletions

View File

@@ -25,27 +25,63 @@ idf.py flash
```
# Configuration
![config-top](https://user-images.githubusercontent.com/6020549/147515950-b6e2cf2f-5a82-4114-a565-df7a78085c8d.jpg)
![config-mpr121](https://github.com/nopnop2002/esp-idf-mpr121/assets/6020549/6780b5af-256e-4a12-866a-742868694124)
![Image](https://github.com/user-attachments/assets/66e7e417-3a55-49aa-ab57-8e9ff0f848a3)
![Image](https://github.com/user-attachments/assets/40d3a5ac-43cd-4fc7-a80d-4f330d677d94)
# Wirering
|MPR121||ESP32|ESP32-S2/S3|ESP32-C2/C3/C6|
|:-:|:-:|:-:|:-:|:-:|
|SCL|--|GPIO22|GPIO12|GPIO6|
|SDA|--|GPIO21|GPIO11|GPIO5|
|SCL|--|GPIO19|GPIO12|GPIO6|
|SDA|--|GPIO18|GPIO11|GPIO5|
|IRQ|--|GPIO15|GPIO18|GPIO4|
|GND|--|GND|GND|GND|
|VCC|--|3.3V|3.3V|3.3V|
__You can change it to any pin using menuconfig.__
__Note:__It is recommended to add external pull-up resistors for SDA/SCL pins to make the communication more stable, though the driver will enable internal pull-up resistors.
__You can change it to any pin using menuconfig.__
# Screen Shot
![mpr121-2](https://user-images.githubusercontent.com/6020549/147515969-54901561-66f5-4077-b6f8-7dbd7fe49f2c.jpg)
Supports multiple simultaneous touches.
```
I (55786) MAIN: electrode 0 was just touched
I (55786) MAIN: electrode 1 was just touched
I (55786) MAIN: electrode 2 was just touched
I (55786) MAIN: electrode 3 was just touched
I (58446) MAIN: electrode 0 was just released
I (58446) MAIN: electrode 1 was just released
I (58446) MAIN: electrode 2 was just released
I (58446) MAIN: electrode 3 was just released
```
# How to use this component in your project
Create idf_component.yml in the same directory as main.c.
```
YourProject --+-- CMakeLists.txt
+-- main --+-- main.c
+-- CMakeLists.txt
+-- idf_component.yml
```
Contents of idf_component.yml.
```
dependencies:
nopnop2002/mpr121:
path: components/mpr121
git: https://github.com/nopnop2002/esp-idf-mpr121.git
```
When you build a projects esp-idf will automaticly fetch repository to managed_components dir and link with your code.
```
YourProject --+-- CMakeLists.txt
+-- main --+-- main.c
| +-- CMakeLists.txt
| +-- idf_component.yml
+-- managed_components ----- nopnop2002__mpr121
```
# Reference
https://github.com/nopnop2002/esp-idf-ttp229

View File

@@ -0,0 +1,3 @@
set(component_srcs "mpr121.c")
idf_component_register(SRCS "${component_srcs}" PRIV_REQUIRES driver INCLUDE_DIRS ".")

View File

@@ -9,6 +9,22 @@ menu "MPR121 Configuration"
default 19 if IDF_TARGET_ESP32C3
default 30 if IDF_TARGET_ESP32C6
choice I2C_PORT
prompt "I2C port that controls this bus"
default I2C_PORT_0
help
Select I2C port that controls this bus.
config I2C_PORT_0
bool "I2C_PORT_0"
help
Use I2C_PORT_0.
config I2C_PORT_1
depends on IDF_TARGET_ARCH_XTENSA
bool "I2C_PORT_1"
help
Use I2C_PORT_1.
endchoice
config I2C_ADDRESS
hex "I2C address"
default 0x5A
@@ -18,7 +34,7 @@ menu "MPR121 Configuration"
config SCL_GPIO
int "SCL GPIO number"
range 0 GPIO_RANGE_MAX
default 22 if IDF_TARGET_ESP32
default 19 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 6 # C3 and others
help
@@ -28,7 +44,7 @@ menu "MPR121 Configuration"
config SDA_GPIO
int "SDA GPIO number"
range 0 GPIO_RANGE_MAX
default 21 if IDF_TARGET_ESP32
default 18 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 5 # C3 and others
help

View File

@@ -48,15 +48,17 @@
#include "mpr121.h"
#define NOT_INITED_BIT 0
#define ADDRESS_UNKNOWN_BIT 1
#define READBACK_FAIL_BIT 2
#define OVERCURRENT_FLAG_BIT 3
#define OUT_OF_RANGE_BIT 4
#if CONFIG_I2C_PORT_0
#define I2C_NUM I2C_NUM_0
//#define I2C_NUM I2C_NUM_1
#else
#define I2C_NUM I2C_NUM_1
#endif
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency. no higher than 1MHz for now */
@@ -86,21 +88,11 @@ void MPR121_setRegister(MPR121_t * dev, uint8_t reg, uint8_t value){
}
} else if(reg<MPR121_CTL0){
wasRunning = dev->running;
if(wasRunning) MPR121_stop(dev); // we should ALWAYS be in stop mode for this
if(wasRunning) MPR121_stop(dev);
// we should ALWAYS be in stop mode for this
// unless modding MPR121_ECR or GPIO / LED register
}
#if 0
Wire.beginTransmission(address);
Wire.write(reg);
Wire.write(value);
if(Wire.endTransmission()!=0){
dev->error |= 1<<ADDRESS_UNKNOWN_BIT; // set address unknown bit
} else {
dev->error &= ~(1<<ADDRESS_UNKNOWN_BIT);
}
#endif
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev->address << 1) | I2C_MASTER_WRITE, true);
@@ -124,20 +116,6 @@ uint8_t MPR121_getRegister(MPR121_t * dev, uint8_t reg){
ESP_LOGD(TAG, "getRegister reg=0x%02x", reg);
uint8_t scratch = 0;
#if 0
Wire.beginTransmission(address);
Wire.write(reg); // set address to read from our requested register
Wire.endTransmission(false); // repeated start
if(Wire.requestFrom(address,(uint8_t)1) == 1){ // just a single byte
dev->error &= ~(1<<ADDRESS_UNKNOWN_BIT); // all good, clear the bit
scratch = Wire.read();
} else {
dev->error |= 1<<ADDRESS_UNKNOWN_BIT; //set the bit - something went wrong
}
#endif
uint8_t buf[2];
memset (buf, 0, 2);
@@ -177,48 +155,10 @@ uint8_t MPR121_getRegister(MPR121_t * dev, uint8_t reg){
return scratch;
}
bool MPR121_begin(MPR121_t * dev, int16_t address, int16_t touchThreshold, int16_t releaseThreshold, int16_t interruptPin, int16_t sda, int16_t scl){
// SDA and SCL should idle high, but MPR121 can get stuck waiting to complete a transaction
// this code detects this state and releases us from it
#if 0
//boolean stuck_transaction = false;
bool stuck_transaction = false;
uint8_t stuck_transaction_retry_count = 0;
const uint8_t stuck_transaction_retry_MAX = 10;
::pinMode( PIN_WIRE_SDA, INPUT_PULLUP );
::pinMode( PIN_WIRE_SCL, INPUT_PULLUP );
do{
if(( ::digitalRead( PIN_WIRE_SDA ) == LOW ) && ( ::digitalRead( PIN_WIRE_SCL ) == HIGH )){
Serial.println("MPR121_begin stuck_transaction = true");
stuck_transaction = true;
::pinMode( PIN_WIRE_SCL, OUTPUT );
::digitalWrite( PIN_WIRE_SCL, LOW );
delay( 1 ); // this is way longer than required (would be 1.25us at 400kHz) but err on side of caution
::pinMode( PIN_WIRE_SCL, INPUT_PULLUP );
stuck_transaction_retry_count++;
} else {
Serial.println("MPR121_begin stuck_transaction = false");
stuck_transaction = false;
}
} while ( stuck_transaction && ( stuck_transaction_retry_count < stuck_transaction_retry_MAX ));
// TODO: add new error code that can be handled externally
if( stuck_transaction_retry_count > 0){
if( stuck_transaction ){
} else {
}
}
// now we've released (if necessary) we can get on with things
Wire.begin();
#endif
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = sda,
@@ -400,7 +340,8 @@ void MPR121_settingsType(MPR121_settings_type *defaultSettings){
//void MPR121_applySettings(MPR121_t * dev, MPR121_settings_type *settings){
void MPR121_applySettings(MPR121_t * dev){
bool wasRunning = dev->running;
if(wasRunning) MPR121_stop(dev); // can't change most regs when running - checking
if(wasRunning) MPR121_stop(dev);
// can't change most regs when running - checking
// here avoids multiple stop() / run() calls
MPR121_setRegister(dev, MPR121_MHDR, dev->defaultSettings._MHDR);
@@ -524,6 +465,7 @@ bool MPR121_updateFilteredData(MPR121_t * dev){
for(int i=0; i<26; i++){ // 13 filtered values
buf[i] = MPR121_getRegister(dev, MPR121_E0FDL+i);
if (( i % 2) == 0) vTaskDelay(1);
}
for(int i=0; i<13; i++){ // 13 filtered values
@@ -539,38 +481,6 @@ bool MPR121_updateFilteredData(MPR121_t * dev){
}
return true;
#if 0
uint8_t LSB, MSB;
Wire.beginTransmission(address);
Wire.write(MPR121_E0FDL); // set address register to read from the start of the
//filtered data
Wire.endTransmission(false); // repeated start
if(MPR121_touchStatusChanged(dev)) {
dev->autoTouchStatusFlag = true;
}
if(Wire.requestFrom(address,(uint8_t)26)==26){
for(int i=0; i<13; i++){ // 13 filtered values
if(MPR121_touchStatusChanged(dev)) {
dev->autoTouchStatusFlag = true;
}
LSB = Wire.read();
if(MPR121_touchStatusChanged(dev)) {
dev->autoTouchStatusFlag = true;
}
MSB = Wire.read();
dev->filteredData[i] = ((MSB << 8) | LSB);
}
return(true);
} else {
// if we don't get back all 26 values we requested, don't update the FDAT values
// and return false
return(false);
}
#endif
}
int MPR121_getFilteredData(MPR121_t * dev, uint8_t electrode){
@@ -598,31 +508,6 @@ bool MPR121_updateBaselineData(MPR121_t * dev){
}
return true;
#if 0
Wire.beginTransmission(address);
Wire.write(MPR121_E0BV); // set address register to read from the start of the
// baseline data
Wire.endTransmission(false); // repeated start
if(MPR121_touchStatusChanged(dev)) {
dev->autoTouchStatusFlag = true;
}
if(Wire.requestFrom(address,(uint8_t)13)==13){
for(int i=0; i<13; i++){ // 13 filtered values
if(MPR121_touchStatusChanged(dev)) {
dev->autoTouchStatusFlag = true;
}
dev->baselineData[i] = Wire.read()<<2;
}
return(true);
} else {
// if we don't get back all 26 values we requested, don't update the BVAL values
// and return false
return(false);
}
#endif
}
int MPR121_getBaselineData(MPR121_t * dev, uint8_t electrode){
@@ -651,7 +536,8 @@ void MPR121_setTouchThresholdAll(MPR121_t * dev, uint8_t val){
if(!MPR121_isInited(dev)) return;
bool wasRunning = dev->running;
if(wasRunning) MPR121_stop(dev); // can only change thresholds when not running
if(wasRunning) MPR121_stop(dev);
// can only change thresholds when not running
// checking here avoids multiple stop() / run()
// calls
@@ -689,7 +575,8 @@ void MPR121_setReleaseThresholdAll(MPR121_t * dev, uint8_t val){
if(!MPR121_isInited(dev)) return;
bool wasRunning = dev->running;
if(wasRunning) MPR121_stop(dev); // can only change thresholds when not running
if(wasRunning) MPR121_stop(dev);
// can only change thresholds when not running
// checking here avoids multiple stop / starts
for(uint8_t i=0; i<13; i++){

View File

@@ -1,2 +1 @@
idf_component_register(SRCS "main.c" "mpr121.c"
INCLUDE_DIRS ".")
idf_component_register(SRCS "main.c" INCLUDE_DIRS ".")

View File

@@ -62,16 +62,17 @@ void app_main(void)
#if 0
MPR121_setTouchThresholdAll(&dev, 40); // this is the touch threshold - setting it low makes it more like a proximity trigger, default value is 40 for touch
MPR121_setReleaseThresholdAll(&dev, 20); // this is the release threshold - must ALWAYS be smaller than the touch threshold, default value is 20 for touch
// this is the touch threshold - setting it low makes it more like a proximity trigger, default value is 40 for touch
MPR121_setTouchThresholdAll(&dev, 40);
// this is the release threshold - must ALWAYS be smaller than the touch threshold, default value is 20 for touch
MPR121_setReleaseThresholdAll(&dev, 20);
#endif
MPR121_setFFI(&dev, FFI_10); // AFE Configuration 1
MPR121_setSFI(&dev, SFI_10); // AFE Configuration 2
MPR121_setGlobalCDT(&dev, CDT_4US); // reasonable for larger capacitances
MPR121_autoSetElectrodesDefault(&dev, true); // autoset all electrode settings
MPR121_updateTouchData(&dev); // Clear touch status register
while(1) {
MPR121_updateAll(&dev);
@@ -82,6 +83,6 @@ void app_main(void)
ESP_LOGI(TAG, "electrode %d was just released", i);
}
}
vTaskDelay(10);
vTaskDelay(1);
}
}