Color Identification with Machine Learning in Arduino

In this Arduno Machine learning project we will use an RGB sensor to identify objects by color.
This is a version of the project found on the Tensorflow blog. In this tutorial we will use a much less powerful chip, an Arduino Nano (older generation) equipped with a 32 kb flash and only 2 kb of RAM.

Properties Definition

To understand which object we're pointing at, we need a color sensorTCS3200) RGB components. This means that our features will be 3D, which leads to a really simple model with very high accuracy.

Saving Sample Data

We do not need any processing to get to the property vector from sensor readings, so the code will be simple: read each component from the sensor and assign it to the set of features.This part will vary according to the specific chip you have.

#define S2 2
#define S3 3
#define sensorOut 4

double features[3];

void setup() {
  Serial.begin(115200);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
}

void loop() {
  readRGB();
  printFeatures();
  delay(100);
}

int readComponent(bool s2, bool s3) {
  delay(10);
  digitalWrite(S2, s2);
  digitalWrite(S3, s3);

  return pulseIn(sensorOut, LOW);
}

void readRGB() {
  features[0] = readComponent(LOW, LOW);
  features[1] = readComponent(HIGH, HIGH);
  features[2] = readComponent(LOW, HIGH);
}
void printFeatures() {
    const uint16_t numFeatures = sizeof(features) / sizeof(float);
    
for (int i = 0; i < numFeatures; i++) {
        Serial.print(features[i]);
        Serial.print(i == numFeatures -  1 ? 'n' : ',');
    }
}

Turn on the serial monitor and put some colored objects in front of the sensor: move and rotate the object a little, so that the samples will contain different shades.

Save records for each color to a file that bears the name of the color, so you get meaningful results later.

Do not forget to try the "blank color" as well: do not put anything in front of the sensor and let it record for a while.

If you perform a smooth installation, you should finish with distinctive features, as shown in the stroke chart below.


Decision limits of 2 PCA components from color properties

Training and Exporting the Classifier

See this tutorial for a detailed guide.

from sklearn.ensemble import RandomForestClassifier
from micromlgen import port

# place your samples in the dataset folder# one class per file# One propertyvector per line in CSV format
features, classmap = load_features('dataset/')
X, y = features[:, :-1], features[:, -1]
classifier = RandomForestClassifier(n_estimators=30, max_depth=10).fit(X, y)
c_code = port(classifier, classmap=classmap)
print(c_code)


At this point, you must copy the printed code and transfer it to a file named mode.hl in your Arduino project.

Running Inference

#include model.h

void loop() {
  readRGB();
  Serial.println(classIdxToName(predict(features)));
  delay(1000);
}

Put a colored object in front of the sensor and see the defined object name printed on the serial monitor.

Do you remember the "blank color"? That's why it needs to be saved, so you'll be an "empty" value when there are no objects, otherwise you'll get unexpected predictions

Given the simplicity of the task, you should easily achieve close to 100% accuracy for different colors (there may be some difficulties in distinguishing orange from yellow due to poor lighting). Be sure to duplicate the same setup during both training and classification.

That's it: you ran machine learning at 2 Kb!

Targeting Arduino Nano (older generation), the project requires 5570 bytes (18%) program space and 266 bytes (12%) RAM. This means that you can run machine learning in fewer areas than Arduino Nano provides.