In this Arduino Machine Learning project, we will use an accelerometer sensor to identify your movements. This content is actually a reconstruction of a project on the Tensorflow blog. Unlike the writing on the Tensorflow block, we'll use the older generation and the weaker Arduino Nano instead of the Arduino Nano 33 BLE. Arduino Nano, 32kb flash and onlyIt is a development card equipped with 2 kb of RAM.
Description of Properties
To understand what movement we are making, we will use accelerations along 3 axes (X, Y, Z) from an IMU, that is, the accelerometer sensor.
With NUM_SAMPLES, we will record a fixed number of transactions starting from the first motion detection.
This means that our feature vectors will be large enough to fit in the memory of the Arduino Nano NUM_SAMPLES
Wewill start with a low value to keep NUM_SAMPLES as lean as possible. If your classifications suffer from insufficient accuracy, you can increase this number.
Saving Sample Data
Reading Data From Sensor (IMU)
First of all, we need to read the raw data from the sensor.This piece of code will differ depending on the specific sensor you are using.We will use the 9-axis "MPU9250" sensor alternatively you can use a different acceleration sensor or the MPU6050 sensor, which is the same family member. To keep things simple and understandable, we will perform the sensor installation and reading process in 2 functions:
You can see several sample applications for MPU6050 and MPU 9250.No matter what code you use, you must save the sensor code you use to call in the project's main code in a file named imu.h. In addition, keeping all the codes and files in one folder will make your job easier.
In the main .ino file, we pour the sensor values into the serial monitor / plotter:
Open the serial plotter and move it a little to get an idea of the range of your readings:
Due to gravity, we get a constant value of -9.8 on the static Z axis (you can see this from the moving image at the top).To eliminate this constant value, we need to create a offset of 9.8, so that it is not affected by the moving gravity made on the Z axis.
After Z-axis calibration, the serial plotter will look like this:
Detecting The First Move
Now we need to check for movement.To keep it simple, we will use a pure approach that will look for a high value in acceleration: if a threshold is exceeded, it will mean that a movement begins.
If you have done the calibration step, a threshold of 5 should work well.If you have not calibrated, you need to find a value that suits your needs.
If there is no action, we do not take any action and we continue to monitor it.If there's movement,
we'llprint the next NUM_SAMPLES readings to the serial monitor.
Let's save 15-20 instances for each transaction and save one for each transaction to a single file.Since we deal with multidimensional data, you need to collect as many samples as possible to average the noise.
Training and Exporting the Classifier
If the code below doesn't mean anything to you; If you want to use a python or C++ trained model on Arduino or other development cards, you can learn the details in this article.
At this point, you need to copy the printed code and save it as
model.h in your Arduino project folder.
Unlike previous and simpler ones, we can't easily achieve 100% accuracy in this project on machine learning.The movement is quite noisy, so you should try a few parameters for the classifier and choose the ones that perform best.Let's show a few examples:
Decision limits of 2 PCA components of sensor properties, linearkernel
Decision limits of 2 PCA components of sensor properties,Polynomial kernel
Decision limits of 2 PCA components of sensor properties, RBF core (kernel), 0.01 gamma
Decision limits of 2 PCA components of sensor properties, RBF core (kernel), 0.001 gamma
Choosing the Right Model
Now that we have chosen the best model, we must transfer it to code C.Here comes the problem: not all models will fit on the development card.
The core of the SVM (Support Vector Machines) are support vectors: each trained classifier will be characterized by a certain number.The problem is that if there are too many, the generated code will be too large to fit in the microprocessor's flash.
Therefore, instead of choosing the best model for accuracy, you should sort from best performer to worst.For each model, starting from the beginning, you should transfer it to your Arduino project and try to compile it: if it fits, you can use it without problems.Otherwise, you should choose the next one and try again.
It may seem like a tedious process, but keep in mind that we are trying to extract a class from 90 features in 2 Kb RAM and 32 Kb flash.
Here are a few numbers for the different combinations we tested:
|Kernel||C||Gamma||Degrees||Vectors||Flash size||RAM (b)||Avg. accuracy|
As you can see, we achieved very high accuracy in the test set for all classifiers: we used only one in arduino nano.Of course, if you use a larger microprocessor, you can also use others.
As a side note, take a look at the RAM column, all values are equal. This is because it is independent of the number of support vectors in the application and depends only on the number of properties.
We've finished all the work and the work. You can now classify transactions with Arduino Nano and 2 Kb RAM. Without long neural networks, Tensorflow, 32-bit ARM processors, we performed a 97% SVM-based machine learning with an 8-bit microprocessor.
Targeting Arduino Nano (older generation), the program requires 25310 bytes (82%) of program space and 1228 bytes (59%) of RAM.This means that you can run machine learning in even fewer areas than Arduino Nano provides.So we have shown that the answer to the question of whether I can run machine learning on Arduino is clearly YES.