Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By shoelessone
#32799 Hey all!

I know the esp-12e has the ADC pin exposed, but I'm wondering if anybody can point me towards an example of how I might use this button with a simple capacitive touch button.

The "button" is basically a copper disk that I'd like to wire up in my "sketch". I don't need any sort of precision (I know there is a fair amount of talk about how much resolution the ADC pin has) - I just need to know whether somebody is touching the thing, or not.

I will be use a "bare" esp-12e (making a custom pcb for it), but for hte time being I'm breadboarding everything up with one of those fancy esp-12e test boards. I noticed it has a light sensor already hooked up to the pin, and just for fun I tried a VERY simple test of attaching a jumper wire directly to the ADC pin on the board to see what sort of numbers I go. In short, I seemed to get numbers been, roughly, 8 and 18. MOST of the time the values I got were > 12 when I was touching the button, but things seemed to jump around a lot so I"m not sure if I could reliably use this just as i had it setup.

So, all of this said, given that I'm a bit of an EE novice, can anybody recommend me a particular circuit/sketch/etc that I might be able to use for this setup?

THANK YOU!
User avatar
By lethe
#32804 You don't need an ADC for a capacitive touch button.
For the most simple approach, you just need 1 GPIO with a piece of wire attached.
In your code you need to:
- configure this pin as output
- wait a little
- reconfigure the pin as input
- enable the internal pull-up resistor
- count a variable up, until the pin reads high

I have this approach working in an ESP powered desklamp and it works quite well, with a little tuning. I'm not using arduino, but here's some C code, in case that helps:
Code: Select all#include <gpio.h>
#include <osapi.h>
#include <eagle_soc.h>

static const int timerIntervalMs = 100;
static const int threshold = 5;  // tweak me
static const int gpio = 2;
static ETSTimer touchTimer;

static void touchTimerCb(void *arg) {
    int riseTime = 0;

    PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U);
    GPIO_OUTPUT_SET(gpio, 0);
    os_delay_us(1000);

    GPIO_DIS_OUTPUT(gpio);
    PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO2_U);

    while (!(gpio_input_get()&(1<<gpio))) {
        ++riseTime;
    }

    if (riseTime > threshold) {
      // touch detected, do something
      // (perhaps only if triggered twice in a row, to avoid false positives)
    }
}

void user_init(void) {
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
   os_timer_disarm(&touchTimer);
   os_timer_setfn(&touchTimer, touchTimerCb, NULL);
   os_timer_arm(&touchTimer, timerIntervalMs, 1);
}


A more sophisticated approach would use 2 GPIOs, a 1M resistor and optionally a small cap (10pF or so) connected like this: Image

The basic principle is the same, you are just using seperate GPIOs for trigger and sensing, so you don't need to rely on the internal pull-up (and have more control over the timing due to the resistor & cap).
Last edited by lethe on Wed Jun 15, 2016 10:56 pm, edited 1 time in total.
User avatar
By shoelessone
#32809 Wow, thank you for the extremely thoughtful/thorough response lethe, I really appreciate it!

That said, I'm in a small "situation" because I'm pushing the number of GPIO pins I'm using already - in short, I have 8 LEDs I want to power (all will be around 6 or 7mA, which I believe is within range of the 12mA each pin can handle?), and I have 9 pins on the ESP-12E. But, I was hoping to leave one pin, GPIO 0 open so that I could still use it to program the board if I needed to.

Which leaves me with 0 GPIO pins left :( - I COULD use a port expander I know, or I'm guessing I could biuld some fancier switch for the GPIO0 pin so I could switch it between 3.3V for programming and a GPIO pin... but I figured, considering I have the ADC pin, I could save myself some work by just using that!

Thoughts? I am really open and so I'd appreciate any thoughts on the matter!
User avatar
By lethe
#32811 You can cut down the number of I/Os needed by using a clever circuit layout and quickly cycling through the LEDs.
For example, if you arrange your LEDs in a matrix, you can drive up to 9 LEDs using 6 pins: http://www.tuline.com/dru/content/ardui ... matrix-pwm (random link, there might be better explanations)

If you use the fact, that the ESPs I/O pins are tri-state, you can even drive more LEDs, but the addressing scheme gets a bit more complex: https://en.wikipedia.org/wiki/Charlieplexing

In both cases, the LED won't be lit all the time (33% for the 3x3 matrix), so you should use transistors and drive them with higher currents.