Skip to main content

SD:S3 The Untold Love Story

This is a stereotypical love story of the shamelessly festive variety, of how two seemingly different storage mediums defy all doom-mongers and naysayers to conquer the world - together.

The premise of this story is so ludicrous, the ending so unsatisfying, that this is all we have to say about when Barry the SD card met Ally the S3 bucket... for now.

If you are allergic to even a little sprinkle of holiday sentimentality, it might be best for your health to abandon this post... right about now.

Sleepless in Seattle, Amazon HQ:

After our recent intrepid detours taken outdoors, equipped with a bag full of electronics, we've been attempting to refocus our efforts on some things that are much closer to home.  And to get back on to the AWS IoT portfolio devised by that cloud mega corp headquartered out in Seattle.

To this end, here's the shamelessly melodramatic screenplay that even Richard Curtis would find too embarrassing to draft for Nickelodeon.

  • We will be using an ESP32 development board running MicroPython.  We have paired it up with a breadboard, as we have quite a few modules to attach to its various pins.
  • Speaking of modules, our production will be getting some screen time.  We will be using an SSD1306-driven 128×32 OLED screen to display pointless stuff, a BME280 sensor to measure atmospheric temperature, humidity and pressure, and a SD card device to directly log our results .
  • And because we do want to store all this data also in the lovey-dovey cloud, we'll be using AWS IoT Greengrass running on a Raspberry Pi together with AWS IoT Core to publish our readings via MQTT.
  • Lastly, we'll store this data in an AWS S3 bucket to complete the holy matrimony between SD and S3.


This is the fifth instalment in the dreary straight-to-video romcom series I-O-Mr-T - which Roger Ebert once described as a poignant, modern fairytale in which electronic components from different walks of life follow their destinies and find love in unexpected breakout boards, breadboards and power rails.

And in case you didn't pick these up on VHS in the local Blockbuster bargain bin back in the 90s, here are the instalments that defined romance for a generation.

  1. Gold Filing
  2. Castle Track-a-lot
  3. Chariots of Wire
  4. Athlete's Foot

Right - let's get on with the cooking up of this experiment because we're hungry for sweet, savoury IoT and there's just Something about Mary Berry.

And - no - no glue is involved.

"colin firth" not in "hill":

It is fast becoming increasingly hard to keep track of the actors and actresses appearing in an ever-growing list of romcom films. 

For example, was it Colin Firth playing the recurring role of the bumbling Englishman in Notting Hill?  Did Drew Barrymore manage to compress her sensor readings for LoRa into the 50 First Bytes?  Did Tom Hanks demand that Meg Ryan drop the use of an unclassified personal POP3 server in You've Got Mail Server?

Thankfully for us, however, we have a pretty clear idea as to what activities will star in this little feature.

Here are the spoilers:

  • After attaching all aforementioned electronic components to the ESP32 development board, we will first attempt to send a witty message to the SSD1306-driven 128×32 OLED screen like Meg and Tom, original developer advocates of the AOL "send email" functionality.
  • Then, we'll use the BME280 sensor to measure atmospheric temperature, humidity and pressure because Punxsutawney needs a good weather station all year around.
  • Should we be storing these readings somewhere local first, before we dispatch them to some anonymous server on the cloud?  Yeah, go on then.  Let's try saving arbitrary data to an attached SD card.  Because that's Definitely, Maybe what cool kids do these days with their selfies and screenshots of someone's now-deleted Tweet.
  • Yet, we all remember that quote from Dirty Dancing: Nobody puts ZigBee in a dormer.  Sorry, not that one.  This one: What's big, cuddly and is great at digesting inordinate amounts of data like Uncle Buck?  Cloud, right?  Which is why we'll send our readings to AWS IoT Core - via an IoT "Greengrass is Greener on the Other Side, especially when illuminated by a green LED" device - and store our data safely in a S3 bucket.

And, nope, it was the other Englishman (Hugh Grant) in Notting Hill.

How to Lose a vi in 10 Days:

She was just a girl standing in front of root@server123:~, asking vim to love her


Please excuse the format.  We have inadvertently launched vi, and we can't easily find a way out. 

We have spent many months demonstrating how we collect sensor readings from various modules using MicroPython running on an ESP32 development board. Similarly, we have used AWT IoT Greengrass Core running on a local Raspberry Pi device in the past to concentrate readings from our various microprocessors, and to act as a gateway to AWS IoT Core.


