Using TinyML on Arduino to Scan Plant Leaves for Health

This article is from Arduino Project Hub

Author: Arduino “having11” Guy

Using TinyML on Arduino to Scan Plant Leaves for Health

Prerequisites

Like humans, plants can also get sick; for instance, the leaves of a plant may turn yellow or develop spots due to fungi or other pathogens. Thus, by harnessing the power of machine learning, we can scan the colors and then use them to train a model that can detect the color of the leaves and make judgments about their health status.

Hardware

This project primarily uses the Arduino Nano 33 BLE Sense, chosen mainly for its powerful set of sensors, including a 9DoF IMU, APDS-9960 (for color, gesture, proximity, and brightness), a microphone, and a temperature/humidity/pressure sensor combo. To allow the circuit board to move around the plant leaves and take measurements, a pair of stepper motors is used in conjunction with a pair of DRV8825 driver boards.

Using TinyML on Arduino to Scan Plant Leaves for Health

Using TinyML on Arduino to Scan Plant Leaves for Health

Setting Up TinyML

For this project, the built-in sensors listed for the Arduino Nano 33 BLE Sense on Edge Impulse will not work, meaning we must use the data forwarder instead of the serial daemon.

First, create a new project and name it. Next, you need to install the EdgeImpulse CLI using Node.js and NPM. Then run:

npm install -g edge-impulse-cli

If the installation path cannot be found, you may need to add its installation path to the PATH environment variable. Next, run

edge-impulse-data-forwarder
and ensure it is working, then press Ctrl + C to exit.

Using TinyML on Arduino to Scan Plant Leaves for Health

Color Recognition

The APDS-9960 works by reading the wavelengths of light reflected off the surface of an object to determine its color. To communicate with the sensor, it’s best to install the Arduino APDS9960 library, which provides access to some useful functions.

In the code, first initialize the APDS-9960, and then the program enters a loop function, waiting until color data is available. If readings are available, use

APDS.readColor()

and the proximity to the surface to read the color. Each RGB component is converted from 0-2 ^ 16-1 to its value as a ratio of the total.

Scanner

Scanning the color of the leaves is done by moving the equipment along two axes to allow the leaves to pass under the onboard APDS-9960 at various positions. Each axis is moved by rotating the screw in a clockwise or counterclockwise direction to translate the program segment in either direction. The entire system was designed in Fusion 360, and below are some renderings of these designs:

Using TinyML on Arduino to Scan Plant Leaves for Health

Using TinyML on Arduino to Scan Plant Leaves for Health

Using TinyML on Arduino to Scan Plant Leaves for Health

The X-axis is positioned above the Y-axis, allowing the top program segment to move on both axes. The Y-axis has an additional V wheel to support the weight of the stepper motor. The parts are printed using PLA with a fill rate of about 45%.

Using TinyML on Arduino to Scan Plant Leaves for Health

Collecting Data

When the system first starts, the stepper motors do not know their initial position, so we must perform a homing reset (which can be achieved via limit switches). Next, initialize the APDS-9960. There is a bounding box defined as an array of two elements that contains the relative corners of a box. A random point is then selected between these two positions, and the stepper runs to that position while reading the color between them.

Processing and Sending Color Information

As mentioned earlier, use

APDS.readColor()

to read the color. After calculating the total, the percentage is computed and sent via USB by calling

Serial.printf()
with the values separated by commas and each reading separated by a newline. After receiving the data, the data forwarder program sends it as training data to the Edge Impulse cloud with a given label (healthy or unhealthy).

Using TinyML on Arduino to Scan Plant Leaves for Health

Using TinyML on Arduino to Scan Plant Leaves for Health

Training the Model

After collecting all the training data, it’s time to build a model that can distinguish between healthy and unhealthy leaves. I used a pulse composed of a three-axis time series, spectral analysis module, and Keras module. The following screenshots show how I generated these features from the data:

Using TinyML on Arduino to Scan Plant Leaves for Health

Using TinyML on Arduino to Scan Plant Leaves for Health

Testing

To test the new model, I collected some new test data, which was unhealthy. The model’s accuracy is about 63%, and after going through some test features, it was able to classify the leaves correctly most of the time.

Using TinyML on Arduino to Scan Plant Leaves for Health

This accuracy can be improved by adding more training data and slowing down the training speed.

Code

#include <Arduino_APDS9960.h>#include <AccelStepper.h>#include <MultiStepper.h>#include "pinDefs.h" int r, g, b, c, p;
float sum;
AccelStepper xStepper(AccelStepper::DRIVER, STEPPER_1_STEP, STEPPER_1_DIR);
AccelStepper yStepper(AccelStepper::DRIVER, STEPPER_2_STEP, STEPPER_2_DIR);
MultiStepper steppers;// a random location will be chosen within the bounding box
const long boundingBox[2][2] = {    {0,0},    {40,40}};
void setup(){    Serial.begin(115200);    while(!Serial);
    if(!APDS.begin()) {        Serial.println("Could not init APDS9960");        while(1);    }
    pinMode(X_AXIS_HOMING_SW, INPUT_PULLUP);    pinMode(Y_AXIS_HOMING_SW, INPUT_PULLUP);    //Serial.println(digitalRead(X_AXIS_HOMING_SW) + digitalRead(Y_AXIS_HOMING_SW));    xStepper.setPinsInverted(X_AXIS_DIR);    yStepper.setPinsInverted(Y_AXIS_DIR);    xStepper.setMaxSpeed(150);    yStepper.setMaxSpeed(150);    steppers.addStepper(xStepper);    steppers.addStepper(yStepper);    homeMotors();}
void loop(){    long randomPos[2];    randomPos[0] = random(boundingBox[0][0], boundingBox[1][0]) * STEPS_PER_MM;    randomPos[1] = random(boundingBox[0][1], boundingBox[1][1]) * STEPS_PER_MM;    steppers.moveTo(randomPos);
    while(steppers.run())    {        if(!APDS.colorAvailable() || !APDS.proximityAvailable()){}        else {            APDS.readColor(r, g, b, c);            sum = r + g + b;            p = APDS.readProximity();
            if(!p && c > 10 && sum >= 0)            {                float rr = r / sum, gr = g / sum, br = b / sum;                Serial.printf("%1.3f,%1.3f,%1.3f\n", rr, gr, br);            }        }    }}
void homeMotors(){    // home x    //Serial.println("Now homing x");    while(digitalRead(X_AXIS_HOMING_SW))
        xStepper.move(-1);
    // home y    //Serial.println("Now homing y");    while(digitalRead(Y_AXIS_HOMING_SW))        yStepper.move(-1);    xStepper.setCurrentPosition(0);    yStepper.setCurrentPosition(0);}

Schematic

Using TinyML on Arduino to Scan Plant Leaves for Health
Arduino Technical Communication Group

The communication group is ready for everyone, and next, Teacher Yinghe will lead everyone to get started with Arduino series development boards. Please scan the QR code below to join the group. If the group QR code has expired, you can reply with the keyword “Arduino” in the “Yinghe Academy” public account to join the group chat.

Using TinyML on Arduino to Scan Plant Leaves for Health

END

Yinghe Academy

The Yinghe team is committed to providing standardized core skill courses for electronic engineers and students in related fields, helping everyone effectively improve their professional abilities at all stages of learning and work.

Using TinyML on Arduino to Scan Plant Leaves for Health

Yinghe Academy

Let’s explore and advance together in the field of electronics

Follow the Yinghe public account for immediate access to classes

Using TinyML on Arduino to Scan Plant Leaves for Health

Click to read the original text for more

Leave a Comment