How to set WiFi data for customers using embedded spark.core

Hey all,

There are 3 things the existing Spark apps do during setup:

  • register a user account / login
  • use Smart Config to send Wi-Fi credentials to the Core
  • once the Core is online, claim it to the logged-in user

You can modify the apps to do any of these and not the others. We are working on SDKs for iOS, Android, and Cordova. These are true SDKs, meaning that unlike the current example apps, modifying for your purposes will be much easier. We plan to release them when we ship the Photon.

If you are releasing a product to customers based on Spark, you should talk to us! Email sales@spark.io. Weā€™re building out the product creator workflow as part of the fleet management tools in progress right now. Your devices will be assigned a product ID, which should be compiled into your firmware so that they identify themselves when they come online. When the customer claims the device using your app, you can also set the product ID at that time.

The customer will claim, but you will have full visibility into the fleet of devices with that product ID. You will soon be able to restrict what capabilities the customer has versus which ones you have, for instance, as a product creator, you will want to be able to push our firmware updates. However, unless your product is intended to be hackable by the customer, she should not.

7 Likes

There seems to be a slightly clunky workaround for the problem of end user entering only their wifi credentials. You need to create a second dummy account which has no cores claimed.

  1. Claim the core on your regular account
  2. Clear the wifi credentials
  3. Ship to customer
  4. Provide your customer with the user name and password of the dummy account
  5. They log in and try to claim the core using the dummy account and their own wifi credentials
  6. The core will actually connect although the app hangs and says try again

Perhaps this is a bug, but maybe a real simple solution is to have Spark create a universal dummy account ā€œwifi_onlyā€ and just fix up the app a little not to hang.

Tom

Thatā€™s an interesting workaround. The right thing to do here however is to edit the app to only do Smart Config, not registration or claiming.

I am facing with the exactly same problem. I have been struggling with the WiFi setting issue for the customer side for at least 1 month. Here is the totally different solution that I am trying,

An SD card within a text document. Customer can write the SSID and password on that text document and spark reads at each time it starts with SEMI_AUTOMATIC mode.

By this way, spark gets the SSID and password each time from SD card which can be updated by customer. It seems totally legit but I am facing different problems. I can read the SSID and password from SD card and clear the credentials if they are different than previous ones. Then I am trying to connect the spark with the new SSID and password. However at this step spark connects previous connection rather than new one.

Any help may solve our problem in a different way (at least it would be a solution).

Think you got that backwards, I take it you mean a text document within an SD card?

Happy to try and help, can you share the relevant part of firmware code where you check the credentials and then try and connect?

Pardon me ^^ of course text document within an SD card. long hours study :confused:

Text document is in this form: ssid,password,
Here is the code: (btw code is just for finding the credentials and then establishing a connection)

#include "application.h"
#include "sd-card-library/sd-card-library.h"

const uint8_t chipSelect = A2;    
File credential;    

SYSTEM_MODE(SEMI_AUTOMATIC);

int i = 0;
int run = 1;
char ssid[64];
char pass[64];

void setup() 
{
    pinMode(A0,OUTPUT);    //for DEBUG
    Serial.begin(9600);

    credential = SD.open("ssid.txt");
    //Read SSID
    i = 0;
    run = 1;
    while(run){
        char ch = credential.read();
        if(ch == ','){
            run = 0;
            ssid[i] = '\0';
        }
        else{
            ssid[i] = ch;
        }
        i++;
    }
    //Read Password
    i = 0;
    run = 1;
    while(run){
        char ch = credential.read();
        if(ch == ','){
            run = 0;
            pass[i] = '\0';
        }
        else{
            pass[i] = ch;
        }
        i++;
    }

        credential.close();

    digitalWrite(A0,HIGH);

    if(Spark.connected()) 
    {
        Spark.disconnect();
    }
    WiFi.clearCredentials();
    WiFi.setCredentials(ssid,pass);
    Spark.connect();

    while(Spark.connected() == false) 
    {
        Spark.connect();
        Serial.print("Name: ");
        Serial.println(ssid);
        Serial.print("Pass: ");
        Serial.println(pass);
        Serial.println("Trying ...");
        delay(500);
    }
    digitalWrite(A0,LOW);
}

void loop() 
{ 
    digitalWrite(A0,HIGH);
    delay(100);
    digitalWrite(A0,LOW);
    delay(100);

    Serial.println("------------------------");
    Serial.println("Connected to:");
    Serial.print("Name: ");
    Serial.println(ssid);
    Serial.print("Pass: ");
    Serial.println(pass);
}

Since youā€™re using semi-automatic mode, you wonā€™t be connected to the Spark cloud until the first time you call Spark.connect. This means that the first time you call Spark.connected it will always be false. That said, it shouldnā€™t make it break, just unneeded code. You also donā€™t need to clear the credentials, you can just set them and overwrite the old ones.

I think the reason it might be connecting with the old credentials is because youā€™re not calling WiFi.on anywhere. Itā€™s unclear in the documentation, but if you use anything except automatic mode you need to call that yourself. Itā€™s being called implicitly with Spark.connect here, but Iā€™m assuming that since itā€™s not on when youā€™re setting credentials theyā€™re not actually being saved.

