The Photon changelog - what's new and different from the Core

This content is copied from our blog post on the same topic. Discuss the changes here!

Today, after long last, we’re shipping the Photon!

Over the past two years, we’ve shipped 50,000 Spark Cores to customers all over the world. We learned a lot from our first product, and we’ve fed those learnings into the development of the Photon. The Photon is better than the Spark Core in every way, and we couldn’t be more excited to share it with you.

The Photon is designed to be backwards compatible with the Spark Core, but there are some differences that you should be aware of if you’ve been using a Spark Core. Most of these changes are dramatic improvements, but they are differences nonetheless.

There’s a lot of content here, so if you want just the summary, here you go:

  • The Photon includes a more powerful and more reliable Wi-Fi module, and you’ll have a lot more RAM and processing power at your disposal.
  • There are a bunch of new hardware peripherals, and the Photon can be surface mounted (if you buy it without headers).
  • We now have our own modules, the PØ and the P1, for sale alongside the Photon. Great for when you want to scale up manufacturing.
  • The firmware includes a full RTOS (Real Time Operating System), and the Wi-Fi connectivity code will soon run alongside your code in a more intelligent way than it did on the Spark Core.
  • We’ve made some awesome changes to our firmware to separate your code from the system code so that over-the-air firmware updates are BLAZING fast (a couple seconds to update).
  • We fixed lots of bugs. Most of those fixes (and many of the improvements) will be available on the Spark Core as well in a few weeks, including significant reductions in memory consumption (both FLASH and RAM).

Ok! Now, for those who want all the details, let’s dive into what’s changed:

Hardware

From Texas Instruments to Broadcom. The Spark Core used a Wi-Fi module from Texas Instruments called the CC3000. The Photon includes an upgrade to our own Wi-Fi module - the PØ - which includes a Broadcom Wi-Fi chip (BCM43362) and a souped up microcontroller (STM32F205). Broadcom makes the Wi-Fi chips in most routers and phones, so their chips are best-in-class. Expect big improvements in stability.

Power consumption has been dramatically reduced, and you have access to better low power modes. Simply due to hardware changes (a better Wi-Fi chip and a switch-mode power supply), average power consumption has dropped from ~150mA on the Spark Core to ~80mA on the Photon. In addition, the Photon has many more options for low power modes, including modes where you can trade off Wi-Fi latency for power consumption, bringing your power consumption down closer to ~15mA. And if you’re creating a battery-powered product, you can put the Photon entirely to sleep and achieve power consumption as low as 160uA.

The Photon is surface mountable. Most of you have ordered Photons with headers, which fit into a breadboard and are great for prototyping. We also sell Photons without headers, which can be soldered directly to a circuit board either with a soldering iron or with a reflow oven (using castellated edges). When you mount the Photon down to a PCB, you also have access to the USB data lines, the LED pins, and the SETUP button pin so that you can expose those features on your own circuit board.

The Photon has two different antenna options on every board. Every Photon includes both a chip antenna and a u.FL connector (for external antennas). By default, the Photon will use the chip antenna, but you can switch to the u.FL connector with one line of code.

The Photon has lots of new peripherals available. The Spark Core had UART, SPI, and I2C peripherals exposed, as well as ADCs (analog pins) and timers (PWM pins). The Photon has the same capabilities, plus a second SPI bus, two Digital to Analog Converters (DAC), a CAN bus, and I2S. These peripherals are not all supported in software yet, but they will be supported soon. The WAKEUP and VBAT pins are also exposed, which helps with low power modes.

Cleaner layout and fancy colors. We did some fancy footwork with the hardware design to make it extra pretty. The most noticeable changes are that the LED on D7 is exactly where you’d expect it to be, and we’ve adopted a new color scheme: matte black soldermask and cyan silkscreen.

A few things were removed. We took off the external flash to save space (since we had a lot more internal flash to work with), and removed the A6 and 3V3* pins to make room for other new features. If you want external flash, check out our P1 module, which includes external flash inside the Wi-Fi module.

We’ve got our own Wi-Fi modules for manufacturing at scale. The PØ, the module inside the Photon, is available for $10/unit (cloud service included). We also sell a variation called the P1 which is a tad bigger than the PØ but includes an antenna and external flash; the P1 is available for $12/unit (cloud service included). Both of these modules include the STM32F205 microcontroller, so you don’t need an additional processor to run your device.

Firmware

