Published © CC BY

Classify Candy in Free Fall Using TinyML

Using the Arduino KNN library to classify the color of M&Ms we throw at it.

IntermediateShowcase (no instructions)4,686
Classify Candy in Free Fall Using TinyML

Things used in this project

Hardware components

Arduino Nano 33 BLE Sense
Arduino Nano 33 BLE Sense

Hand tools and fabrication machines

Scissors, Free Fall
Scissors, Free Fall


Read more


Arduino sketch

Classify object without using proximity, using illumination from the Arduino onboard LEDs

  k-NN color classification

  This sketch classifies objects using a color sensor.

  First you 'teach' the Arduino by putting an example of each object close to the color sensor.
  After this the Arduino will guess the name of objects it is shown based on how similar
  the color is to the examples it has seen.

  This example uses a simple case of k-Nearest Neighbour (k-NN) algorithm where k=1.

  HARDWARE: Arduino Nano BLE Sense

  USAGE: Follow prompts in serial console. Move object close to the board to sample its color, then move it away.

  Works best in a well lit area with objects of different colors.

  NOTE: Make sure Serial Monitor's line ending setting is configured for "Newline" or "Both NL & CR".

  This example code is in the public domain.


#include <Arduino_KNN.h>
#include <Arduino_APDS9960.h>

const int INPUTS = 3; // Classifier input is color sensor data; red, green and blue levels
const int CLASSES = 3; // Number of objects we will classify (e.g. Apple, Banana, Orange)
const int EXAMPLES_PER_CLASS = 1; // Number of times user needs to show examples for each object

// K=1 means the classifier looks for the single closest color example it's seen previously
const int K = 1;

// Create a new KNNClassifier
KNNClassifier myKNN(INPUTS);

// Names for each class (object type)
String label[CLASSES];

// Array to store data to pass to the KNN library
float color[INPUTS];

// Threshold for color brightness
const float THRESHOLD = 0.98;
int initialAmbient = 0;

void setup() {

  while (!Serial);

  // Pins for the built-in RGB LEDs on the Arduino Nano 33 BLE Sense
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  if (!APDS.begin()) {
    Serial.println("Failled to initialized APDS!");
    while (1);

  initialAmbient = readAmbient();

  Serial.println("Arduino k-NN color classifier");

  // Ask user for the name of each object
  for (int currentClass = 0; currentClass < CLASSES; currentClass++) {

    Serial.println("Enter an object name:");
    label[currentClass] = readName();

    // Ask user to show examples of each object
    for (int currentExample = 0; currentExample < EXAMPLES_PER_CLASS; currentExample++) {

      Serial.print("Show me an example ");

      // Wait for an object then read its color

      // Add example color to the k-NN model
      myKNN.addExample(color, currentClass);


void loop() {

  int classification;

  // Wait for the object to move away again
  while (!APDS.proximityAvailable() || APDS.readProximity() == 0) {}

  Serial.println("Let me guess your object");

  // Wait for an object then read its color

  // Classify the object
  classification = myKNN.classify(color, K);

  // Print the classification


int readAmbient() {
  int red, green, blue, ambient;
  while (!APDS.colorAvailable()) {};
  APDS.readColor(red, green, blue, ambient);
  return ambient;

void readColor(float color[]) {
  int red, green, blue, ambient = 0, colorTotal = 0;

  // Wait until shadow of object passing
  while (readAmbient() > initialAmbient * THRESHOLD) {}

  // Wait until we have a color bright enough
  while (ambient < initialAmbient * THRESHOLD) {

    // Sample if color is available and object is close
    if (APDS.colorAvailable()) {

      // Read color and proximity
      APDS.readColor(red, green, blue, ambient);
      colorTotal = (red + green + blue);

  // Normalise the color sample data and put it in the classifier input array
  color[0] = (float)red / colorTotal;
  color[1] = (float)green / colorTotal;
  color[2] = (float)blue / colorTotal;

  // Print the red, green and blue percentage values

// reads a name from the Serial Monitor
String readName() {
  String line;

  while (1) {
    if (Serial.available()) {
      char c = Serial.read();

      if (c == '\r') {
        // ignore
      } else if (c == '\n') {

      line += c;

  return line;




3 projects • 34 followers