Core code won't compile "WLAN_SERIAL_CONFIG_DONE not declared in this scope"

This code compiled last week, now it doesn’t. My code is below, this is in the application.ino file. The ISR is in the SparkInterval timer written by peekay. This feature allows me to exit and enter listen mode after timeouts. What happened??? I double checked my version control and there have been no changes to the code in over a month.

/////////////////////////////////////////////////////////////////////
//name: si_sparkconn_isr
//desc: this function is placed in an interrupt service routine
//      This is needed because the WiFi.listen() is blocking and
//      only an interrupt vector can check these flags
//args: none
//returns: none
//notes: if features are added check that functions are just checking
//      flags not calling other functions.  If other functions (like
//      Spark.connect() or WiFi.listen() should only be called from
//      the "loop()")
//author: jerome verhoeven
//date: 2/23/2015
/////////////////////////////////////////////////////////////////////
void si_sparkconn_isr (void)
{
  isr_loop_count++;
  if(current_mode == listen_mode)
  {
    if(WiFi.listening()
        && (isr_loop_count >= (listen_timeout / (TIMER_INTERVAL / 2000))))
    {
      WLAN_SERIAL_CONFIG_DONE = 1;
      fire_connect = 1;
      isr_loop_count = 0;
    }
    else if(!WiFi.listening()) //this catches the user entering the wrong wifi credentials during listening mode.
    {
      fire_connect = 1;
      isr_loop_count = 0;
    }

  }
  else if(current_mode == connect_mode)
  {

    if(WiFi.listening())
    {
      current_mode = listen_mode;
    }
    else if(!Spark.connected())
    {
      if(isr_loop_count >= (connect_timeout / (TIMER_INTERVAL / 2000)))
      {
        fire_listen = 1;
        isr_loop_count = 0;
        status_log(CONNECT_MODE_TIMEOUT);
      }
      else
      {
        fire_connect = 1;
      }
      fire_udp_reset = true;
    }
    if(Spark.connected()) isr_loop_count = 0; //if we are connected reset the loop counter
  }

In the IDE, you can click on your devices drawer, and expand the arrow next to the device. This will display a dropdown box that allows you to select the firmware version. You can revert to 0.3.4 to go back to the previous version.

Alternatively, you can use the new API to exit listening mode WiFi.listen(false) will cause the device to exit listening mode.

The system flags are internal to the device and we will be replacing these going forward with corresponding public APIs so that they are documented and understood!

2 Likes

I can’t find this… Is this only in the webIDE? Or am I missing something? I use the particle console IDE on a mac. Thanks for the tip on the WiFi.listen(false). I will give that a whirl. Can you think of any reasons (bugs) that I would introduce replacing WLAN_SERIAL_CONFIG_DONE = 1 with WiFi.listen(false). I won’t really have a lot of time to test, as we are deploying product.

UPDATE: I changed out the WiFi.listen(false) but now I get

wombat.cpp:135: undefined reference to `Wiring_TIM2_Interrupt_Handler'
wombat.cpp:135: undefined reference to `Wiring_TIM3_Interrupt_Handler'
wombat.cpp:135: undefined reference to `Wiring_TIM4_Interrupt_Handler'

I didn’t write a wombat.cpp file (our project is call wombat.ino). Anyway I assume this has something to do with peekay’s SparkInterval library?

Thanks in advance

Jerome

What is your code now to switch between connect and listen?

for those playing at home, this modified code works:

/////////////////////////////////////////////////////////////////////
//name: si_sparkconn
//desc: calls functions that put the sparkcore in listen for wifi
//      credentials mode, and try to connect to the spark cloud
//      respectively.  Spark.connect() specifically should not be
//      called from an isr.
//args: none
//returns: none
//notes: must be placed in the "loop" function
//author: jerome verhoeven
//date: 2/20/2014
///////////////////////////////////////////////////////////////////
void si_sparkconn (void)
{
  if (fire_listen == 1){
      Serial.println("starting listen mode");
      fire_listen = 0;
      fire_connect = 0;
      isr_loop_count = 0;
      WiFi.disconnect(); // to enter listen mode more quickly
      WiFi.listen(true);
      current_mode = listen_mode;

      // Flag to toggle whether the ISR has processed yet
      fire_run = 1;


  }
  else if (fire_connect == 1){
      Serial.println("starting connect mode");
      fire_listen = 0;
      fire_connect = 0;
      isr_loop_count = 0;
      WiFi.listen(false);
      Particle.connect();
      current_mode = connect_mode;

      // Flag to toggle whether the ISR has processed yet
      fire_run = 1;

      // red, green, blue, 0-255.
      // the following sets the RGB LED to emerald green:
  }

  /*
  if (fire_run == 1){
      Serial.println("a fire run WAS TRIGGERED");
  }
  */



  if (fire_run == 0 && isr_loop_count == 0){
    RGB.control(false);
  }
  /*
  else if (isr_loop_count > 2000){
    isr_loop_count = 0;
  }
  */
  return;
}

/////////////////////////////////////////////////////////////////////
//name: si_sparkconn_isr
//desc: this function is placed in an interrupt service routine
//      This is needed because the WiFi.listen() is blocking and
//      only an interrupt vector can check these flags
//args: none
//returns: none
//notes: if features are added check that functions are just checking
//      flags not calling other functions.  If other functions (like
//      Spark.connect() or WiFi.listen() should only be called from
//      the "loop()")
//author: jerome verhoeven
//date: 2/23/2015
/////////////////////////////////////////////////////////////////////
void si_sparkconn_isr (void)
{

  if (current_mode == connect_mode) {
    // Are we currently connected
    if (Particle.connected()){
      // If we are actually connected, reset the loop, everything is good
      isr_loop_count = 0; // reset so if it fails it doesn't trip
    }
    else { // not connected
      isr_loop_count++;
      // See if we're still not connected after the cycle timeout
      if (isr_loop_count >= connect_timeout_cycles) {
          // Trigger a listen cycle
          fire_listen = 1;
      }

      // Are we accidentally listening when meant to be connecting?
      if(WiFi.listening() && fire_run == 0){
          fire_connect = 1;
      }
    }

  }
  else if(current_mode == listen_mode) {
    isr_loop_count++;

    //WiFi.listen(true);
    if(WiFi.listening() && isr_loop_count >= listen_timeout_cycles){
        //WiFi.listen(false);
        fire_connect = 1;
    }
		else if(!WiFi.listening() && fire_run == 0) //this catches the user entering the wrong wifi credentials during listening mode.
    {
      // Perhaps the mode wasn't triggered correctly
      fire_listen = 1;

    }
  }

  // Flag that we've looped
  fire_run = 0;

  return;

}

I know the above code is working 110% for me, it’d require more effort to compare/contrast against the original, but pretty sure there are some gotchas I’ve fixed.
One of the key hurdles was the code in the setup:

    si_sparkconn();
    delay (10);
    conn_timer.begin(si_sparkconn_isr, 30000, hmSec);
    delay (10);
    // ** REALLY ** important for this to be after the timer above is started
    // Otherwise it will never trigger
    fire_connect = 1;
    Particle.connect();

If you particle.connect before you start your interrupt timer then you’ll be waiting a long time for it to interrupt! :wink:

The other trick of note: Don’t use long delay() in your loop, as it could mean an interrupt has run but your main loop hasn’t called sparkconn yet! Use an elapsed millis comparison to the time now and save the time - general practice when you have multiple timer cycles going on in your loop() but worth noting as any long delays (ie 10secs) could mean you aren’t detecting the ISR counter in a timely fashion.

incidentally, found a bug with switching between particle.connect & wifi.listen - the RGB color doesn’t change. Took me a while to realise based on debugs and running wifi diagnostic scan that the softap was actually being turned on!