SoftAP rejects my wifi password always

I looked up WiFi.scan() and if I understood correctly it will only list the wifis but not connect to them. Id have to list them and compare each to the ones I have stored in my credentials, correct?

My idea is to WiFi.scan() and then for each wifi found do a getCredentials() and compare them. If there is a match then attempt to connect.

If I let it run to the end of loop it will blink green and “freeze” for a few seconds until it gives up, so I have to prevent this from happening. If no wifis found and I reach the end of the loop should I turn WiFi.off() and then back on once the loop started over?
Im not sure if all this is too complicated and there is a simpler way that lets me:

  1. keep the device responsive and sensing for as long as possible
  2. if wifi goes away, keep sensing and look for wifis (this is where the thread enable was handy, now I have to do it sequentially, right?)
  3. wifi scan takes only about 1 or 2 seconds, that is ok, but trying to connect takes about 20 or 30 seconds, this is not ok.
  4. once wifi is back, simply connect and upload the backed up messages.

Below is a code I intend to run if Particle.disconnected(), which I briefly check every second after reading my sensors.
The problem is that I dont know how to compare the sanned wifis with my credentials:

void wificheck(){
    Serial.println("wificheck()");
    
    flagwifi=1;   //to be used in other routines and prevent from being called too often
  
    
    if (!WiFi.ready())
    {   //if no wifi, then scan every minute or (x minutes) and compare to credentials, if match found connect 
        WiFi.disconnect();
        Serial.print("No wifi ");
       


        WiFiAccessPoint aps[20];
        int found = WiFi.scan(aps, 20);         //list available wifis
        for (int i=0; i<found; i++) {           //for each found, check if it is known and connect
            WiFiAccessPoint& ap = aps[i];       //no idea what this is
            Serial.print("SSID found: ");
            Serial.println(ap.ssid);            //this is taken from https://docs.particle.io/reference/device-os/firmware/photon/#scan-)
            
            //// get credentials and compare them /////
           // WiFiAccessPoint ap[5];              //list all credentials and compare to the current ssid found
           // int creds = WiFi.getCredentials(ap, 5);
           // for (int j = 0; j < creds; j++) {
               // Serial.print("ssid: ");
           //>>>this does not work    if(ap.ssid==ap[j].ssid){Serial.print(" and it is known! Connecting...");
            //        WiFi.connect();
            //   }
             //  else 
             //  {
             //      Serial.println(" not known");
             //  }
             
            //}
        } 
    }
    
    if (WiFi.ready()){ 
        
        Particle.connect();
        if (Particle.connected()) {Particle.process();flagwifi=0;}
    }
}

Uhm, no! You can do a WiFi.getCredentials() and WiFi.scan() once and then compare each found entry in one list with each found entry in the other list - WiFi.getCredentials() will only give you a list of up to 5 credentials on a Photon, the five SSIDs for that can easily be remembered in a local array for all networks the scan will return.

And only try to connect when you found a match. If not, I’d call WiFi.off().

C/C++ strings (aka char arrays) cannot be compared via the == equality check. You should rather use strcmp().

BTW, I’d use the callback version of WiFi.scan() in case you find yourself in a crowded area with an unknown number of possible networks around you. For that you can keep your stored WiFi credentials in a global array (or local to the calling function an passing in via the void* data parameter).

1 Like

I have successfully implemented a Wifi checking code that does not block my code without the need for thread enable. =)


