Archive | September, 2018

Particle memory limitations and workarounds

18 Sep18

Particle memory limitations and workarounds

When coding in C/C++ it's crucial to do memory management correct. For a device that is expected to "just work" you simply cannot have any memory leaks. The simple way to solve this is to never allocate memory dynamically. By just instantiating all objects statically, you can be guaranteed that you always have enough memory. What do you do when you past this?

With the first Particle hardware platform called Spark Core, you had about 108Kb for your program and 35Kb of runtime memory available. With the Particle Photon, you have 128Kb program and about 60Kb runtime. This extra memory does however come with an undocumented limitation - for the Setup wifi feature (known as Listen Mode) to work, you have to leave at least 21.5Kb of the 60Kb free. You are free to use more, but if you do so the Listen Mode will not work correctly. Saving credentials will seem to work, but eventually fail.

If you've gotten to this, the trick is of course to start allocating memory dynamically instead of statically. That way you can utilise the same memory for multiple things. Jumping through some hoops and rethinking what needed to be in memory at what time, we found a fairly simple solution. We have a lot of debug features that take up valuable memory. Customers will normally not use these, so by making it all dynamic we suddenly had a lot of memory to spare. Here's how the memory usage looked before and after:

Memory use:
   text    data     bss     dec   note
  89884    2148   43360  135392   (before dynamic allocation)
  89868    2148   33128  125144   (after dynamic allocation of a large buffer)
  90012    2148   18468  110628   (Debug screens moved to RAM)

We basically halved the memory usage without sacrificing any features by just rethinking what we needed to load at what times in the program. I'm quite happy with how this turned out and I wanted to share in case others run into the same issue. Big shoutout the the great community and employees at Particle that helped solve this issue!

Level shifting NeoPixels for Particle Photon

14 Sep18

Level shifting NeoPixels for Particle Photon

I just miscounted how many GPIO pins I had for a project, so I had to find a way to save some pins. In this project we have a status LED that is either red, green or both (producing a somewhat orange color). I need 4 of these per Photon, so that's 8 pins. What about using programmable ws2812, sw2812b or SK6812 LED's?

They only need a single pin to drive many LEDs (NeoPixels is just the marketing name that Adafruit apply for all of these), so I can potentially save up to 7 pins, but also make other colors than red/green possible. Surely enough, I had some of these floating around from a former project.

For my Bitmart marquee sign I used maybe 90 of these, but I kept having bugs causing random flashes if I pulled too much power. Back then I used a 74HCT125 for level shifting, but I couldn't find either that or the 74AHCT125 variant in my component shelves. I did however find some 74HCT245 deep down in a drawer and surely enough - these are what is perferred for driving these programmable LED's in the Teensy community. Both will do the job!

I plugged it up and it worked perfectly! No glitches, just perfect timing. From the datasheets, the 74HCT125 and 74HCT245 looks to have very similar characteristics, but the first shifts 4 lines and the other shifts up to eight lines. The one I used in the Bitmart-sign was just one I found in a shelf at Bitraf. Maybe that one was damaged? Hmmm. I'll have to revisit that project to fix the glitches, but for now I've solved my problem.

I had a hard time locating pinouts / connection schematics for these IC's so here they are for use with Particle Photon.

Connecting Particle Photon to NeoPixels using 74HCT125

Connecting Particle Photon to NeoPixels using 74HCT245

Yellow wire is data out from the Photon. Purple is the level shifted data signal. Red is 5V. Black is GND. Do not omit the fat Capacitor that feeds the fast PWM LEDs.