But - often - it is advantageous to store readings taken directly to a local storage device to ensure we retain a local copy.  Secure Digital - or SD - is a widely used non-volatile memory card format commonly seen in smartphones, cameras and all sorts of other devices these days.  They can store gigabytes' worth of data, and are tiny in size, so make an ideal storage device for IoT data.


Now the aim here is to also make an identical copy of the data in the cloud.  Specifically, we want to create objects in an AWS S3 bucket.  This will be achieved using a Rule in AWS IoT Core which will duly save the messages it receives from our device via Greengrass into the designated S3 bucket.

A little like this:


Some (Smart) Thing's Got a Sieve:

Right, how do these festive feel-good stories normally start?

There's a snowstorm outside.  Two bumbling protagonists - one preferably with an English accent - are stuck together in a local incarnation of an unnamed global coffee franchise with a * in its name (not literally using epoxy glue... no, that would be a Saw film).  They stare longingly at each other over a wall of iPhones, MacBooks and the latest super food smoothie made out of kelp and local pond water.  Then, after entering some fictitious numbers into adjacent cells in Excel (Ally is obviously a work-obsessed high-flying tax accountant at Earnest and Dung), the tension is finally broken with the film's standout quote.

You had me at print(Hello World)

And the two lovers frantically start to make... hardware!

We start by reserving two GPIO pins to provide HIGH and LOW signals to red and green LEDs.  These LEDs are connected to ground using corresponding 330Ω resistors to limit the current through each semiconductor.

Next, we use two GPIO pins to form an I2C bus - one that will be shared between the OLED screen and the BME280 sensor.  This coupling works, because they are both equipped with different I2C addresses and can therefore be reached over the same physical I2C medium.  The modules appear to have built-in pull-up resistors too, which is very handy for us.

Lastly, we need four additional GPIO pins for the SPI connection which will be used to communicate with the SD card module.

Here's the famous table on which Barry the SD card will meet Ally the S3 bucket to exchange some pleasantries.

ESP32 PinConnected to...We should care, because???
GPIO 33Red LED (with 330Ω resistor in series)Provides current to the red LED so that it can warn the audience about the appearance of the idiotic (but inexplicably affluent) ex who will do everything to ruin the couple's relationship
GPIO 32Green LED (with 330Ω resistor in series)Provides current to the green LED to indicate that the ex has been safely disposed of... by a hitman (totally unnecessary back story: the hitman is actually a 40-year old gherkin)
GPIO 26SSD1306 OLED SCL and BME280 SCLThis is used for the shared I2C Clock signal
GPIO 27SSD1306 OLED SDA and BME280 SDAThis is used for the shared I2C Data signal
GPIO 18SD card SCKThis is used for the SPI Clock signal
GPIO 23SD card DIThis is used for the SPI MOSI signal
GPIO 19SD card DOThis is used for the SPI MISO (soup) signal
GPIO 15SD card CSThis is used for the SPI (mint choc) Chip Select signal

Clearly, all the relevant power connections of the modules (3.3V, 5V and GND) are cabled up as well.  Our SD card module, for example, appears to require a 5V supply unlike the rest (more likely to do with the built-in voltage regulator of the module than the SD card itself).

Here's the cute baby photos.  Awww.

So, on what wholly unnecessary tangent does the story go on next?

The 92-minute running time can't simply consist of songs by Boyzone and scenes of completely indecisive human beings telling peripheral characters about how much they love or not love a certain individual, in ASCII.

Yes, let's proceed to create completely needless drama.

We have some blinky-blinky LEDs on hand, we can add some cheery sparkle to proceedings.  Sending the GPIO pin HIGH raises the pin's voltage to 3.3V, and as such, sends current flowing to turn the LED on.  Sending it LOW will turn it back off.  Like Mr. Miyagi said.  HIGH = on.  LOW = off.  HIGH = on.  LOW = off.  Get it?

Nice and simple; let's give it a go.

from machine import Pin 
LED_RED_GPIO = const(33)
LED_GREEN_GPIO = const(32)
led_red = Pin(LED_RED_GPIO, Pin.OUT)
led_green = Pin(LED_GREEN_GPIO, Pin.OUT)

Wow, OK.  That wasn't as satisfying as we thought it would be.

What's that?  Didn't we connect an OLED display to the ESP32 development board as well?  We sure did.  Let's send it some poignant messages about true love.

We first initialise an I2C bus using our designated GPIO pins, and feed it to the SSD1306 MicroPython library.  Running a scan() reveals our two I2C devices that are already on the bus (OLED and the BME280), and we can simply use text() and show() methods of the library, after we initialise an oled object, to send characters to the screen.

