How to write to flash on an Arduino Nano BLE

Photo by Brecht Bug

I’ve been enjoying using the Arduino Nano Sense BLE 33 board as an all-round microcontroller for my machine learning work, but I had trouble figuring out how to programmatically write to flash memory from a sketch. I need to do this because I want to be able to download ML models over Bluetooth and then have them persist even if the user unplugs the board or resets it. After some research and experimentation I finally have a solution I’m happy with, so I’ve put an example sketch and documentation up at

The main hurdle I had to overcome was how to initialize an area of memory that would be loaded into flash when the program was first uploaded, but not touched on subsequent resets. Since modifying linker scripts isn’t recommended in the Arduino IDE, I had to come up with a home-brewed solution using const arrays and C++’s alignas() command. Thankfully it seems to work in my testing.

There’s a lot more documentation in the README and inline in the sketch, but I would warn anyone interested in this that flash has a limited number of erase/write cycles it can handle reliably, so don’t go too crazy with high-frequency changes!

How to transfer files over BLE

Image from Wikipedia

I’ve now taught a lot of workshops on TinyML using the Arduino Nano Sense BLE 33 board, including the new EdX course, and while it’s a fantastic piece of technology I often have to spend a lot of time helping students figure out how to get the boards communicating with their computer. Flashing programs to the Arduino relies on having a USB connection that can use the UART serial protocol to communicate, and it turns out that there are a lot of things that can go wrong in this process. Even worse, it’s very hard to debug what’s going wrong, since the UART drivers are deep in the operating system, and vary across Windows, MacOS, and Linux computers. Students can end up getting very frustrated, even after referring to the great troubleshooting FAQ that Brian on the EdX course put together.

I’ve been trying to figure out if there’s an alternative to this approach that will make life easier. To help with that, I’ve been experimenting with how I might be able to transfer files wirelessly over the Bluetooth Low Energy protocol that the Arduino board supports, and I now have a prototype available at There are lots of disclaimers; it’s only a few kilobytes per second, I haven’t tested it very heavily, and it’s just a proof of concept, but I’m hoping to be able to use this to try out some approaches that will help students get started without the UART road bumps.

I also wanted to share a complete example of how to do this kind of file transfer more generally, since when I went looking for similar solutions I saw a lot of questions about how to do this but not many solutions. It’s definitely not an application that BLE is designed for, but it does seem possible to do at least. Hopefully having a version using a well-known board and WebBLE will help someone else out in the future!

How screen scraping and TinyML can turn any dial into an API

This image shows a traditional water meter that’s been converted into a web API, using a cheap ESP32 camera and machine learning to understand the dials and numbers. I expect there are going to be billions of devices like this deployed over the next decade, not only for water meters but for any older device that has a dial, counter, or display. I’ve already heard from multiple teams who have legacy hardware that they need to monitor, in environments as varied as oil refineries, crop fields, office buildings, cars, and homes. Some of the devices are decades old, so until now the only option to enable remote monitoring and data gathering was to replace the system entirely with a more modern version. This is often too expensive, time-consuming, or disruptive to contemplate. Pointing a small, battery-powered camera instead offers a lot of advantages. Since there’s an air gap between the camera and the dial it’s monitoring, it’s guaranteed to not affect the rest of the system, and it’s easy to deploy as an experiment, iterating to improve it.

If you’ve ever worked with legacy software systems, this may all seem a bit familiar. Screen scraping is a common technique to use when you have a system you can’t easily change that you need to extract information from, when there’s no real API available. You take the user interface results for a query as text, HTML, or even an image, ignore the labels, buttons, and other elements you don’t care about, and try to extract the values you want. It’s always preferable to have a proper API, since the code to pull out just the information you need can be hard to write and is usually very brittle to minor changes in the interface, but it’s an incredibly common technique all the same.

