Bluetooth Low Energy (BLE). It’s fairly cheap to implement, power effective, well supported on current smartphones, and for small packets of data it’s fast enough and plays well with Arduino.

Well, to a degree, just like how Arduino “plays well” with ethernet and WiFi, provided your not dealing with more than a few dozen bytes at time, the Arduino usually can hold it’s own within the 2 KB-ish SRAM that comes onboard.

What if your sending it ton more data like a webpage, or very verbose commands? These require hundreds of bytes to be parsed through the Arduino’s Micro-controller at a time. You’ll most likely run into a Heap Crash. Simply put, more data is needing to be stored on the Arduino at a moment when there isn’t the space to hold it. The Micro-controller then locks up, your LEDs or what ever is attached go all wonky, and serial output gets garbled or just stops until the Arduino is reset. And this will happen again and again.’

The root of the problem is that the Microcontroller on the Arduino usually only have 2 KB (yep Killobytes ). I’m working with an Arduino Micro, which has 2.5KB of SRAM. To give perspective, this page with images is still several hundred or thousand KBs big. Every character is one byte. My Arduino Micro could hold up to around 2,500 characters in it’s SRAM. Granted there wouldn’t be room for any thing else. No cool libraries, no room for logic operations, nada. You get nothing, YOU LOSE SIR!

A few things can be done on the programming side of things. You can store any strings in flash memory (PROGMEM or program memory) using the F() function, try to only declare constant variables in the functions that need them, and many other things as well.

But when everything programatticaly can’t be used to free up every byte of SRAM on the Micro-controller, then the next thing to do is re-evaluate your hardware choices. At this point I could of decided to move to a Teensy, Electric Imp, Spark Core (my photon is on Pre-order 🙂 ),or, any other prototyping platform that innately has the SRAM needed on board for large data transactions.

Or I could externalize more SRAM outside the Arduino via SPI. I’m pretty sure I’m going to get flamed pretty hard by some people for this. If so, please leave your constructive feedback in the comments.

There were a few reasons I went the route I did. One, I wasn’t in the mood to order and wait for a beefier Micro-controller to show up. Two, the libraries and examples I’d cited and drawn inspiration from

are all written for Arduino. Three, actually for the most part the Arduino is being under utilized. So far, my project hasn’t presented a need for a Micro-controller that’s faster or has more GPIO’s. I only need more SRAM. Just that one thing.

I do the googling, and eventually I wind up ordering a few samples of Microchip’s 23A256 256 Kbit SPI interfaced SRAM chips. This IC had a written library from the Arduino Playground, which looked promising.

One snag though, the 23A256 operates at 3.3v and the data sheet doesn’t exactly pride it with being 5v tolerant on the data lines. My project is running @ 5v, so meh, gotta use a logic level converter. I ordered this one from SparkFun. There are few different ways of doing this using resistors, buffers, etc. This was the most cost effective option that didn’t require me to consume another data sheet to understand how it works and why it’s so reliable.

Time passes, stars align and alas I’m at my bench following data sheets and examples wiring the SPI SRAM to my Arduino Micro via a logic-level converter. Yay, so much work for so little cool factor(no blinky, buzzy, or other cool shit. Just chips and wires ).

I run the example 23A256 test sketch from the Arduino Playground. It doesn’t work. I poke at it and my circuit for about two hours. Nothing. Efff it, I’ll just do it my self. (Lesson learned, give up on things given to you for free sooner.)

I wrote a test that read a byte from the first address of the SRAM IC (0X0000), wrote a random value from 0-255, read it back, and then moved on to the next address (0x0001) and repeated until it got to the last address (0x7FFF). To verify that I was indeed writing and reading from/to the 23A256, I disconnected the MISO line and got all 0xFF for the values reading back. Reconnected it, and it went back to reading and writing the values from the external SRAM Yay! Win!

So now I can just drop the BLE board into the design, write a few functions for reading and writing bytes too and from the BLE interface to the SRAM and move on to the victory dance. But, nope.

Reading data from the SRAM was just showing up as 0xFF. I did a number of things that I can’t really recall because they didn’t work. I throw my hands up and venture out to the Adafruit support forums. Adafruit support Mike and Paul Stoffregen came to the rescue. Evidently I’d forgotten that SPI four different modes (essentially predefined settings for timing signals on the SPI bus).

The Bluefruit LE module uses mode 1, while the SRAM uses mode 0. When the BLE.begin() function is run, it intiaties the SPI library to use mode 1. What needs to happen is that when data is being transacted between external SRAM and Arduino that the SPI bus needs to be set to MODE_0 and set back to MODE_1 once the transaction as completed.

This exactly is the new functionality that Paul Stoffregen wrote into the SPI library. I downloaded the files from github for the Adafruit nrf8001 (Bluefruit LE) and SPI library and added them to my Arduino IDE.

I modified the Adafruit Echo Demo that took whatever byte was being passed out the BLE buffer into an arbitrary location on the SRAM and to read it back through the Serial Monitor.

This is screen shot of my Serial Monitor. The characters not in brackets are the bytes read straight from the BLE interface, while the characters in brackets have been routed from the BLE interface, into SRAM (at an arbitrary address), read back and outputted through the serial monitor. And it doesn’t…drop…a…beat.

So, then happy ending right? Bytes are able to be sent from the BLE breakout to SRAM instantly, there isn’t really an apparent delay in data moving between the two from what I can observe in the Serial Monitor. I think, “Okay, so it’s time to drop this into my application and everything should be fine.”

Well, well, do I have a story to tell about that. But it’s going to require a deep dive into the SRAM’s datasheet and whole new conversation about optimization and trade-offs. Stay tuned, the second part is coming soon!