from machine import I2C, Pin 
scl_pin = Pin(26, Pin.IN, Pin.PULL_UP)
sda_pin = Pin(27, Pin.IN, Pin.PULL_UP)
i2c = I2C(scl=scl_pin, sda=sda_pin, freq=400000)

import ssd1306
oled = ssd1306.SSD1306_I2C(128, 32, i2c)
oled.text("ANOTHER BORING ", 0, 0)
oled.text("IOT PROJECT... ", 0, 16)

Aren't we that hilarious jester who is best friends with the aesthetically pleasing main characters, but has failed miserably to achieve anything meaningful in life by the end of the film.

The red LED it is, then.

Oh, did we say the story's backdrop was some fictitious town experiencing an unseasonable snowstorm?  Yes, we think we did.  Which is handy, as we now have an excuse to introduce an otherwise completely random temperature / humidity / pressure sensor.

Here, we have a BME280 sensor that we can interact with using the MicroPython BME280 library.  Notice how this device is connected to the same I2C bus (pins) as the OLED screen so we're simply reusing the i2c object. The read_compensated_data() method of BME280 class does the trick just fine.

import bme280_float
bme = bme280_float.BME280(i2c=i2c)
measurements = bme.read_compensated_data()

Now, you don't have to be Richard Gere from Pretty Woman to overcome the moral dilemma of playing out your sins on-screen.  The LED is now green - because we're winning.

Now onto the interesting bit... the SD card (or Barry as we have christened him).

We use the MicroPython SD Card library after we initialise a SPI object.   Then, we simply mount it at /sd.  That's it.  No, really.  We can write to and read from the SD card as long as it has been formatted as FAT32 beforehand, and all the plumbing is sound.

Notice how SPI uses a distinct set of ESP32 pins.

import machine, sdcard, os
from machine import Pin, SPI
spisd = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
sd = sdcard.SDCard(spisd, machine.Pin(15))
os.mount(sd, MOUNTPOINT)

The /sd directory is now available for use from within MicroPython.  Which means we can write something "hilarious" to it in the form of a test.txt file. Go on, under-achieving-best-friend, offer us some comic relief like you're supposed to.

MESSAGE = "This is another boring IoT test. Please ignore.\n"
with open(FILENAME, "w") as file_write:

After the SD card has been unmounted, we can safely eject it and insert it into a laptop to check that the content has been preserved.

...Which it has.  Excellent!

Hang on a second.  That was all about Barry.  Where has Ally the S3 bucket been hiding all this time?  Had that posh ex made an unwelcome return from a round-the-world yacht race sponsored by some sovereign wealth fund?

We have spent a considerable time chronicling AWS IoT Greengrass in Green, Green Grass of /home.  And more generally, how we register and connect things in AWS IoT Core is described throughout the I-O-Tea series.

Clearly, to work with AWS IoT, we need our thing to exist in the device registry of AWS IoT Core.

thingy-thingy-thing-thing is what we've decided to call our ESP32 development board in AWS IoT Core. 

Since we'll be publishing our sensor readings to MQTT topic givememysensorreadings/ohhereitis, we need to give this device permissions to publish to this MQTT topic.

Remember that AWS IoT requires secure communication using certs, and to announce its identity.  The certificates downloaded for the device from AWS IoT Core have been uploaded to the ESP32 so that the umqtt.simple client can be furnished with SSL details when establishing the onwards MQTT connection to Greengrass.

Now we should probably add the device to our Greengrass Group.

We've decided that Ally is a S3 bucket.  Of course, she could just as easily have reprised her previous role as a DynamoDB table (Frozen Pi), IoT Analytics channel (Quantitative Wheezing), Lambda function (Have-ocado), Elasticsearch Service endpoint (Hard Grapht),  IoT Events input (Pear Force One) or any other AWS service directly accessible using a supported Rule in AWS IoT Core.

In fact, we'll re-enable our Rule to forward our data to an AWS IoT Analytics channel anyway, since it's a convenient destination to store our sensor data.

But we also promised you a Rule for S3.  In AWS IoT Core, we create a Rule that automatically saves messages received on MQTT topic givememysensorreadings/ohhereitis as an object in a S3 bucket we have called wierdandwonderfulsensorreadings.

The key being used for the S3 Rule ensures that the data is actually being organised under a semi-legible folder structure consisting of the MQTT topic, and device name.  The objects in S3 will be individually named as the timestamp.


We then create a Subscription for our Greengrass Group, so that any messages that are received on topic givememysensorreadings/ohhereitis are immediately dispatched to AWS IoT Core in the cloud - and thereby invoking the Rule and getting saved as a S3 object.

