Recently I was generously given a Spark Core (note, not the heretofore unreleased Photon) from my friend Bill.

The Core is a tiny Arduinoish compatible board with WiFi built into it. I'll assume you can figure out why that is cool on your own.

As soon as I got it I ran through the online Getting Started Guide and had it up and running, and was controlling pins from my phone. One of the features of the board is that it ships with an entire cloud based ecosystem. You can use their WebIDE to flash your code to the board, you can send data to and from the board via their REST api and you can control aspects of the board via your phone, and their cloud. I think that's great as it gives people unfamiliar with microcontrollers a way to hit the ground running. I also think it's interesting from an IoT perspective.

But...

But I want to use it for home automation projects and I don't particularly fancy my data hitting some other person's servers. The great thing is, Spark.io realizes this, and provides a way for you to use the Spark Core with no Cloud interaction at all. (gold star Spark.io!).

The downside is the info for how you go about doing this is scattered all over their commit messages and docs. To be fair they aren't hiding anything, at all, but my tiny brain always wants to see the simplest possible set-up that does what I want.

For the purposes of this post I want to take a factory reset/brand new Core and upload my code, and start the WiFi without the Core talking to Spark Cloud, at all.

Having said that, I had a few false starts getting this going and if you do things in a different order, you might find the Core does try to reach out to the cloud (again, that's a totally fine thing to do, because that's what they are trying to accomplish with the product).

Let's begin.

Step 1

The first step is to Factory Reset the Core. You might be able to skip this step if you just got the device, but it certainly won't hurt it if you do this. Plug the Core into your laptop using the micro-usb cable. This will power the device. Now hold the Core up so the usb port is at the top. Depress and hold the left button. Click and release the right button. Continue to hold the left button for about 10 seconds, until the main LED goes solid white. Release the left button and you can now put the Core back down on the table (sofa, rock, railing, seat of ferris wheel...wherever you are). We're done with the reset and the main LED should be blinking blue.

Step 2

In step 2 we need to have a local development environment set up. This was trivial to do following the README on the Github page. I did deviate slightly in that I used homebrew to get the version 4.8 GCC for ARM compiler using the following:

brew tap PX4/homebrew-px4
brew update
brew install gcc-arm-none-eabi-48

If you end up with another version of the compiler, you could run into issues (I did when I tried to use 4.7).

Step 3

Now that you have a local development environment, we can dig in. Ultimately your entry point to the code is in /path/to/core-firmware/src/application.cpp. Move that file out of the way, and put the following in it's place.

#include "application.h"
SYSTEM_MODE(SEMI_AUTOMATIC)
int led = D7;
void setup() {
  WiFi.connect();
  pinMode(led, OUTPUT);
}
void loop() {	
  digitalWrite(led, HIGH);
  delay(5000);
  digitalWrite(led, LOW);
  delay(5000);
}

This code does a few things for us. First of all it puts the system into SEMI_AUTOMATIC mode, meaning it will not reach out to the cloud unless you tell it to with your code. Second it fires off WiFi.connect(). The reason we have that here is because if it doesn't have credentials already for a network, it will listen for them to be delivered (which we'll do in a minute). Then the main loop here just turns the on-board LED on and off so we know it's working. If you set up WiFi before uploading code like with the new SYSTEM_MODE, it will reach out to the cloud to see if it's already associated with an account.

Step 4

Ok, almost done. Let's build and upload our code. Navigate to the /path/to/core-firmware/build directory and issue:

make clean
make

This will clean up any past attempts to build the code, and rebuild the firmware again. When that completes you should have the file core-firmware.bin in the build directory with you.

Now put the Core into DFU mode by holding the Core with the USB port at the top and holding down the left button. Then tap the right button and release. When the main LED begins flashing yellow release the left button (about 3 seconds). Now if you followed the README linked above you should be able to query the device with something like:

plum:build me$ dfu-util -l
dfu-util 0.8
[...]
Found DFU: [1d50:607f] ver=0200, devnum=6, cfg=1, intf=0, alt=1, name="@SPI Flash : SST25x/0x00000000/512*04Kg", serial="6D8B368A4857"
Found DFU: [1d50:607f] ver=0200, devnum=6, cfg=1, intf=0, alt=0, name="@Internal Flash  /0x08000000/20*001Ka,108*001Kg", serial="6D8B368A4857"

Great, now we can upload the firmware.

plum:build me$ dfu-util -d 1d50:607f -a 0 -s 0x08005000:leave -D core-firmware.bin
[...]
Opening DFU capable USB device...
[...]
Download        [=========================] 100%        77312 bytes
Download done.
File downloaded successfully
Transitioning to dfuMANIFEST state

At this point the Core should blinking blue, which says "I'm happy, but I'd take some WiFi credentials if you had some".

If you don't want to use the WiFi you could stop here and use it as a serial connected device, or you can follow the next step.

Step 5

We're going to create a serial connection to the device. The Core can only respond to 2 inputs when connected to this way. w, which will prompt you for WiFi credentials, and i, which will show you the Core id. We obviously want w.

Create a Serial connection.

plum:build me$ screen /dev/cu.usbmodemfa131  9600
SSID: hardtoguessssid
Security 0=unsecured, 1=WEP, 2=WPA, 3=WPA2: 3
Password: super sekret
Thanks! Wait about 7 seconds while I save those credentials...
Awesome. Now we'll connect!
If you see a pulsing cyan light, your Spark Core
has connected to the Cloud and is ready to go!
If your LED flashes red or you encounter any other problems,
visit https://www.spark.io/support to debug.
    Spark <3 you!

That's it. It doesn't do anything interesting, that part is up to you next. However it will get you into a state that circumvents the cloud.

Happy hacking!