RedBear Duo restart when change WiFi network

Hi,

I am trying to define the WiFi settings dynamically, so i am passing the information over the serial, process the data and call the functions below.

WiFi.on(); // WIFI_CONNECT_NO_LISTEN is not available in WEB IDE for Duo!! :(
WiFi.clearCredentials();
WiFi.setCredentials(ssid, pass); // The credentials are ok!    
WiFi.disconnect();
WiFi.connect();
long int start = millis();
while ( !WiFi.ready() && millis() - start < TIMEOUT_CONNECTION ) {};

// Verify connection
if ( WiFi.ready() ) 
{
    Serial.println("OK");
}else{
    WiFi.listen(false);
    WiFi.off();
}    
return;
  1. If the credentials are OK, it prints the “OK” and the board restart, loosing the current serial connection.
    Is it possible to configure this ‘new’ network without restarting the board?

  2. If the credentials are wrong, the board keeps trying the connection, executing the loop() with huge interval of times, so I turn off the WiFi to avoid this.
    Is it possible to stop trying the connection (for the loop() execution come back to normal)?

Not an answer to your question yet, but did you know this one

  if (waitFor(WiFi.ready, TIMEOUT_CONNECTION))
    // got ready in time
  else
    // timed out

Should be, but haven't tested with RedBear Duo yet.

What SYSTEM_MODE() are you using?
Are you using SYSTEM_THREAD(ENABLED)?

AFAIK a max retry setting for connection attempts is implemented in the most recent Particle firmware, but I don't know what version RedBear used as their basis.

Hi @ScruffR,

I did not know this one!

I am using SYSTEM_MODE(MANUAL).
I am not using the SYSTEM_THREAD(ENABLED) (i did not know this command). But using it, when I scan the WiFi networks (for example) sometimes the Duo stops, flashing the led in red color accusing Hard fault, or just stop to respond in the serial.

Have you got some short test sketch for me that exhibits this behaviour to flash it to one of mine and also try it on a Particle?

Hi @ScruffR,

Here is some example of the code that I made in the Arduino IDE. In this case, compiling in the Arduino IDE the board did not restart, but entered in listening mode sometimes.

TCPClient client;

// Para se conectar em uma nova rede, é necessário alterar para manual, para que a placa ntre no setup
SYSTEM_MODE(MANUAL);

void printWifiStatus();

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  
  WiFi.on();
}

void print_credentials(){
  Serial.print("Credential:");
  if( !WiFi.hasCredentials() ) return;

  WiFiAccessPoint ap[5];
  int found = WiFi.getCredentials(ap, 5);
  for (int i = 0; i < found; i++) {
	  Serial.print("ssid: ");
	  Serial.println(ap[i].ssid);
  }
}

bool make_connection(){
	WiFi.on();
	delay(500);
	WiFi.connect();    
	Serial.println("Make connection");
	
	if ( waitFor(WiFi.ready, 1000) ) 
	{
		return true; // I return a success message from Serial
	}
	else
	{
		WiFi.disconnect();          // Redundância
		WiFi.listen(false);         // Desabilita o Listening mode
		WiFi.off();
		return false;// I return a error message from Serial
	}
}

void loop() {
  if(Serial.available()){
	switch((char)Serial.read()){
	  case 'a':
		Serial.println("CONN1 - RIGHT");
		WiFi.clearCredentials();
		WiFi.setCredentials("right_name" , "pass");
		make_connection();
		break;
	  case 'b':
		Serial.println("CONN2 - WRONG");
		WiFi.clearCredentials();
		WiFi.setCredentials("wrong_name","pass");
		make_connection();
		break;
	  case 'c':
		print_credentials();
		break;
	}
  }
}

My code in Particle IDE follows almost the same workflow, I receive the data from Serial and then I attempt to connect with the received data, using the code in the question.