The biggest reason we haven’t seen more adoption of this equivalent approach for IoT is that training and deploying machine learning models on embedded systems has been very hard. If you’ve done any deep learning tutorials at all, you’ll know that recognizing digits with MNIST is one of the easiest models to train. With the spread of frameworks like TensorFlow Lite Micro (which the example above apparently uses, though I can’t find the on-device code in that repo) and others, it’s starting to get easier to deploy on cheap, battery-powered devices, so I expect we’ll see more of these applications emerging. What I’d love to see is some middleware that understands common displays types like dials, physical or LED digits, or status lights. Then someone with a device they want to monitor could build it out of those building blocks, rather than having to train an entirely new model from scratch.

I know I’d enjoy being able to use something like this myself. I’d use a cell-connected device to watch my cable modem’s status, so I’d know when my connection was going flaky, I’d keep track of my mileage and efficiency with something stuck on my car’s dash board looking at the speedometer, odometer and gas gauge, it would be great to have my own way to monitor my electricity, gas, and water meters, I’d have my washing machine text me when it was done. I don’t know how I’d set it up physically, but I’m always paranoid about leaving the stove on, so something that looked at the gas dials would put my mind at ease.

There’s a massive amount of information out in the real world that’s can’t be remotely monitored or analyzed over time, and a lot of it is displayed through dials and displays. Waiting for all of the systems involved to be replaced with connected versions could take decades, which is why I’m so excited about this incremental approach. Just like search engines have been able to take unstructured web pages designed for people to read, and index them so we can find and use them, this physical version of screen-scraping takes displays aimed at humans and converts them into information usable from anywhere. A lot of different trends are coming together to make this possible, from cheap, capable hardware, widespread IoT data networks, software improvements, and the democratization of all these technologies. I’m excited to do my bit to hopefully help make this happen, and I can’t wait to see all the applications that you all come up with, do let me know your ideas!

Why Do I Think There Will be Hundreds of Billions of TinyML Devices Within a Few Years?

Rising Graph Icons - Download Free Vector Icons | Noun Project
Image by The Noun Project

A few weeks ago I was lucky enough to have the chance to present at the Linley Processor Conference. I gave a talk on “What TinyML Needs from Hardware“, and afterwards one of the attendees emailed to ask where some of my numbers came from. In particular, he was intrigued by my note on slide 6 that “Expectations are for tens or hundreds of billions of devices over the next few years“.

I thought that was a great question, since those numbers definitely don’t come from any analyst reports, and they imply at least a doubling of the whole embedded system market from its current level of 40 billion devices a year. Clearly that statement deserves at least a few citations, and I’m an engineer so I try to avoid throwing around predictions without a bit of evidence behind them.

I don’t think I have any particular gift for prophecy, but I do believe I’m in a position that very few other people have, giving me a unique view into machine learning, product teams, and the embedded hardware industry. Since TensorFlow Lite Micro is involved in the integration process for many embedded ML products, we get to hear the requirements from all sides, and see the new capabilities that are emerging from research into production. This also means I get to hear a lot about the unmet needs of product teams. What I see is that there is a lot of latent demand for technology that I believe will become feasible over the next few years, and the scale of that demand is so large that it will lead to a massive increase in the number of embedded devices shipped.

I’m basically assuming that one or more of the killer applications for embedded ML become technically possible. For example, every consumer electronics company I’ve talked to would integrate a voice interface chip into almost everything they make if it was 50 cents and used almost no power (e.g. a coin battery for a year). There’s similar interest in sensor applications for logistics, agriculture, and health, given the assumption that we can scale down the cost and energy usage. A real success in any one of these markets adds tens of billions of devices. Of course, the technical assumptions behind this aren’t certain to be achieved in the time frame of the next few years, but that’s where I stick my neck out based on what I see happening in the research world.

