Determinando a saúde das plantas com TinyML
Componentes e suprimentos
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 |
Ferramentas e máquinas necessárias
![]() |
| |||
![]() |
|
Aplicativos e serviços online
![]() |
| |||
![]() |
| |||
![]() |
|
Sobre este projeto
A premissa
Assim como os humanos, as plantas também podem ficar doentes. E assim como você pode desenvolver uma erupção cutânea por causa de uma infecção de pele, as folhas de uma planta podem ficar amareladas e / ou manchadas por um fungo ou outro patógeno. Portanto, aproveitando o poder do aprendizado de máquina, as cores podem ser digitalizadas e usadas para treinar um modelo que pode detectar quando a cor de uma folha está desativada.
O Hardware
O cérebro desse projeto é o Arduino Nano 33 BLE Sense, e ele foi escolhido por vários motivos. Primeiro, ele possui um conjunto rico de sensores poderosos, incluindo um 9DoF IMU, APDS-9960 (cor, gesto, proximidade e brilho), microfone e uma combinação de sensor de temperatura / umidade / pressão. Para mover a placa ao redor da folha da planta e fazer medições, um par de motores de passo é usado em conjunto com um par de placas de driver DRV8825.


Configurando TinyML
Para este projeto, os sensores integrados listados para o Arduino Nano 33 BLE Sense no Edge Impulse não funcionarão, já que apenas o acelerador e o microfone estão listados. Isso significa que o encaminhador de dados terá que ser usado em vez do daemon serial. Para começar, criei um novo projeto e nomeei-o. Em seguida, instalei o Edge Impulse CLI instalando Node.js e NPM e, em seguida, executando
npm install -g edge-impulso-cli
. Você pode precisar adicionar seu caminho de instalação à sua variável de ambiente PATH se ele não puder ser encontrado. Em seguida, execute edge-boost-data-forwarder
e certifique-se de que funciona e, em seguida, use Ctrl + C para sair. 
Leitura a cores
O APDS-9960 lê as cores refletindo a luz infravermelha da superfície e lendo os comprimentos de onda que não são absorvidos pelo material. Para se comunicar com o sensor, é melhor instalar a biblioteca Arduino APDS9960, que dá acesso a várias funções úteis. No código, o APDS-9960 é inicializado primeiro e, em seguida, o programa entra na função de loop. Lá, ele espera até que haja dados de cores. Se uma leitura estiver disponível, a cor é lida com
APDS.readColor ()
junto com a proximidade com a superfície. Cada componente RGB é convertido de um número 0-2 ^ 16-1 em uma proporção de seu valor sobre a soma.
A plataforma de digitalização
A digitalização da cor de uma folha é realizada movendo um equipamento em dois eixos para passar por vários locais da folha sob o APDS-9960 a bordo. Cada eixo é movido girando um parafuso de avanço no sentido horário ou anti-horário para transladar um bloco em qualquer direção. Todo o sistema foi projetado no Fusion 360, e aqui estão alguns renderizadores do design abaixo:



O eixo X repousa sobre o eixo Y, permitindo que o bloco superior se mova em ambos os eixos. Há uma roda em V adicional no eixo Y para suportar o peso do motor de passo. As peças foram impressas em plástico PLA com cerca de 45% de preenchimento.

Coletando dados
Quando o sistema é inicializado pela primeira vez, os motores de passo não sabem onde estão, então os dois eixos se movem para a origem passo a passo até atingirem o interruptor de limite. Em seguida, o APDS-9960 é inicializado. Existe uma caixa delimitadora que é definida como duas matrizes de dois elementos que contêm cantos opostos de uma caixa. Um ponto aleatório é escolhido entre esses dois locais e, em seguida, os steppers são executados para essa posição enquanto lêem as cores intermediárias.
Processamento e envio de informações de cores
As cores são lidas com
APDS.readColor ()
, Como mencionado anteriormente. Depois que a soma é calculada, uma porcentagem é calculada e enviada via USB chamando o Serial.printf ()
método. Os valores são separados por vírgulas e cada leitura é separada por um caractere de nova linha. Quando os dados são recebidos pelo programa de encaminhamento de dados, eles são enviados para o projeto de nuvem Edge Impulse como dados de treinamento com o rótulo fornecido (como íntegros ou não íntegros). 

Treinando um modelo
Depois que todos os dados de treinamento foram coletados, é hora de fazer um modelo que possa diferenciar entre folhas saudáveis e não saudáveis. Usei um impulso composto por séries temporais de três eixos, um bloco de análise espectral e um bloco de Keras. Você pode ver a captura de tela abaixo de como eu gerei os recursos a partir dos dados:


Teste
Para testar meu novo modelo, reuni alguns novos dados de teste, desta vez de uma folha não íntegra. A precisão do modelo ficou em torno de 63% e, após enviar alguns recursos de teste, conseguiu classificar corretamente a folha na maioria das vezes.

Essa precisão pode ser melhorada adicionando mais dados de treinamento e diminuindo a velocidade de treinamento.
Código
- leafReader.ino
- pinDefs.h
leafReader.ino C / C ++
#include#include #include #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; // um local aleatório será escolhido dentro da caixa delimitadoraconst long boundingBox [2] [2] }, {40, 40}}; configuração vazia () {Serial.begin (115200); while (! Serial); if (! APDS.begin ()) {Serial.println ("Não foi possível iniciar o APDS9960"); enquanto (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); soma =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 "); enquanto (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);}
pinDefs.h C / C ++
#define STEPPER_1_STEP 2 # 3 # definir STEPPER_1_DIR definir STEPPER_2_STEP 4 # 5 # definir STEPPER_2_DIR definir X_AXIS_HOMING_SW 6 # definir Y_AXIS_HOMING_SW 7 // # verdadeiro se invertidos definir X_AXIS_DIR falsos # definir Y_AXIS_DIR falsos # definir micropassos 1 # definir STEPS_PER_MM 160 * micropassos
Peças personalizadas e gabinetes
Peças para impressão 3D
Arquivo CAD em thingiverse.comEsquemas

Processo de manufatura
- Monitoramento de CO2 com Sensor K30
- Comunicação para surdos-cegos com 1Sheeld / Arduino
- Aceitar moeda de controle com Arduino
- Arduino com Bluetooth para controlar um LED!
- Sensor capacitivo de impressão digital com um Arduino ou ESP8266
- Brincando com Nextion Display
- Braço robótico controlado por Nunchuk (com Arduino)
- Arduino Nano:Controle 2 motores de passo com joystick
- Medindo a radiação solar com Arduino
- Mini Radar com Arduino