Of course, we can test this manually by creatively fabricating figures on the ESP32 like Ally the high-flying tax accountant, and watching them come in on the AWS IoT console.

Here's actual footage of this mysterious device in action.

But in reality, we'd wrap this up in a MicroPython application that repeats this indefinitely, to ensure that sensor readings are taken, and dispatched, even While You are Sleeping.

Finally, we find this identical data stored away in Amazon S-3(Three).  Not to be confused with Katherine Heigl's classic with slightly more S's - 27 S's in fact - an inspiring story of a Siamese cat that accidentally falls asleep on a very specific key of the owner's developer MacBook.

And of course, we can store the same data to the attached SD card to complete the story, and therefore bring this melodrama to a happy, symmetrical conclusion.

Well, that's that then.  This is the sentimental end to this heart-warming tale of two storage mediums that were fated to be together.  Like, forever.  Or, until the next sequel.  Whichever comes first, before the divorce.

We're now off to direct the next instalment, Four Beddings and an Urinal, in which a lonely Debenhams store assistant meets the love of his life (and more importantly the year's sales targets) selling Internet-connected futons, and a smart toilet from Japan.  Or off on our next outdoor expedition; to be documented in It's Rab Actually, about a down and out mountaineer who has had his North Face sponsorship terminated.

Happy holidays everyone!

Don't miss Rage:MKR, in which we reaffirmed our eternal commitment to AWS IoT Analytics by connecting up AWS QuickSight and Jupyter Notebooks to our AWS IoT Analytics Data Sets.

10 Things I Hate about Glue:

This is the MicroPython library we use to drive the OLED screen using the SSD1306 chip:
We can interact with the BME280 temperature / humidity / pressure sensor using this useful MicroPython library:
The MicroPython SD card library... kinda useful if you want to use SD cards with MicroPython:
Here's how to get started on AWS IoT Greengrass:
List of AWS IoT Rules available are documented here:
More generally, here's the AWS IoT documentation:



LoRa-Wan Kenobi

In the regurgitated words of Michael Bublé: It's a new dawn .  It's a new day .  It's a new Star Wars film .  For me .  And I'm (George Lucas, and I'm) feeling good .  Unfortunately for Canadian Mike, the Grammy that year was won by the novelty disco classic with the famous refrain: We love IoT, even in Planet Tatooine * . *Not true. Clearly, the Star Wars producers didn't sincerely mean the last Jedi the previous time around.  Return of the Jedi, released during the decade that spearheaded cultural renaissance 2.0 with the mullet and hair-metal , was less economic with the truth.  Either way, we're going to take inspiration from the impressive longevity of the money-spinning space-opera and reboot our franchise with some Jedi mind tricks.  Except this particular flick doesn't require an ever-growing cast of unrecognisable characters, unless ASCII or UTF counts.  In place of an ensemble gathering of Hollywood stars and starlets, we will b

Battle of BLEtain

The trolling . The doxing . An army of perplexing emojis. And endless links to the same - supposedly funny - viral video of a cat confusing a reflection from a dangling key for a golden hamster, while taking part in the mice bucket challenge. Has social media really been this immense force for good? Has it actually contributed significantly to the continued enlightenment of the human (or feline) race? In order to answer these poignant existential questions about the role of prominent platforms such as Critter, StinkedIn and Binterest, employing exceptional scientific rigour equal to that demonstrated by Theranos , we're going to set up a ground-breaking experiment using the Bluetooth Low Energy feature of MicroPython v1.12, and two ESP32 development boards with inexplicable hatred for one another.  And let them hurl quintessentially British expressions (others call them abuse) at each other like two Wiltshire residents who have had their internet access curbed by the co

Hard grapht

You would all be forgiven for assuming that bar , pie and queue line are favourite pastimes of the British .  Yet, in fact – yes, we did learn this back in GCSE maths – they are also mechanisms through which meaningless, mundane data of suspect origin can be given a Gok Wan -grade makeover, with the prime objective of padding out biblical 187-page PowerPoint presentations and 871-page Word reports (*other Microsoft productivity tools are available).  In other words, documents that nobody has the intention of ever reading.  But it becomes apparent over the years; this is perhaps the one skill which serves you well for a lifetime in certain careers.  In sales.  Consultancy.  Politics.  Or any other profession in which the only known entry requirement is the ability to chat loudly over a whizzy graph of dubious quality and value, preferably while frantically waving your arms around. Nevertheless, we are acutely conscious of the fact that we have spent an inordinate amount