From my perspective, I see models and software already available for things like on-device server-quality voice recognition already, such as Pixel’s system. Of course this example currently requires 80 MB of storage and a Cortex A CPU, but from what I see happening in the MCU and DSP world, the next generation of ML accelerators will provide the needed compute capability, and I’m confident some combination of shrinking the model sizes and increased storage capacity will enable an embedded solution. Then we just need to figure out how to bring the power and price down! It’s similar for other areas like agriculture and health, there are working ML models out there just looking for the right hardware to run on, and then they’ll be able to solve real, pressing problems in the world.

I may be an incorrigible optimist, and as you can see I don’t have any hard proof that we’ll get to hundreds of billions of devices over the next few years, but I hope you can at least understand the trends I’m extrapolating from now.

How to Organize a Zoom Wedding

Photo by Chantal

Joanne and I got engaged two years ago in Paris, and were planning on getting married in the summer, before the pandemic intervened. Once it became clear that it might be years until everybody could meet up in person, especially older members of our families who were overseas, we started looking into how we could have our ceremony online, with no physical contact at all. It was unknown territory for almost everybody involved, including us, but it turned out to be a wonderful day that we’ll remember for the rest of our lives.

In the hope that we might help other couples who are navigating this new world, Joanne has written up an informal how-to guide on Zoom weddings. It covers the legal side of licenses in California, organizing the video conferencing (we used the fantastic startup Wedfuly), cakes, dresses, flowers, and even the first dance! We’re so happy that we were still able to share our love with over a hundred terrific guests, despite the adverse circumstances, so we hope this guide helps others in the same position.

The Five: Putting Jack the Ripper’s Victims at the Center of the Story

Years ago I went on a “Jack the Ripper” walking tour when I visited London without giving it much thought. The murders felt like fiction, in the same realm as Sherlock Holmes or Dr Jekyll and Mr Hyde. Even visiting the spots where the bodies were found didn’t make an impact. I’ve never been a “Ripperologist” but as someone interested in Victorian history it’s been hard to avoid the story and endless theories about the case.

Over time I’ve found myself actively avoiding the subject though. The way the story is told seems to center the perpetrator as the star of the show, endlessly fascinating and worthy of study. At its worst the literature seems little more than a way to vicariously replay the victimization of women over and over again. I’ve run into the same problem with the whole “True Crime” genre – I want the catharsis of a solved case, and the glimpses into people’s hidden lives, but I don’t think murderers are nearly as interesting as they’d like us to believe.

That’s why I was so excited when I saw “The Five” coming up for publication. The book tells the life stories of the canonical victims of the Ripper, up to but not including their deaths. I was already a fan of the author from the wonderful Harlots TV show, and here she has done another amazing job bringing strong, complex, ignored people to life. While she’s at it, she also makes a strong case that the prejudices about the women we’ve inherited from the original investigators have distorted our understanding of the case and blinded us to likely solutions. If most of the women weren’t prostitutes, as she argues convincingly, and if they were attacked while asleep, then many of the old narratives fall apart. It’s a great example of how highlighting the stories of people who have traditionally been ignored isn’t just a worthy pursuit, it also adds to our overall understanding of the past.

Even ignoring the wider lessons, this is a beautifully-written set of stories that I found hard to put down, and I had to ration myself to one a night to avoid burning through it all too fast. With deep research, Rubenhold draws sketches of girls growing into women, living full lives as daughters, mothers, friends, and workers, despite our knowledge of the shadow of Whitechapel looming in their future. They all suffer blows that end up pushing them into poverty, but what she drives home is that they were far more than just their ending, and what a loss their deaths were to themselves and many others. Alcoholism, poverty, and rough sleeping are common factors, but the path to them is wildly different in each story. It even made me rethink some of my expectations of unbending Victorian morality, with most of the women at least temporarily benefiting from pragmatic attempts to help them from well-wishers, even after their notional “fall”.