void getcreds(){
    WiFiAccessPoint ap[5];
    int found = WiFi.getCredentials(ap, 5);
    for (int i = 0; i < found; i++) {
        Serial.println("wifi credentials: ");
        Serial.print(i);Serial.print(". ");
        Serial.println(ap[i].ssid);
        cred[i]=String(ap[i].ssid);
    }
}
void wificheck(){
    Serial.print("wificheck...");
    //Serial.println("wifi ON");
    WiFi.on();
    
    if (Particle.connected())
    {
        Particle.process();
        if(flagwifi==2) //this is for publishing backups asap
        {
            publishnow=0;    Serial.println(" force publish now");
            flagwifi=0;
        }
    }
    else 
    {  
        flagwifi=1;
        Serial.println("Scanning wifis...");
        WiFiAccessPoint aps[20];
        int found = WiFi.scan(aps, 20);         //list available wifis
        for (int i=0; i<found; i++) {                 //for each found, check if it is known and connect
            WiFiAccessPoint& ap = aps[i];       //no idea what this is
            Serial.print("SSID ");Serial.print(i);Serial.print(": ");
            Serial.println(ap.ssid);            //this is taken from https://docs.particle.io/reference/device-os/firmware/photon/#scan-)

            for(int j=0;j<5;j++){
                if(cred[i].equals(String(ap.ssid)))             //from https://community.particle.io/t/how-to-compare-string-with-char/3929
                {
                    Serial.println (" ^ match!! connecting..."); 
                    j=5; 
                    i=found;
                    WiFi.connect();
                    Particle.connect();
                    publishnow=0; flagwifi=2;
                }
            }
        }
    }//end if !wifi.ready
    
    if (WiFi.ready()){ 
        Particle.connect();//Serial.println("particle connect");
        if (Particle.connected()) {Particle.process();Serial.println("System online");flagwifi=0;}
    }
    else
    {
        WiFi.off();
    }
    
}//end wificheck

thanks @ScruffR

The next step is to optimize the backup section so that it consumes less memory and makes the use of softAP more reliable.

This is what I have now:

#define ARRAYSIZE 200
String backup[ARRAYSIZE];
String payload;


void onlinecheck()
{
    if (Particle.connected()) {             //if internet, send backups every delay until finished
        Particle.process();
        Serial.println("INTERNET OK!!");
        digitalWrite(ledred,LOW);
        digitalWrite(ledgreen,HIGH); //green

        counterstatus++;
        if (counterstatus>9999){counterstatus=0;}
        unsigned int intcounterstatus=counterstatus;
        counterstatus=intcounterstatus;

        if(backupcounter>0){
            for(int o=0;o<ARRAYSIZE;o++){ 
                if(backup[o] != "x"){      //previously the entire array was set to "x"
                    delay(200);
                    String id = System.deviceID();
                    Particle.publish(String(id.c_str()), backup[o] , PRIVATE);
    
                    Serial.println("");Serial.print("backup: ");Serial.print(o);Serial.print(" sent!  Remaining: "); Serial.print(backupcounter-1);  //sorry for bad style, will fix it later
                    freemem = System.freeMemory();
                    Serial.print("  free memory: ");  //checking ram
                    Serial.println(freemem);
                    Serial.println(backup[o]);
                    backup[o]="x";
                    Particle.process();
                    backupcounter--;
                    delay(200);  //is it too fast to send backups every 400ms?
                }
            }
        }
    }

    else {                   //if no internet store backup 
    
     
        Serial.println("");
        Serial.println("NO INTERNET!!");

        updatecurrentTime(); //get time in epoch format
        
        counterstatus++;
        if (counterstatus>9999){counterstatus=0;}
        unsigned int intcounterstatus=counterstatus;
        counterstatus=intcounterstatus+0.1;
                     
        for(int o=0;o<=ARRAYSIZE-1;o++){
            
            if(backup[o]=="x")
            {
                String id = System.deviceID();
                payload = String::format(  "{\"Timestamp_Device\":\"" + String(currentTime) + "\",\"device_id\":\"" + String(id.c_str()) +  "\",\"temp\":\"" + String(flowtemp1) + "\",\"flowshort\":\"" + String(flowtotal) +  "\",\"flowacum\":\"" + String(flowacum) + "\",\"vbat\":\"" + String(vbat) + "\",\"counterstatus\":\"" + String(counterstatus)+"\"}");
                backup[o] = payload;
                backup[o+1]="x";
                Serial.print("backup: ");Serial.print(o);Serial.print(" saved:  "); 
                Serial.print(backup[o]); Serial.println(" ");
                
                if(o==ARRAYSIZE-3){                 //if array full, delete it. this should only replace first entry and so on
                    cleanbackup();   //this sets the entire array to "x"
                    backupcounter=0;
                }
                else { o=ARRAYSIZE+1; }
                backupcounter++;
                
                freemem = System.freeMemory();
                Serial.print("free memory: ");
                Serial.println(freemem);
            }
        }
    }//end else
}//end onlinecheck

So I want to implement your recommendations from: Photon working both online and offline but the coding level is a bit too advanced for me, so I will try it but I will most probably get stuck. Any recommendations on how to proceed? The idea is to have as many backups available as possible without risking the stability of the system.
thanks

1 Like