Can a P1 be setup to connect to the internet without claiming it?

Hello,
I have a brand new P1 and is soldered to expose the pins. I put the P1 in bootloader mode (flashing yellow). I am flashing my code using dfu-util. At this point the P1 is not associated with any account or it’s been connected to any WiFi before. My code is as follows:

#define WIFINAME "xxxxxxxxxx"
#define PASSWORD "yyyyyyyy"

SYSTEM_MODE(MANUAL)

void setup() {

    WiFi.on();    
    if(WiFi.hasCredentials())
    { 
        WiFi.clearCredentials(); 
    }
    WiFi.setCredentials(WIFINAME, PASSWORD);
    Particle.connect();
}

void loop() {
    if(Particle.connected() == false){
        Particle.connect();
    }
    
    Particle.process();
    delay(1500);
}

This clears the existing WiFi credentials, sets the new WiFI credentials and connects to the cloud.

This works on the P1’s which are already claimed. But when I do this on a new P1, the device seems to download the code using dfu-util over USB but it doesn’t connect to the cloud after that. It stays in the particle setup mode.

Is there anyway to connect the device to the internet without claiming it?

Thank you
Dheeraj

1 Like

You will need to setup wifi credentials first using particle setup or particle serial wifi

2 Likes

I’d have to do some tests, but I think this should work for unclaimed devices just as well, so I doubt you need to go through particle setup and particle serial wifi

Maybe you could try this after you’ve stored the credentials

  delay(100);
  WiFi.off();
  delay(100);
  WiFi.on();

And to prevent the device from going into Listening Mode you could also give this a try

SYSTEM_THREAD(ENABLED)
STARTUP(WiFi.off())

But I would also advise against the unconditional clearing and re-setting of credentials in setup() and when setting credentials I’d rather suggest you use the four-parameter overload which will also work if the respective network is not currently available.

And instead of retriggering a Particle.connect() every 1500ms I’d change your reconnect logic to this

void loop() {
    if(!Particle.connected()) {
        Particle.connect();
        waitFor(Particle.connected, 30000);
    }
  
  Particle.process();
}
2 Likes

Thanks. This did it. Any idea why particle serial wifi should be called first? Why not use the code which I posted to configure WiFi over dfu-util?

My code works after I configure my P1 using particle serial wifi initially.

I tried all the suggestions in here.

Flashed the following firmware to Photon over serial in order to set WIFI credentials but the Photon stays in listening mode even after the fware has been flashed.

the only way to get it out of listening mode involves running particle serial wifi or particle setup. why is this?

SYSTEM_THREAD(ENABLED);

STARTUP(WiFi.off());

void setup() {

    WiFi.clearCredentials(); 
    delay(750);
    
    WiFi.setCredentials("myssid","mypassword",WPA2,WLAN_CIPHER_AES_TKIP); 
    
    delay(750);
    WiFi.off();
    delay(100);
    WiFi.on();
}

void loop() {

}

is there any other way of sending wifi credentials directly to photon through a batch process (without user typing it). it doesn't look like 'particle serial wifi' accepts any credentials as command line arguments.

I noticed that my photon was on older system firmware version.

So I tried it again

  1. updated system firmware first using particle update.
  2. flashed by dummy firmware containing wifi credentials over serial to the photon (particle serial flash )

This time the photon did connect to wifi autoatically after the firmware was flashed to it.

In order to use set or clear credentials on the WiFi module it has to be on. That’s why the OP had the WiFi.on() command in place to begin with.

The hint about WiFi.off() was for the particular demand to prevent the device from immediately falling into Listening Mode, but won’t work well with the credential clearing/setting.

Also when opting for WiFi.off() (or other non-cloud modes) it’s advisable to use SYSTEM_MODE(SEMI_AUTOMATIC) too.

Let me poke at this problem again. I’ve discussed this before, but since @dheerajdake has the exactly same problem that I have and the thread offers no solution, I’ll revive this rather than starting a separate thread. I have discussed this before, but I eventually had to register all the units in my first batch of P1 based custom boards. Now I’ve just received another batch of 60 units and can do more testing on this.

My ideal setup is to flash a single -bin file via Serial to the device that will set default Wifi credentials as soon as the software runs. After some physical tests of the PCB, the firmware will then register itself with a special endpoint on our cloud service and write the returned config to the P1 external Flash memory so it’s always there upon startup. Ideally, I could also make the board claim itself to our account, but for now I’m just having it print the claim-command to serial so the operator can cut and paste this. It’s not ideal, but it works.