What does shine through most strongly though is how imperfect the safety net was, especially for poor women. There were very few second chances. One of the reasons I’ve ended up reading so much Victorian history is in an attempt to understand my adopted America, as the only comparable era I can find with such fabulous energy and grinding poverty so close together. It has made me wonder about all the stories I don’t know of people just a few hundred meters from me right now who are living on the same kind of knife edge, and might end up dying in poverty. I hope it’s given me a little more moral imagination to understand the struggles that those around me are facing, and motivation to find ways to help. I do know I won’t be able to visit London again without thinking of Polly, Annie, Elizabeth, Kate, and Mary Jane.

Quantization Screencast

TinyML Book Screencast #4 – Quantization

For the past few months I’ve been working with Zain Asgar and Keyi Zhang on EE292D, Machine Learning on Embedded Systems, at Stanford. We’re hoping to open source all the materials after the course is done, but I’ve been including some of the lectures I’m leading as part of my TinyML YouTube series. Since I’ve talked a lot about quantization on this blog over the years, I thought it would be worth including the latest episode here too.

It’s over an hour long, mostly because quantization is still evolving so fast, and I’ve included a couple of Colabs you can play with to back up the lesson. The first lets you load a pretrained Inception v3 model and inspect the weights, and the second shows how you can load a TensorFlow Lite model file, modify the weights, save it out again and check the accuracy, so you can see for yourself how quantization affects the overall results.

The slides themselves are available too, and this is one area where I go into more depth on the screencast than I do in the TinyML book, since that has more of a focus on concrete exercises. I’m working with some other academics to see if we can come up with a shared syllabus around embedded ML, so if you’re trying to put together something similar for undergraduates or graduates at your college, please do get in touch. The TensorFlow team even has grants available to help with the expenses of machine learning courses, especially for traditionally overlooked students.

Converting a TensorFlow Lite .cc data array into a file on disk

Most of the devices TensorFlow Lite for Microcontrollers runs on don’t have file systems, so the model data is typically included by compiling a source file containing an array of bytes into the executable. I recently added a utility to help convert files into nicely-formatted source files and headers, as the convert_bytes_to_c_source() function, but I’ve also had requests to go the other way. If you have a .cc file (like one from the examples) how do you get back to a TensorFlow Lite file that you can feed into other tools (such as the Netron visualizer)?

My hacky answer to this is a Python script that does a rough job of parsing an input file, looks for large chunks of numerical data, converts the values into bytes, and writes them into an output file. The live Gist of this is at and will contain the most up to date version, but here’s the code inline:

import re
output_data = bytearray()
with open('tensorflow/tensorflow/lite/micro/examples/magic_wand/', 'r') as file:
  for line in file:
    values_match = re.match(r"\W*(0x[0-9a-fA-F,x ]+).*", line)
    if values_match:
      list_text =
      values_text = filter(None, list_text.split(","))
      values = [int(x, base=16) for x in values_text]
with open('converted.tfl', 'wb') as output_file:

You’ll need to replace the input file name with the path of the one you want to convert, but otherwise this should work on most of these embedded model data source files.

TinyML Book Released!


I’ve been excited about running machine learning on microcontrollers ever since I joined Google and discovered the amazing work that the speech wakeword team were doing with 13 kilobyte models, and so I’m very pleased to finally be able to share a new O’Reilly book that shows you how to build your own TinyML applications. It took me and my colleague Dan most of 2019 to write it, and it builds on work from literally hundreds of contributors inside and outside Google. The most nerve-wracking part was the acknowledgements, since I knew that we’d miss important people, just because there were so many of them over such a long time. Thanks to everyone who helped, and we’re hoping this will just be the first of many guides to this area. There’s so much fascinating work that can now be done using ML with battery-powered or energy-harvesting devices, I can’t wait to see what the community comes up with!

To give you a taste, there’s a hundred-plus page preview of the first six chapters available as a free PDF, and I’m recording a series of screencasts to accompany the tutorials.

Why you must see Richard Mosse’s Incoming

mosse1.pngImage by Richard Mosse

