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

Moderator: igrr

User avatar
By shoelessone
#33061 Thanks for this.

Part of my concern is that I'm using MQTT and am constantly connected to "listen" for published messages coming in. In the past when I've tried to add long delays in my code, it seems that I tend to have more random issues with disconnects. I think the code you posted had a 1 second delay in there? I'm not sure how often that happens (and maybe it really was totally arbitrary), but if I'm constantly checking for a touch of a button it seems like I might have issues with other bits of my code?



EDIT: by the way, if I hook up the ADC pin to a piece of wire and use the bit of code from the library I linked to above, except I remove the (critical, I realize) bits of the code I reference above ADMUX, etc, things actually work pretty well, but they are inconsistent. Basically as you can see in this video I recorded below, things are basically PERFECT, or at least as far as I need them perfect, but over time the values i get out change... I'll get 0 for default state and 10 for touched (ideal), for a while but then I'll test again after letting the sketch run and I'll get 0 default and 1 touched. Or 1 default and 2 touched. Or even once 1 default and 1 touched.

It's frustrating because this is baiscally exactly what I want... just not consistent enough!

https://goo.gl/photos/KQ9qcnWmfgnJEg539
User avatar
By lethe
#33083
shoelessone wrote:I think the code you posted had a 1 second delay in there? I'm not sure how often that happens (and maybe it really was totally arbitrary), but if I'm constantly checking for a touch of a button it seems like I might have issues with other bits of my code?

That's actually a 1ms (1000µs) delay and could probably be much shorter. It's just there to ensure that the pin is discharged before starting the measurement (and might be entirely uneccesary). I did not time the entire function, but that delay should account for the vast majority its execution time.

In my code, the touch detection is run every 100ms while the ESP also runs an esphttpd based webserver, answering GET requests every couple of seconds (from my desktop, if it's running). So far I did not encounter any problems with that approach. However unlike the arduino stuff, there's no main loop in my code. The touch detection is running of a timer provided by the SDK libraries and everything else is event driven, so the SDK may decide to delay execution of the touch function, if it's busy.

EDIT: by the way, if I hook up the ADC pin to a piece of wire and use the bit of code from the library I linked to above, except I remove the (critical, I realize) bits of the code I reference above ADMUX, etc, things actually work pretty well, but they are inconsistent.

Without those bits, the code does nothing else than sampling the ADC. That ADCMUX stuff is indeed critical, as those registers directly control the ADC hardware on the AVR to switch between charging and discharging.
Without this, you are not measuring any capacitance. What you are measuring is probably a result of the different potentials of the ESP and your body. It will probably fail completely, if you keep touching the ESPs ground pin while touching the ADC. (I'm not an electrical engineer or physicist though, someone more qualified to answer this may correct me...)
User avatar
By shoelessone
#33118 Well thanks for all of the help lethe - I ended up going with your first recommendation. After stepping through your code (there are a few things that don't seem to have Arduino parallels) with my buddy, this is what we came up with in terms of code, in case it's helpful to anybody (or if you want to tell me if there are problems with it! :)):

Code: Select allconst int capSamples = 40;
const int capInputPin = 12;
const int threshHold = 2000;
bool touched = 0;
long lastTime = 0;

void setup() {
 Serial.begin(115200);
   pinMode ( capInputPin, OUTPUT);
   digitalWrite(capInputPin, LOW);
}

static bool checkTouch() {
   long riseTime = 0;

   //capSamples = int 20 - just the number of samples to take - adjust as desried
   for(int i = 0; i < capSamples; i++){

    //capInputPin = int 12 in my case, just the pin # to use
    pinMode(capInputPin, OUTPUT);
    digitalWrite(capInputPin, LOW);

    //This delay which may or may not need to be here.   
    delayMicroseconds(500);

    pinMode(capInputPin, INPUT_PULLUP);

    while(digitalRead(capInputPin) != HIGH){
      ++riseTime;
    }

   }
   //"threshHold" is some number that you will likely need to
   //experiment with. For 20 samples, somewhere around 1000
   //might be good.
   return (riseTime > threshHold);   
}


void loop() {
 
  if((millis() - lastTime) > 5000){
    if(checkTouch()){
      Serial.println("-----------------------TOUCHED------------------");
      lastTime = millis();
    }
  }
  Serial.println("other stuff happening here..");
 
}


Now I just have to make sure I can ground out pin 0 for programming!
User avatar
By shoelessone
#33122 Actually, simple follow up question:

in terms of using GPIO 0 for an LED "output" but also wanting to (maybe) re-program the board later, couldn't I just use GPIO 0 as a "normal" out put pin, but when/if I wanted to reprogram I would just make sure hte pain was grounded before starting up?

It seems that when the GPIO0 is grounded on bootup the board enters "programming mode" no matter what.. so if I did set the thing as an output in my setup() function or whatever, it wouldn't matter because the board would be put into programming mode before that?

Perhaps this is what you were sort of recommending already, but lethe you talked about "switching" the direction via circuit so LOW = LED on and HIGH = LED off, and like always I'm guessing there was some great reason for you suggesting this over simply connecting GPIO0 to ground and startup...