I’ve tried making such automated setups before without success and I’ve now also tried what @ScruffR suggested above without success. Just as the others, I cannot prevent the board from entering Setup Mode. It seems the reason is that even before any user code is executed, there is a check in the Particle Firmware that says something like “if you don’t have wifi credentials, don’t try to execute the user software”.

We do not want to set up many hundred boards manually, so using the app or CLI to set up wifi is out of the question.

Here’s what I’ve tried:

  • Just checking with WiFi.hasCredentials() has no effect since it won’t be executed unless there already are some credentials set.
  • Using SYSTEM_THREAD(ENABLED) has no effect. User code is still not executed.
  • Setting SYSTEM_MODE(SEMI_AUTOMATIC) (or setting it to anything else) has no effect. User code is still not executed.
  • Using STARTUP(WiFi.off()) has no effect. User code is still not executed and as far as I can see, you cannot use WiFi.setCredentials unless Wifi is operating.

Ideas:

  • If the Particle CLI supported setting wifi credentials as a one-liner, I could easily make a script that first set the credentials and then flashed the setup firmware. The likely candidate in CLI is the “particle serial wifi” command, but according to the docs it does not seem to offer any options? https://docs.particle.io/reference/cli/#particle-serial-wifi It basically does exactly the same as “particle setup”, but ignores the login check.

  • wifitester.cpp is a file in the firmware. It looks like this is a way to test wifi setups and that it’s included in the firmware? Is this something that’s available from the command line? Looking at this Particle Firmware Updates Thread it might be code used by the Tinker software?

Do you have a USB serial port on your P1 board? It sounds like you do if you’re programming the initial firmware binary by serial.

Have you tried setting the Wi-Fi credentials using particle serial wifi with a JSON file? You can do it entirely automated, before you flash your firmware binary.

Create a JSON file with the Wi-Fi credentials:

{"network":"xxx","security":"WPA2_AES","password":"xxx"}

Then you can set them with a command like:

particle serial wifi --port xxx --file wifi.json

It should be possible to run that without user intervention when the P1 is in listening mode.

2 Likes

Since when do we have this (documented)? :+1:

But this is still some behaviour that seems buggy

I haven't really found a GitHub issue for this exact behaviour, but it should be looked at IMO.

Yeah. I agree, but it puzzles me that none of the many that have built products on Particle have stumbled upon this or already solved it? Maybe @sparkly @Mjones @mterrill (from this thread) and others that already have products out there could share how they do their automated setup of new boards?

The best way to set up a new product for a customer, not just my preference, but the best solution overall (unless you want them to setup a particle account) is the softAP setup page. This allows the customer to setup Wi-Fi credentials almost exactly like they would connect their phone to a new Wi-Fi. The UI for this is very simple, intuitive, and familiar for anyone to use.

@dheerajdake why would you not want to claim the P1? Having it in your devices gives you complete control, if you find a firmware issue in 6 months, you can make the necessary changes and reflash OTA.

Right. That’s not a bad idea for one of my two projects where I only produce a few boards at a time (for now). For the other project I’ll soon get 200 devices at a time, so I really want to automate anything I can, including the functional testing, claiming and registration with our services. Due to the bug mentioned above, I cannot seem to get around this without adding wifi manually for 200 devices…

I haven’t tried yet, but I’m sure that’s almost a days work of pointless typing? :stuck_out_tongue:
(I’d really not do that)

Did the JSON file technique I mentioned above not work?

Oh my… Clicking the link here on the site only took me to the last reply. I didn’t catch that there were multiple. Gimme a second here to test :smiley:

That looks super-awesome! Just what I need!

@Mjones I don’t remember why I wanted that option. It was an year ago when I wanted to do this.

1 Like

I'm using CLI Version 1.25.0 on OSX Sierra and I get error messages when trying this:

particle serial wifi --port /dev/tty.usbmodem1451 --file defaultwifi.json

Using Wi-Fi config file: defaultwifi.json
Attempting to configure Wi-Fi on --port
! Something went wrong: Error: Error: No such file or directory, cannot open --port

I have a P1 in listening mode on port /dev/tty.usbmodem1451. If I omit the --port part of the command I get the following error:

Using Wi-Fi config file: defaultwifi.json
Attempting to configure Wi-Fi on --file
! Something went wrong: Error: Error: No such file or directory, cannot open --file

Suggestions @rickkas7?

Ah! I just omit the --port part and keep the path to the device like this and it works!

particle serial wifi /dev/tty.usbmodem1451 --file defaultwifi.json

Perfect! Now I can script this! :smiley:
I’ll see if I can find the relevant page in the docs and add this on a pull request, since I can’t find it anywhere in the Docs.

1 Like

I think when you upgrade to 1.29.0 or later of the CLI it will require the --port option before the port name. But I’m glad you have a suitable workaround now!