Iā€™m also curious as to why you have a while loop trying to connect in addition the Spark.connect call above it.

Then, do you think that would it work?

void setup() 
{
pinMode(A0,OUTPUT);    //for DEBUG
Serial.begin(9600);

credential = SD.open("ssid.txt");
//Read SSID
i = 0;
run = 1;
while(run){
    char ch = credential.read();
    if(ch == ','){
        run = 0;
        ssid[i] = '\0';
    }
    else{
        ssid[i] = ch;
    }
    i++;
}
//Read Password
i = 0;
run = 1;
while(run){
    char ch = credential.read();
    if(ch == ','){
        run = 0;
        pass[i] = '\0';
    }
    else{
        pass[i] = ch;
    }
    i++;
}

credential.close();

digitalWrite(A0,HIGH);

WiFi.on();
WiFi.setCredentials(ssid,pass);
Spark.connect();

digitalWrite(A0,LOW);
}

Yeah, give it a go! :smile:

Hey guys, it worked!

Now I can give the SSID and password to the SD card and spark can read those credential at the beginning and connect with them.

However I figured that, spark keeps the previous credentials as well, and as far as I noticed it connects to strongest network, not sure though. Maybe someone can explain this process better? Any way, here you have a solution :blush:

1 Like

How about setting the credentials via usb? Can be done really easy via serial, a program can be written for it with the company logos etc.

1 Like

I am really surprised that there isnā€™t a simple solution to being able to change the SSID and Password of a Spark core as needed when distributing these gizmos. I also have a small run (dozens of devices?) that need to be mailed out and locally reconfigured by the recipient.

I can see the catch-22 situation.

When packaging a Spark core based product, good practice would be to provide a recessed ā€˜Reset/Setupā€™ pushbutton inside the case but accessible through a small hole from the outside, similar to the one found on many devices, the kind that you need to press with a paperclip. Pressing the button during bootup would place the Spark core in ā€˜beacon modeā€™ (I made that up, I donā€™t know the proper term), where it would be seen by a mobile app device and show/ask for SSID and password, which could then be written back to the Spark core.

But then, the button should not be necessary at all; if the Spark fails to connect to WiFi, it should be possible to automatically drop to what I call ā€˜beacon modeā€™ and be visible to enter new credentials. Having a button provides physical security where you have to press a button rather than just drive-by.

You could even have an option in the mobile app to require a password (as stored in the coreā€™s flash) to change the connectivity settings.

This business of plugging in USB cables, using SD cards with text files, sharing accounts, etc is really rinky-dink for what should be basic built-in functionality on a device of this type.

I am disappointed that the ā€˜bigger pictureā€™ has been ignored.

You do realise that this ā€˜beacon modeā€™ youā€™re talking about already exists in the form of the ā€˜listening modeā€™, noticeable by the blinking blue LED? You can get there by holding the MODE button until it starts blinking blue. You can then pass it new credentials through the app. So your whole concept of using a button to get to this mode is already there.
As long as there are credentials stored, it will keep cycling through them to see if any match. To have it go to listening mode if it doesnā€™t find anything would be rather impractical. What if my wifi drops out for a minute, then my device will be stuck in listening mode while it could have recovered.
What can be done is loading up your firmware, after which you erase the credentials. This way, the device will automatically go to listening mode, and will stay there until it gets valid credentials.

1 Like

Yes, this has been discussed at the beginning of the thread, but it seems to require using the developer Spark login in the app, which was used to claim the device, in order to change the credentials.

I could be mistaken, but I donā€™t believe you have to have claimed the device in order to be able to change the credentials. The Spark app uses the TI software to configure the credentials, after which it can link it to your account. Seeing as you could also use the TI stand-alone app, there shouldnā€™t be a reason why youā€™d need to have claimed the device beforehand. Thereā€™s even a Java SDK if Iā€™m not mistaken, so you can configure it with a computer/laptop which has a wireless connection.

Hi

Where do we find the ti standalone lp?

On the Apple AppStore itā€™s listed under TI WiFi SMARTCONFIG. Not sure about android, but Google should able to help you out.
Itā€™s included in the Spark app, so if you can use that, thereā€™s no need to download TIā€™s.

thanks,
off course I know about the other app :wink:.
I was just curious.

1 Like

Hi @Moors7,

You mention being able to connect to the photons hotspot and entering the WiFi credentials there. Do you know of any documentation on the subject? or has this not been implemented yet?

Thanks!

I'm not sure where I said that, but I'll take your word for it...
The Photon and Core use different technologies, so make sure you don't mix them up. The Core kinda "throws" credentials through the ether where they can be picked up, whereas you make a connection with the photon. How they work exactly, I don't really know.
I think this thread might contain some useful information in regard to the softAP setup process, and what possibilities there are/might be:

You can always check the docs for information on how to connect your devices: https://docs.particle.io/guide/getting-started/start/photon/#step-2-connect-with-your-smartphone