When I went to SF MoMA over the holiday break I didn’t have a plan for what I wanted to see, but as soon as I saw the first photos of Richard Mosse’s Incoming exhibition I knew where I’d be spending most of my time. His work documents the European refugee crisis in a way I’ve never seen before. The innovation is that he’s using infrared and nightsight cameras designed for surveillance to document the lives and deaths of the people involved, on all sides. The work on show is a set of large stills, and a fifty minute film without narration. I highly encourage you to check out the exhibition yourself, and I’ll be going back to the museum for an artist talk tomorrow (Saturday January 11th at 2pm), but I wanted to share a few thoughts on why I found it so powerful, partly just to help myself understand why it had such an emotional impact on me.

The representation of the scenes is recognizable, but the nightsight makes them different enough that they broke through my familiarity with all the similar images I’ve seen in the news. It forced me to study the pictures in a new way to understand them, they live in an uncanny valley between abstract renders and timeworn visual cliches, and that made them seem much closer to my own life in a strange way. I couldn’t fit what I was seeing into the easy categories I guess I’ve developed of “bad things happening somewhere far away”.

mosse4.pngI realized that I rely on a lot of visual cues to understand the status and importance of people in images like these, and most of those were washed away by the camera rendering. I couldn’t tell what race people were, or even if they were wearing uniforms or civilian clothes, and I realized that I reach for those markers to make sense of images like these. Without those, I was forced to look at the subjects as people rather than just members of a category. I was a bit shocked at how jarring it was to lose that shorthand, and found myself searching for other clues to make up for my loss. Where does the woman in the cover image above come from? I can guess she’s a refugee from the shawl, but I can’t tell much else. My first guess when I saw the photo above is that it was migrants, but the caption told me these were actually crew members of a navy vessel.

It forced me to confront why I have such a need to categorize people to understand the stories. Part of it feels like an attempt to convince myself their predicament couldn’t happen to me or those I love, which is a lot easier if I can slot them into an “other” category


A lot of the images are taken from a long distance away using an extreme zoom, or stitched together from panoramas. On a practical level this gives Mosse access to sites that he couldn’t reach, by shooting from nearby hills or shorelines, but it also affects the way I found myself looking at the scenes. The wide shots (like the refugee camp used for the cover of give you a god-like view, it’s almost isometric like old-school simulation games. I was able to study the layout in a way that felt voyeuristic, but brought the reality home in a way that normal imagery couldn’t have done. There are also closeups that feel intrusive, like paparazzi, but capture situations which normal filmmakers would never be able to, like refugees being loaded onto a navy boat. Everybody seems focused on their actions, working as if they’re unobserved, which adds an edge of reality to the scenes I’m not used to.


Capturing the heat signatures of the objects and people in the scene brings home aspects of the experience that normal photography can’t. One of the scenes that affected me most in the film was seeing a man care for an injured person wrapped in a blanket. The detail that was heartbreaking was that you can see his handprints as marks of warmth as he pats and hugs the victim, and watch as they slowly fade. Handprints show up on the sides of inflatables too, where people tried to climb in. You can also see the dark splashes of frigid seawater as the refugees and crew struggle in a harsh environment, the sharpness of the contrast made me want to shiver as it brought home how cold and uncomfortable everyone had to be.

I can’t properly convey how powerful the exhibition is in words, I just hope this post might encourage some more people to check out Mosse’s work for themselves. The technical innovations alone make this a remarkable project (and I expect to see many other filmmakers influenced by his techniques in the future) but he uses his tools to bring a unfolding tragedy back in the spotlight in a way that only art can do. I can’t say it any better than he does himself in the show’s statement:

Light is visible heat. Light fades. Heat grows cold. People’s attention drifts. Media attention dwindles. Compassion is eventually exhausted. How do we find a way, as photographers and as storytellers, to continue to shed light on the refugee crisis, and to keep the heat on these urgent narratives of human displacement?