Определение здоровья растений с помощью TinyML
Компоненты и расходные материалы
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 |
Необходимые инструменты и машины
![]() |
| |||
![]() |
|
Приложения и онлайн-сервисы
![]() |
| |||
![]() |
| |||
![]() |
|
Об этом проекте
Предпосылка
Как и люди, растения тоже могут заболеть. И точно так же, как у вас может развиться сыпь от кожной инфекции, листья растения могут пожелтеть и / или покрываться пятнами из-за грибка или другого патогена. Таким образом, используя возможности машинного обучения, цвета можно сканировать, а затем использовать для обучения модели, которая может определять, когда цвет листьев отключен.
Оборудование
Мозгом этого проекта является Arduino Nano 33 BLE Sense, и он был выбран по нескольким причинам. Во-первых, он имеет богатый набор мощных датчиков, включая 9DoF IMU, APDS-9960 (цвет, жест, приближение и яркость), микрофон и комбинированный датчик температуры / влажности / давления. Чтобы перемещать плату по листу растения и проводить измерения, используется пара шаговых двигателей в сочетании с парой плат драйверов DRV8825.


Настройка TinyML
Для этого проекта встроенные датчики, перечисленные для Arduino Nano 33 BLE Sense на Edge Impulse, не будут работать, поскольку указаны только ускоритель и микрофон. Это означает, что вместо последовательного демона придется использовать перенаправитель данных. Для начала я создал новый проект и назвал его. Затем я установил интерфейс командной строки Edge Impulse, установив Node.js и NPM, а затем запустив npm install -g edge-impulse-cli
. Вам может потребоваться добавить его путь установки в переменную среды PATH, если он не может быть найден. Затем запустите edge-impulse-data-forwarder
и убедитесь, что он работает, затем нажмите Ctrl + C для выхода.

Цвет чтения
APDS-9960 считывает цвет, отражая инфракрасный свет от поверхности и считывая длины волн, которые не поглощаются материалом. Для связи с датчиком лучше всего установить библиотеку Arduino APDS9960, которая дает доступ к нескольким полезным функциям. В коде сначала инициализируется APDS-9960, а затем программа входит в функцию цикла. Там он ждет, пока не появятся данные о цвете. Если чтение доступно, цвет считывается с помощью APDS.readColor ()
наряду с близостью к поверхности. Каждый компонент RGB преобразуется из числа 0-2 ^ 16-1 в отношение его значения к сумме.
Сканирующая установка
Сканирование цвета листа осуществляется перемещением буровой установки по двум осям для прохождения различных участков листа под бортовым APDS-9960. Каждая ось перемещается путем вращения ходового винта по часовой стрелке или против часовой стрелки для перемещения блока в любом направлении. Вся система была разработана в Fusion 360, и вот некоторые отрисовки дизайна ниже:



Ось X лежит поверх оси Y, позволяя верхнему блоку перемещаться по обеим осям. На оси Y есть дополнительное V-образное колесо, которое выдерживает вес шагового двигателя. Детали были напечатаны с использованием пластика PLA с заполнением около 45%.

Сбор данных
Когда система запускается впервые, шаговые двигатели не знают, где они находятся, поэтому две оси возвращаются в исходное положение, шаг за шагом перемещаясь в исходное положение, пока они не достигнут концевого выключателя. Затем инициализируется APDS-9960. Существует ограничивающий прямоугольник, который определяется как два двухэлементных массива, содержащих противоположные углы прямоугольника. Между этими двумя местоположениями выбирается случайная точка, а затем шаговые двигатели запускаются в это положение, считывая цвета между ними.
Обработка и отправка информации о цвете
Цвета читаются с помощью APDS.readColor ()
, как упоминалось ранее. После вычисления суммы рассчитывается процентное значение, которое затем отправляется через USB с помощью вызова Serial.printf ()
метод. Значения разделяются запятыми, и каждое чтение отделяется символом новой строки. Когда данные получены программой пересылки данных, они отправляются в облачный проект Edge Impulse в качестве обучающих данных с заданной меткой (как работоспособные или нездоровые).


Обучение модели
После того, как все данные для обучения собраны, пора создать модель, которая сможет различать здоровые и нездоровые листья. Я использовал импульс, состоящий из трехосного временного ряда, блока спектрального анализа и блока Кераса. На снимке экрана ниже показано, как я сгенерировал функции из данных:


Тестирование
Чтобы проверить свою новую модель, я собрал несколько новых тестовых данных, на этот раз нездорового листа. Точность модели составила около 63%, и после отправки некоторых функций тестирования она в большинстве случаев могла правильно классифицировать лист.

Эту точность можно повысить, добавив больше обучающих данных и снизив скорость обучения.
Код
- leafReader.ino
- pinDefs.h
leafReader.ino C / C ++
#include#include #include #include "pinDefs.h" int r, g, b, c, p; сумма с плавающей запятой; AccelStepper xStepper (AccelStepper::DRIVER, STEPPER_1_STEP, STEPPER_1_DIR); AccelStepper yStepper (AccelStepper ::DRIVER, STEPPER_2_STEP, STEPPER_2_DIR); MultiStepper степперы; // в пределах ограничивающего прямоугольника будет выбрано случайное местоположениеconst long boundingBox [2] [2] ={{0, }, {40, 40}}; void setup () {Serial.begin (115200); в то время как (! серийный); if (! APDS.begin ()) {Serial.println ("Не удалось запустить APDS9960"); в то время как (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 ()) {если (! APDS.colorAvailable () ||! APDS.proximityAvailable ()) {} else {APDS.readColor (r, g, b, c); сумма =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 "); в то время как (digitalRead (X_AXIS_HOMING_SW)) xStepper.move (-1); // домой y //Serial.println("Now homing y "); в то время как (digitalRead (Y_AXIS_HOMING_SW)) yStepper.move (-1); xStepper.setCurrentPosition (0); yStepper.setCurrentPosition (0);}
pinDefs.h C / C ++
<Предварительно> #define STEPPER_1_STEP 2 # определить STEPPER_1_DIR-# определить STEPPER_2_STEP 4 # определить STEPPER_2_DIR-# определить X_AXIS_HOMING_SW-# определить Y_AXIS_HOMING_SW-// верно, если инвертированные # определить ложные X_AXIS_DIR # определить ложные Y_AXIS_DIR # определить микрошаги 1 # определить STEPS_PER_MM 160 * микрошагиИзготовленные на заказ детали и корпуса
Детали для 3D-печати
Файл САПР на сайте thingiverse.comСхема

Производственный процесс
- Мониторинг CO2 с помощью датчика K30
- Слепоглухое общение с 1Sheeld / Arduino
- Управление монетоприемником с помощью Arduino
- Arduino с Bluetooth для управления светодиодом!
- Емкостной датчик отпечатков пальцев с Arduino или ESP8266
- Игра с дисплеем Nextion
- Роботизированная рука, управляемая нунчук (с Arduino)
- Arduino Nano:управление двумя шаговыми двигателями с помощью джойстика
- Измерение солнечной радиации с помощью Arduino
- Мини-радар с Arduino