I spent some time today to map all reactions:

  • With no Credentials stored, cleaning up, and setting a wrong credential: Normal
    behavior(keeps everything working) and some times enter in listening
    mode.

  • With a right credential stored, cleaning up, and setting a wrong credential: Some
    times it enters in listening mode and some times in the else
    statement of the waitFor(WiFi.ready,.

  • With a wrong a credential stored, cleaning up, and setting a wrong credential:
    happens the same thing above. And setting a right credential, the
    board restarts.

I hope it can help you to understand better my problem.

I think there is a problem with the docs
They state

But it doesn't build for Photon either, so I'll have a look how it really works and that should work on RedBear Duo too.


Update:
It's actually WIFI_CONNECT_SKIP_LISTEN and does build for RedBear Duo too.
I'll update the docs accordingly

1 Like

@leoguima, I’ve played about a bit and came to the conclusion that this seems to be a RedBear issue, which should be best discussed in their forum, since the Photon I was trying the same code with works fine (no unintended Listening Mode and no reboot after successful connect).
One thing to note her is, that setCredentials() will not store the credentials if that respective network can’t be found unless you provide the credentials including auth scheme and WLAN cipher.
Hence I’ve altered your code into this (additional options ‘A’ and ‘B’, and also a cloud connect with anything else once WiFi connected for OTA flashing)

SYSTEM_MODE(MANUAL);

void printWifiStatus();

void setup() {
  WiFi.on();
  Serial.begin(115200);
}

void print_credentials() {
  Serial.println("Credentials:");
  if(!WiFi.hasCredentials()) 
  {
    Serial.println("  none");
    return;
  }

  WiFiAccessPoint ap[5];
  int found = WiFi.getCredentials(ap, 5);
  for (int i = 0; i < found; i++) {
    Serial.print("  ssid: ");
    Serial.println(ap[i].ssid);
  }
}

bool make_connection() {
  uint32_t ms;
  RGB.control(false);
  ms = millis();
  WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
  Serial.print("WiFi.connect(...)");

  if ( waitFor(WiFi.ready, 10000) ) {
    Serial.printlnf(" success after %dms", millis()-ms);
    return true; 
  }

  Serial.println(" fail!");
  WiFi.off();
  RGB.control(true);
  RGB.color(0x40,0x40,0x40);  // dim gray
  return false;
}

void loop() {
  if(Serial.available()){
  switch((char)Serial.read()) {
    case 'a':
      Serial.println("CONN1 - RIGHT");
      WiFi.on();
      WiFi.disconnect();
      WiFi.clearCredentials();
      WiFi.setCredentials("correctSSID" , "correctPWD");
      make_connection();
      break;
    case 'b':
      Serial.println("CONN2 - WRONG");
      WiFi.on();
      WiFi.disconnect();
      WiFi.clearCredentials();
      WiFi.setCredentials("wrongSSID", "wrongPWD");
      make_connection();
      break;
    case 'A':
      Serial.println("CONN1 - RIGHT with Auth/Cipher");
      WiFi.on();
      WiFi.disconnect();
      WiFi.clearCredentials();
      WiFi.setCredentials("correctSSID" , "correctPWD", WPA2, WLAN_CIPHER_AES);
      make_connection();
      break;
    case 'B':
      Serial.println("CONN2 - WRONG with Auth/Cipher");
      WiFi.on();
      WiFi.disconnect();
      WiFi.clearCredentials();
      WiFi.setCredentials("wrongSSID","wrongPWD", WPA2, WLAN_CIPHER_AES);
      make_connection();
      break;
    case 'c':
      print_credentials();
      break;
    default:
      if (WiFi.ready())
        Particle.connect();
  }
}
  
  if (Particle.connected())
    Particle.process();
}

In your original code you also had the problem, that you were not able to store new credentials once you ran into a condition that caused WiFi.off() which contributed to your Listening Mode problem.
That’s “corrected” in my code too.

Hi @ScruffR,

Really thanks for your attention! I just opened a question on their forum!

1 Like

Just to close the loop on this