We decreased the time to do an Over-the-Air firmware update from more than a minute to just a few seconds. One of the biggest issues with the Spark Core was that over-the-air firmware updates could be somewhat slow, taking a minute or more. This slows down development, so people would do their development locally and program over USB. We’ve made some improvements (detailed below) that dramatically increase the speed of an OTA update so most updates now take just a couple of seconds. We hope that will speed up your development and make the cloud a bit more useful.

We built a Hardware Abstraction Layer (HAL). In order to compile one firmware application against two different target architectures (the Core and the Photon), we built a Hardware Abstraction Layer, or HAL, that makes it much more straightforward to port our firmware libraries to any hardware! This HAL also made possible Bluz and will be used heavily in the Electron. We can’t wait to see which hardware platforms you’ll adapt our firmware libraries to next!

We combined and simplified our firmware libraries into one repository. Our firmware used to be broken up into three libraries: the core firmware library, the communication library, and the library of common drivers. We’ve now combined all of our firmware into one repository and reorganized the firmware so it’s easier to pull out separate bits and pieces if you need them.

We added an RTOS (FreeRTOS) to provide scheduling for the Wi-Fi connectivity code. Real-time operating systems, or RTOSes, provide some of the features of a full operating system but with a very small amount of overhead. Professional engineers working with microcontrollers will typically use an RTOS to add multithreading and lightweight memory management while still allowing real-time hardware interactions that a system with a full OS (e.g. Linux) would not be able to do. We’ve implemented FreeRTOS on the Photon so that we can run the system code (mostly connectivity stuff) and your application in two separate threads. You can also use the RTOS for your own multithreaded code; as we iterate on our firmware, we’ll be providing simple APIs to help you do this in an Arduino-y kind of way.

We separated the system code and your application code into three separate binaries that are dynamically linked and can be reprogrammed separately. A lot of the improvements in OTA speeds came from separating system and application code. The system code can be hundreds of kilobytes, whereas your application code might only be a few KB. If an OTA update requires rewriting the entire program as it does on the Core, that means we’re spending a lot of time downloading the same system code that’s already on the device. By splitting the system and application, we can provide a faster and lower-risk over-the-air firmware update.

We made lots of smaller improvements to performance and stability. These improvements will be released as firmware v0.4.0, which will be available on the Spark Core as well in a few weeks. Here’s a comprehensive list of the improvements we’ve made:

Enhancements:

  • loop() iteration rate increased by 1000 times - from 200 Hz to over 200 kHz!
  • Compiler: Removed all warnings from the compile (and made warnings as errors) so compiler output is minimal.
  • Debugging: SWD Support, thanks to Elco Jacobs. #337
  • Spark.publish() returns a success value - #388
  • Spark.process() as the public API for running the system loop. #347
  • Sleep no longer resets (on the Photon) #283
  • Support for application code outside of the firmware repo. #374
  • MAC Address available in setup via ‘m’ key. #352
  • SoftAP setup on the Photon
  • Spark.sleep() changed to System.sleep() and similarly for deviceID() #390
  • Listening mode uses existing serial connection if already opened. #384
  • Spark.publish("event", PRIVATE) shorthand - #376
  • Improved integrity checks for firmware images
  • Added additional safe/recovery mode in bootloader (> 6.5 sec : restore factory code without clearing wifi credentials)
  • Enabled CRC verification in bootloader before restoring/copying the firmware image from factory reset, ota downloaded area etc.
  • Added ‘program-serial’ to build target to enter serial ymodem protocol for flashing user firmware (Testing pending…)
  • Cloud string variables can be re-defined #241
  • Removed hard-coded limit on number of functions and variables #111
  • Parameterized function callbacks, lambda support for functions #311
  • C++ STL headers supported
  • Can duplicate the onboard RGB LED color in firmware. #302
  • WiFi.selectAntenna() - select between internal (chip) and external (u.FL) antenna on Photon: #394
  • WiFi.resolve() to look up an IP address from a domain name. #91
  • System.dfu() to reboot the core in dfu mode, until next reset or next DFU update is received.

Bugfixes:

  • SOS calling Spark.publish() in SEMI_AUTOMATIC/MANUAL mode
  • Subscriptions maintained when cloud disconnected. #278
  • Fix for events with composite names. #382
  • WiFi.ready() returning true after WiFi.off() in manual mode. #378
  • Serial.peek() implemented. #387
  • Mode button not working in semi-automatic or manual mode. #343
  • Time.timeStr() had a newline at the end. #336
  • WiFi.RSSI() caused panic in some cases. #377
  • Spark.publish() caused SOS when cloud disconnected. #322
  • TCPClient.flush() discards data in the socket layer also. #416

