Connect Particle to Wifi in code

Can I code a wifi connection to a photon?

@weftech, can you describe what you mean in more detail?

I’m shipping 5 photons to different locations which all have different wifi networks. When they arrive I need them to auto connect to the the wifi at that office. I have the SSID and password for all locations. but can not determine how to get them to auto connect.

You can do that in code, which is described in the docs. Have a look :wink:

https://docs.particle.io/reference/firmware/photon/#setcredentials-

1 Like

For your use case you need to use the four-parameter version of `WiFi.setCredentials()’ which also takes the WLAN cipher (which you need to know too)
e.g.

WiFi.setCredentials("SSID", "PASSWORD", WPA2, WLAN_CIPHER_AES));

But you can also use

particle serial wifi

or any serial terminal with the ‘w’ comnand in Listening Mode (both without scanning for the target network)

After setting SSID and the encryption type you’ll be prompted for the WLAN cipher if the network can’t be found.

1 Like

@weftech, beyond what @ScruffR and @RWB said, do keep in mind that running WiFi.setCredentials() on every boot is not ideal. You can ensure that it only runs once by a) Making sure that prior to running the firmware the first time, all WiFi credentials are wiped and then b) using WiFi.hasCredentials() to set the credentials only on the first run:

// Assume all WiFi credentials have been wiped
if (!WiFi.hasCredentials()) {
  // No wifi credentials so set them on first run.  Further runs will skip this
  WiFi.setCredentials("SSID", "PASSWORD", WPA2, WLAN_CIPHER_AES);
}

:wink:

3 Likes

So that would look something like this?

void setup(){
  WiFi.clearCredentials();
  if (!WiFi.hasCredentials()) {
    // No wifi credentials so set them on first run.  Further runs will skip this
    WiFi.setCredentials("TEST", "6502893400", WPA2);
  }

}

void loop(){
  digitalWrite(D7, HIGH);
  delay(1000);
  digitalWrite(D7,LOW);
}

@weftech, you can’t put the WiFi.clearCrendentials() there since it will always clear the credentials and the credentials will always be set! The easiest way to clear credentials without code is to hold the SETUP button down unit you get a rapid flashing blue color on the RGB LED. Then on the next reset, the credentials will be set only once. Does that make sense?

1 Like

Just to reiterate: Why would you need to put that in code when ...

Hi -

I am facing this same situation. I would like to preset the WiFi credentials on behalf of the client so that no setup is required when products arrive at client. Would the best then be to go with peekay’s solution? Standard WPA2 security on the network the device will be connecting to.

Just one more question please? Can I then add networks afterwards if need be, or will this affect anything?

Regards.
Friedl.

You can go with peekay’s solution and yes, you can add other credentials afterwards as long you don’t call WiFi.clearCredentials() in your code.

Thanks, noted. I will add the following in SETUP;

if (!WiFi.hasCredentials()) {
WiFi.setCredentials(“test_SSID”, “test_PASSWORD”, WPA2);
}

Of course this will only work after clearing all existing WiFi credentials. From this I gather the existing connection will still function until such time that I clear them correct? I noticed another article mentioned the Photon should be put in semi automatic mode outside of SETUP first by adding;

SYSTEM_MODE(SEMI_AUTOMATIC);

Is this necessary?

Kind Regards,

Hard to say what the context of that statment was, but I don't think it's required.
However, when the device is expected to run without valid WiFi credentials you need to use a non-AUTOMATIC SYSTEM_MODE() or SYSTEM_THREAD(ENABLED).
Without either of these your code will never start running and hence never execute the WiFi.setCredentials() function.

Hi ScruffR -

I managed to get the Particle.publish command working, or sort of. My code compiles but I am receiving a NULL value in return,. Obviously there is. problem in compiling my STRING, would appreciate if someone can assist?

String UID = "";
    
     for (byte i = 0; i < RC522.serNum[i]; i++) {
     UID += String(RC522.serNum[i] < 0x10 ? "0" : "");
    //   Serial.print(RC522.serNum[i],HEX);
     }
     
        Particle.publish("rfid-read", UID, PUBLIC);
        Serial.println();
  }

– Update end –

Thank you for the timeous response. As I am moving the project over from NodeMCU and Arduino environment, I would like to try and do so with least possible changes so maybe best to hard code the credentials or set up WiFi on site?

I am busy looking into how Photon handles PubSubClient I used in the Arduino environment. still deciding on whether I will use MQTT server for this particular application, to try and post directly to mySQL. Seems security might be an issue on the latter.

Thanks for the help (and patience with a newbie) so far :slight_smile:

You should Serial.print(UID) to see what you actually send but this statement doesn’t seem correct to me

for (byte i = 0; i < RC522.serNum[i]; i++) 

the condition seems rather random - how would the length of serNum correlate with the contents?

Hi Scruff -

I borrowed the code below;

String UID = "";

     for (byte i = 0; i < mfrc522.uid.size; i++) {
       UID += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
       UID += String(mfrc522.uid.uidByte[i], HEX);
     }

As I am not using the MFRC522 library but RFID.h one instead, I tried editing the code to the best of my capabilities, but no luck. The Serial.print(UID) returns 00000

The alternative is to work with the code below:

/* Output the serial number to the UART */
    for(i = 0; i <= 4; i++)
    {
      Serial.print(RC522.serNum[i],HEX);
      Serial.print(" ");
    }
    Serial.println();

This returns the correct information (with the exception of two extra digits at the end which I suppose I can ‘trim’) but I am not sure how to compile the string to get the favoured result to publish.

Many thanks!

What do you get and what do you expect?
This would help understand what data you are dealing with (without needing to know the RC522 library).

Once you know how many for the fields of RC522.serNum[] you need and in what form, you could try something like this

  char str[16];
  snprintf(str, sizeof(str), "%02x %02x %02x", RC522.serNum[0], RC522.serNum[3], RC522.serNum[2]);

Hi Scruff -

What do you get and what do you expect?
This would help understand what data you are dealing with (without needing to know the RC522 library).

I need the UID for each card scanned. Usually the format is i.e AB 12 CD 34. Here is my loop in the Arduino version, of course utilising the MFRC5222.h library and not the RFID.h and posting too MQTT server as apposed to Particle Cloud.

void loop()
  // Look for new cards
{

client.loop();
  delay(500);
  client.publish("topic/on/broker", "I'm here!");
  
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been read
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  wait_tick = millis();
  
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

  printHex(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();

  delay(250);

  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();


char IncomingString[30];

for(int i=0; i<sIncomingString.length();i++){
   IncomingString[i] = sIncomingString.charAt(i); 
}


IncomingString[sIncomingString.length()-1] = NULL;

if (client.publish(topic, IncomingString)) {
      Serial.println("Publish ok");  
      digitalWrite(bluePin, LOW);
      digitalWrite(greenPin, HIGH);
      delay(1000);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, HIGH);   
    }
    else {
      Serial.println("Publish failed");
      digitalWrite(bluePin, LOW);
      digitalWrite(redPin, HIGH);
      delay(2000);
      digitalWrite(bluePin, HIGH);
    }

Serial.print("UID: ");
Serial.println(IncomingString);
}

Many thanks, Friedl!

If you want to get AB 12 CD 34 then this code should give you exactly that

  char str[16]; 
  snprintf(str, sizeof(str)
          , "%02X %02X %02X %02X"
          , RC522.serNum[0]
          , RC522.serNum[1]
          , RC522.serNum[2]
          , RC522.serNum[3]
          );
  Particle.publish("rfid-read", str, PRIVATE);
1 Like