It takes 3 times to enter listening mode every time

In my application, I need to press a user button to enter the listening mode (not those two on the photon board). But every time I have to do this for three times to enter listening mode.

For the first two times, it did goes to the listening mode. But after 2 seconds of blinking blue, it jumped out of listening mode and connect itself to the internet. And it always takes two times failure and stays in listening mode at the third time.

I thought it was my interrupt button decoding. But now Im using the following code from :

I am still getting this problem.

#include "application.h"

void prepare();
void ISR();
//SYSTEM_THREAD(ENABLED)
SYSTEM_MODE(SEMI_AUTOMATIC)
// STARTUP(prepare())

// #define DEBOUNCE      5
#define DEBOUNCE      50
#define SHORTPRESS 1500
#define LONGPRESS  3000
#define DBLTAP     1500

// const int pinIRQ = D6;
const int pinIRQ = P1S2;

// volatile uint32_t blinkPattern = 0x88;
volatile uint32_t msTrig;    // when was last reliable trigger
volatile uint32_t msPress;   // when was the last press/hold
volatile uint32_t msRelease; // when did it get released
volatile uint32_t msHeld;    // how long was it held
volatile uint32_t msDblTap;  // how much time since last release

void ISR()
{
  if (millis() - msTrig <= DEBOUNCE) return;
  msTrig = millis();
  
  if (!digitalRead(pinIRQ))
  { // PRESSED
    msPress = msTrig;
    msDblTap = msPress - msRelease;
    msRelease = 0;
    if (msDblTap > DBLTAP)
      msDblTap = 0;
  }
  else
  { // RELEASED
    msRelease = msTrig;
    msHeld = msRelease - msPress;
    msPress = 0;
    // ******************** range check for hold time *********************
    if (DEBOUNCE < msHeld && msHeld < SHORTPRESS)
    {
      if (!WiFi.listening())
      {
          // WiFi.clearCredentials();
          Particle.disconnect();
          WiFi.listen();
      }
      else
      {
          WiFi.listen(false);
          Particle.connect();
      }
    }
    else if (SHORTPRESS < msHeld && msHeld < LONGPRESS)
      // blinkPattern = 0x80;
      ;
    else
    {
      // blinkPattern = 0x88;
      ;
    }
    // ********************************************************************
  }
}

void prepare()
{
    pinMode(D7, OUTPUT);
    pinMode(pinIRQ, INPUT_PULLUP);
    attachInterrupt(pinIRQ, ISR, CHANGE);
    Particle.connect();
}

void setup() 
{
  prepare();
}

void loop() 
{
  uint32_t msHold;
  uint8_t  factor = 0;
  
  if (msPress)
  { // feedback during hold
    msHold = millis() - msPress;
    factor = 4;  // dim the LED
  }
  else // after release
    msHold = msHeld;
    
  // ******************** range check for hold time *********************
  // if (DEBOUNCE < msHold && msHold < SHORTPRESS)
  // {
  //   RGB.control(true);
  //   RGB.color(0, 0, 255 >> factor);
  // }
  // else if (SHORTPRESS < msHold && msHold < LONGPRESS)
  // {
  //   RGB.control(true);
  //   RGB.color(255 >> factor ,128 >> factor, 0);
  // }
  // else
  //   RGB.control(false);
  // ********************************************************************

  // digitalWrite(D7, (millis() >> 2) & blinkPattern);    
}

Thank you very much guys!

@codemonkeyboris, you shouldn’t be calling Particle.disconnect() or WiFi.listen() or similar functions from your ISR. Instead, set a flag that you poll in loop(). You could also use the clickButton() library for detecting your button push from loop().

1 Like

@peekay123. Yes I tried that before. I also tried using a button decoder without interrupts and it works the same-- always jumps out of listening for the first 2 times.

1 Like

@codemonkeyboris, you might want to consider a delay after Particle.disconnect(). You should also make sure Particle.connect() completes or add tests for Particle.connected() where necessary. You MUST remove this code from your ISR.

1 Like

I tried your suggestion. It still quits listening by itself for the first two times.

I also tried buttonmirror the SETUP/MODE to my user button and that works out! But all I couldn’t put other functions to my user button.