You won't believe it, but you can run Machine learning on embedded systems like an Attiny85 (and many others Attiny)!

ri-elaborated from https://cyaninfinite.com/miniaturize-projects-with-attiny85/

When I first run a Machine learning project on my Arduino Nano (old generation), it already felt a big achievement. I mean, that board has only 32 Kb of program space and 2 Kb of RAM and you can buy a chinese clone for around 2.50 $.

It already opened the path to a embedded machine learning at a new scale, given the huge amount of microcontrollers ready to become "intelligent".

But it was not enough for me: after all, the MicroML generator exports plain C that should run on any embedded system, not only on Arduino boards.

So I setup to test if I could go even smaller and run it on the #1 of tiny chips: the Attiny85.

MicroML exports plain C that could run anywhere, not only on Arduino boards. Click To Tweet

No, I couldn't.

The generated code makes use of a variadic function, which seems to not be supported by the Attiny compiler in the Arduino IDE.

So I had to come up with an alternative implementation to make it work.

Fortunately I already experimented with a non-variadic version when first writing the porter, so it was a matter of refreshing that algorithm and try it out.

Guess what? It compiled!

So I tried porting one my earliear tutorial (the color identification one) to the Attiny and...

Boom! Machine learning on an Attiny85! Click To Tweet

Here's a step-by-step tutorial on how you can do it too.

I strongly suggest you read the original tutorial before following this one, because I won't go into too much details on the common steps here.

1. Features definition

We're going to use the RGB components of a color sensor (TCS3200 in my case) to infer which object we're pointing it at. This means our features are going to be 3-dimensional, which leads to a really simple model with very high accuracy.

The Attiny85 has 8 Kb of flash and 512 bytes of RAM, so you won't be able to load any model that uses more than a few features (probably less than 10).

2. Record sample data

You must do this step on a board with a Serial interface, like an Arduino Uno / Nano / Pro Mini. See the original tutorial for the code of this step.

3. Train and export the SVM classifier

This part is exactly the same as the original, except for a single parameter: you will pass platform=attiny to the port function.

from sklearn.svm import SVC
from micromlgen import port

# put your samples in the dataset folder
# one class per file
# one feature vector per line, in CSV format
features, classmap = load_features('dataset/')
X, y = features[:, :-1], features[:, -1]
classifier = SVC(kernel='linear').fit(X, y)
c_code = port(classifier, classmap=classmap, platform='attiny')
print(c_code)
The Attiny mode has been implemented in version 0.8 of micromlgen: if you installed an earlier version, first update

At this point you have to copy the printed code and import it in your project, in a file called model.h.

Want to learn more?

4. Run the inference

Since we don't have a Serial, we will blink a LED a number of times dependant on the prediction result.

#include "model.h"

#define LED 0

void loop() {
  readRGB();
  classify();
  delay(1000);
}

void classify() {
    for (uint8_t times = predict(features) + 1; times > 0; times--) {
        digitalWrite(LED, HIGH);
        delay(10);
        digitalWrite(LED, LOW);
        delay(10);
    }
}

Here we are: put some colored object in front of the sensor and see the LED blink.

Project figures

On my machine, the sketch requires 3434 bytes (41%) of program space and 21 bytes (4%) of RAM. This means you could actually run machine learning in even less space than what the Attiny85 provides.

This model in particular it's so tiny you can run in even on an Attiny45, which has only 4 Kb of flash and 256 bytes of RAM.

I'd like you to look at the RAM figure for a moment: 21 bytes. 21 bytes is all the memory you need to run a Machine learning algorithm on a microcontroller. This is the result of the implementation I chose: the least RAM overhead possible. I challenge you to go any lower than this.

21 bytes is all the memory you need to run a Machine learning algorithm on a microcontroller Click To Tweet

Troubleshooting

It can happen that when running micromlgen.port(clf) you get a TemplateNotFound error. To solve the problem, first of all uninstall micromlgen.

pip uninstall micromlgen

Then head to Github, download the package as zip and extract the micromlgen folder into your project.


Did you find this tutorial useful? Was is it easy to follow or did I miss something? Let me know in the comments so I can keep improving the blog.



Check the full project code on Github

Help the blow grow