More to come

We still consider our platform a work-in-progress, and while this is a huge step forward for us, it’s still just one more step on the journey. We’re eager for your feedback; if you encounter bugs or want to request new features when you receive your Photon, create a Github issue or contribute a Pull Request; we’d love your help!

17 Likes

Favorite. Post. EVER. :heart_eyes:

4 Likes

First of all congrats to the team for delivering this great product!

Since the Photon is running RTOS, the user code will run regardless if the Photon is connecting/disconnected/etc correct?

I look at the documentation here:

http://docs.particle.io/photon/firmware/#system-modes-semi-automatic-mode

And it states:

When the user calls Spark.connect(), the user code will be blocked, and the device will attempt to negotiate a connection. This connection will block until either the device connects to the Cloud or an interrupt is fired that calls Spark.disconnect().

Is this just not correctly updated? Or will it still block while connecting?

This is inaccurate but subject to changes on the firmware side to sync up the description.

Will be updated once i get access to the docs repo :wink:

1 Like

Woohoo, let’s fly them. :smiley:

Actually @kennethlimcp isn’t quite right here; we are still running code in one thread. We are going to split it into two threads in the near term, but refactoring the code to run in two separate threads was a software feature that we couldn’t get in in time for release.

2 Likes

That’s unfortunate. Main feature I was looking for.

Please let us know when its ready!

2 Likes

How does UDP compare to the spark core?
Can’t wait to get my hands on one.

I believe that UDP should perform according to spec on the Photon, but I’ll let @mdma give the final answer (he’s traveling at the moment)

If I order somewhere next week will I still qualify for the June shipment? Or are they, starting from now, available to ship on demand instead of batch shipping like last time

1 Like

Yep, you’ll be able to get yours in June - we’ll start shipping on-demand once all of the pre-orders have shipped out. the earlier the better!

1 Like

I got my Photons and wanted to stay I am very impressed with the super fast firmware flashing times. Its incredibly quick! Great job!

6 Likes

I got 1 of my 3 ordered Photons this week and even set aside time to get back into it, but now I think I’ll just work on the garden and throw the Photon in a drawer for awhile…

I lost interest in the Core because of the extra code (seemingly) required to stay out of the way of the almost unpredictable WiFi stuff (many wifi networks in my area, lots of instability). Everything I wanted to do seemed much more suited for having a micro that ran local stuff first, connected second (without blocking the first).

When looking at the pinout diagrams for the Core and the Photon, it looks like the second UART has moved from D0/D1 on the Core to D1/D2 on the Photon?
Is this correct?
That would be very unfortunate, because even though I’m not using 3.3V*, I would have to produce two different circuit boards for Core and Photon…

What you are probably seeing on the Photon is the CAN bus on D1/D2 which is a different high speed differential communication protocol.

It’s unclear at the moment if the Photon will support a second hardware serial port since the required pins are actually running to the RGB led. It was not exactly possible to make all of the peripherals line up perfectly when switching from the STM32F103 to STM32F205.

There is still a lot of processing power on the Photon though, so I don’t see why we shouldn’t just implement a Software Serial library :wink:

@BDub, arrrrggghhhh!! Every time I hear SoftwareSerial, I cringe. This library was written for the Arduino platform where turning off ALL interrupts is not a problem. This is necessary to get bit timing accurately enough to work. A different library developed by PRJC called AltSoftSerial may be a better candidate for porting.

The issues is not in receiving data since that can be interrupt driven. Instead, it is with the building of the send data. AltSoftwareSerial uses a timer to drive outgoing bits instead of a non-interruptable loop. At 115Kbaud, the time between bit “changes” is 4.3us, which is doable on a Core and really doable on a Photon. The biggest issue with this approach is that the code can only tolerate a maximum of 1 bit of jitter, meaning other system interrupts cannot run for longer than 4.3us at 115Kbaud for example.

Great info @peekay123, and I specifically left it vague to not imply we would directly port the Arduino SoftwareSerial library… I just think this should be possible to implement in software. I mean, even 9600 baud is better than nothing :smile:

@BDub, I believe 56Kbaud is feasible. Using SparkIntervalTimer, I can working on porting the library as soon as @mdma folds the new timer code into the develop branch of the beta repo. So much to do and so little time!

Oh no! For a commercial product I really need at least two reliable serial ports.
So that pretty much rules out the Photon, right?
I hope the Core will still be available in larger quantities, even after the full launch of the Photon…