Accedé a la primera parte de este proyecto
Paso 1: Diseño e impresión de una funda con temática vegetal
Dado que me enfoqué en construir un dispositivo económico y accesible que capture imágenes de suelos con fertilizantes y ejecute un modelo de detección de objetos para informar al usuario sobre el uso excesivo de fertilizantes químicos a través de WhatsApp a través de la red LoRaWAN, decidí diseñar un modelo modular. y estuche compacto que permite al usuario colocar el control remoto y posicionar SenseCAP A1101 con LattePanda 3 Delta sin esfuerzo. Para evitar la exposición excesiva al polvo y las conexiones de cables sueltas, añadí una cubierta frontal deslizante. Luego, diseñé una cubierta superior diagonal para la sección separada del control remoto de la carcasa principal, que se puede montar mediante juntas de encaje a presión. Además, decidí inscribir el logotipo de Helium y el símbolo de Arduino en la cubierta frontal deslizante y en la cubierta superior diagonal para resaltar la detección de contaminación de fertilizantes habilitada por LoRaWAN.
Como necesitaba conectar SenseCAP A1101 a la carcasa principal a través de su soporte, decidí agregar orificios para tornillos compatibles en la parte superior de la carcasa principal. Debido a la sección separada, pude instalar el control remoto y conectarlo a LattePanda 3 Delta como una sola unidad.
Diseñé la carcasa principal, su cubierta frontal deslizante y la cubierta superior diagonal en Autodesk Fusion 360. Puede descargar sus archivos STL a continuación.
Luego, corté todos los modelos 3D (archivos STL) en Ultimaker Cura.
Como quería crear una estructura vegetal reluciente para la caja principal y aplicar un tema verde único que denotara plantas florecientes, utilicé estos filamentos de PLA:
- Lima eSilk
- Verde RAL 6029
Finalmente, imprimí todas las partes (modelos) con mi nueva impresora 3D Anycubic Kobra 2
Dado que Anycubic Kobra 2 es económico y está diseñado específicamente para la impresión de alta velocidad, le recomiendo Anycubic Kobra 2 si es un fabricante o un aficionado que necesita imprimir varios prototipos antes de finalizar un proyecto complejo.
Gracias a su extrusor directo mejorado, Anycubic Kobra 2 proporciona una velocidad de impresión recomendada de 150 mm/s (hasta 250 mm/s) y alimentación de filamento de doble engranaje. Además, proporciona un ventilador de enfriamiento con un diseño de disipación optimizado para admitir un enfriamiento rápido que complementa la experiencia de impresión rápida. Dado que el eje Z tiene una estructura de varilla de doble rosca, aplana la plataforma de construcción y reduce las capas de impresión, incluso a mayor velocidad.
Además, Anycubic Kobra 2 proporciona una plataforma de succión magnética en la cama calentada para la placa de construcción de acero con resorte resistente a los arañazos, lo que permite al usuario quitar las impresiones sin ningún problema. Lo que es más importante, puede nivelar la cama automáticamente a través de su sistema de nivelación de cama automática LeviQ 2.0 fácil de usar. Además, tiene un sensor de agotamiento de filamento inteligente y la función de reanudar la impresión para fallas de energía.
1# En primer lugar, instale el pórtico y la placa de construcción de acero para resortes.
2# Instale el cabezal de impresión, la pantalla táctil y el sensor de agotamiento del filamento.
3# Conecte los cables paso a paso, interruptor, pantalla y cabezal de impresión. Luego, conecte el tubo de filamento.
4# Si el cabezal de impresión tiembla, ajuste la columna de aislamiento hexagonal debajo del cabezal de impresión.
5# Vaya a Preparar➡ Nivelación ➡ Nivelación automática para iniciar el sistema de nivelación automática de la cama LeviQ 2.0.
6# Después de precalentar y limpiar la boquilla, Anycubic Kobra 2 sondea los puntos predefinidos para nivelar la cama.
6# Por último, fije el tubo del filamento con las abrazaderas para cables, instale el soporte del filamento e inserte el filamento en el extrusor.
7# Dado que Anycubic Kobra 2 aún no es oficialmente compatible con Cura, descargue la última versión de PrusaSlicer e importe el archivo de perfil de impresora (configuración) proporcionado por Anycubic.
8# Luego, cree un perfil de impresora personalizado en Cura para Anycubic Kobra 2 y cambie el código G de inicio y el código G final .
9# Según el código G de inicio y el código G final proporcionados en el archivo de configuración, modifiqué un nuevo código G de inicio y un código G final compatibles con Cura.
10# Según el código G de inicio y el código G final proporcionados en el archivo de configuración, modifiqué un nuevo código G de inicio y un código G final compatibles con Cura.
Start G-code:
G90 ; use absolute coordinates
M83 ; extruder relative mode
G28 ; move X/Y/Z to min endstops
G1 Z2.0 F3000 ; lift nozzle a bit
G92 E0 ; Reset Extruder
G1 X10.1 Y20 Z0.28 F5000.0 ; Move to start position
G1 X10.1 Y200.0 Z0.28 F1500.0 E15 ; Draw the first line
G1 X10.4 Y200.0 Z0.28 F5000.0 ; Move to side a little
G1 X10.4 Y20 Z0.28 F1500.0 E30 ; Draw the second line
G92 E0 ; zero the extruded length again
G1 E-2 F500 ; Retract a little
M117
G21 ; set units to millimeters
G90 ; use absolute coordinates
M82 ; use absolute distances for extrusion
G92 E0
M107
End G-code:
M104 S0 ; Extruder off
M140 S0 ; Heatbed off
M107 ; Fan off
G91 ; relative positioning
G1 E-5 F3000
G1 Z+0.3 F3000 ; lift print head
G28 X0 F3000
M84; disable stepper motors
11# Finalmente, ajuste la configuración oficial de la impresora según el tipo de filamento mientras los copia de PrusaSlicer a Cura.
Paso 1.1: Montaje de la carcasa y realización de conexiones y ajustes
// Connections
// Arduino Nano :
// SH1106 OLED Display (128×64)
// D11 ————————— SDA
// D13 ————————— SCK
// D8 ————————— RST
// D9 ————————— DC
// D10 ————————— CS
// Control Button (A)
// A0 ————————— +
// Control Button (B)
// A1 ————————— +
// Control Button (C)
// A2 ————————— +
// 5mm Common Anode RGB LED
// D3 ————————— R
// D5 ————————— G
// D6 ————————— B
Dado que SenseCAP A1101 no admite la captura de imágenes con diferentes etiquetas, decidí construir un control remoto simple con Arduino Nano para capturar imágenes fácilmente. Luego, empleé LattePanda 3 Delta para programar SenseCAP A1101 para capturar imágenes de acuerdo con las etiquetas transferidas por el control remoto a través de la comunicación en serie.
Para poder transferir comandos a SenseCAP A1101 a través de comunicación serial, conecté Arduino Nano directamente a LattePanda 3 Delta a través de un cable USB. Utilicé una pantalla OLED SH1106 para mostrar las operaciones en curso y visualizar las clases (niveles) de contaminación de fertilizante seleccionadas. Luego, agregué tres botones de control para transferir los comandos del usuario a LattePanda 3 Delta a través de la comunicación en serie. Además, agregué un LED RGB para informar al usuario sobre el estado del dispositivo, lo que indica el éxito de la comunicación en serie.
Después de imprimir todas las partes (modelos), fijé el control remoto a la sección separada de la caja principal con una pistola de pegamento caliente. También utilicé el kit de tornillos del SenseCAP A1101 para sujetar firmemente su soporte a los orificios para tornillos en la parte superior de la carcasa principal.
Coloqué LattePanda 3 Delta en la carcasa principal y adjunté SenseCAP A1101 a su soporte. Luego, adjunté la cubierta superior diagonal a la caja principal a través de sus juntas de encaje a presión.
Finalmente, inserté la cubierta frontal deslizante a través de las abolladuras en la carcasa principal.
Como se mencionó anteriormente, la cubierta superior diagonal se puede utilizar para ocultar el control remoto cuando se ejecuta el modelo de detección de objetos en lugar de recopilar datos.
Paso 1.2: Creación de un LattePanda Deck para mostrar la transmisión de video
Dado que decidí programar SenseCAP A1101 con LattePanda 3 Delta para capturar imágenes según las etiquetas transferidas por el control remoto a través de la comunicación en serie, decidí diseñar un LattePanda Deck único y compacto para mostrar el flujo de video en tiempo real generado por SenseCAP A1101, que no solo es compatible con LattePanda, sino también con cualquier computadora de placa única compatible con HDMI.
Decidí emplear el monitor IPS de alta resolución de 8.8″ (1920*480) de Elecrow como pantalla de mi LattePanda Deck. Gracias a su placa convertidora, este monitor puede alimentarse a través de un puerto USB y funciona sin instalar ningún controlador. Por lo tanto, es es un monitor compacto plug-and-play para LattePanda 3 Delta, que proporciona alta resolución y una frecuencia de actualización de hasta 60 Hz.
Debido al hecho de que quería construir una plataforma resistente y fácil de usar, diseñé una carcasa de dos partes que cubría el marco de la pantalla y proporcionaba una ranura para la placa convertidora. Para evitar la sobreexposición al polvo y proporcionar espacio para la gestión de cables, agregué una cubierta posterior montable adornada con el logotipo de la marca.
Diseñé la carcasa de dos partes y su tapa trasera montable en Autodesk Fusion 360. Puede descargar sus archivos STL a continuación.
Luego, corté todos los modelos 3D (archivos STL) en Ultimaker Cura.
Después de imprimir todas las piezas de la plataforma (modelos) con mi impresora 3D Anycubic Kobra 2, uní la carcasa de dos piezas con la pistola de pegamento caliente.
Luego, fijé el monitor IPS de Elecrow a la carcasa que cubre el marco de la pantalla e inserté la placa convertidora en su ranura.
Después de conectar los cables necesarios a la placa del convertidor, fijé la cubierta trasera montable con tornillos M3.
Después de conectar la placa convertidora a LattePanda 3 Delta a través de sus puertos USB y HDMI, LattePanda reconoce el monitor IPS automáticamente.
Paso 2: crear una cuenta para utilizar la API de WhatsApp de Twilio
Dado que decidí informar al usuario sobre los resultados de la detección del modelo a través de WhatsApp a través de la red LoRaWAN, necesitaba utilizar la API de WhatsApp de Twilio. Twilio brinda al usuario una forma simple y confiable de comunicarse con un teléfono verificado por Twilio a través de WhatsApp a través de su API de WhatsApp para cuentas de prueba. Además, Twilio proporciona bibliotecas auxiliares oficiales para diferentes lenguajes de programación, incluido Python.
#1 En primer lugar, regístrese en Twilio y cree una nueva cuenta de prueba gratuita (proyecto).
#2 Luego, verifique un número de teléfono para la cuenta (proyecto) y establezca la configuración de la cuenta para WhatsApp en Python.
#3 Vaya a Twilio Sandbox para WhatsApp y verifique su dispositivo enviando el código proporcionado por WhatsApp, que activa una sesión de WhatsApp.
#4 Después de verificar su dispositivo, descargue la biblioteca auxiliar de Twilio Python o instálela directamente en Thonny. Luego, vaya a Cuenta ➡ Claves y tokens API para obtener el SID de la cuenta y el token de autenticación en Credenciales en vivo para comunicarse con el teléfono verificado a través de WhatsApp.
Paso 3: Producir fertilizantes orgánicos a partir de estiércol de codorniz en diferentes etapas de descomposición
Como se mencionó anteriormente, utilizar estiércol compostado como fertilizante orgánico puede afectar la acidificación, la integridad y la estructura del suelo según las etapas de descomposición del estiércol (fresco, activo, maduro y viejo). Dado que necesitaba un entorno controlado que manifestara una estructura e integridad del suelo variables para construir un modelo de detección de objetos válido para detectar el uso excesivo de fertilizantes químicos, decidí producir mis fertilizantes orgánicos mediante el compostaje de estiércol.
Afortunadamente, estoy criando codornices para la producción de huevos en mi balcón y tengo experiencia en el compostaje de estiércol de codorniz como fertilizante orgánico. Para examinar la correlación entre la contaminación por fertilizantes químicos (sintéticos) y las diferencias en la integridad del suelo debido a los fertilizantes orgánicos aplicados, comencé a compostar estiércol de codorniz y recolecté el estiércol en diferentes etapas de descomposición:
- Fresco (1 mes)
- Activo (3 meses)
- Viejo (6 meses)
Después de producir fertilizantes orgánicos a partir de estiércol en diferentes etapas de descomposición, los apliqué al suelo en tres macetas separadas.
Paso 3.1: Adición de fertilizantes químicos y siembra de plántulas de tomate
Después de agregar fertilizantes orgánicos a las macetas, aré los suelos extraídos con fertilizantes orgánicos y los dejé reposar por un tiempo.
Luego, agregué fertilizantes químicos (sintéticos) a cada maceta en la misma cantidad para examinar el uso excesivo de fertilizantes químicos dependiendo de la integridad y estructura del suelo alterada por los fertilizantes orgánicos. Apliqué algunos de los fertilizantes químicos solubles en agua más comunes:
- Nitrato de calcio
- Sulfato de magnesio
- Sulfato de amonio
- fosfato de amonio
Para demostrar los efectos perjudiciales de la contaminación por fertilizantes químicos en el medio ambiente dependiendo de la integridad del suelo alterada por los fertilizantes orgánicos, sembré diferentes tipos de plántulas de tomate en cada maceta.
Como se demuestra a continuación, la contaminación con fertilizantes mató algunas plántulas de tomate dependiendo de los niveles de contaminación basados en la integridad del suelo y la estructura alterada por la etapa de descomposición del fertilizante orgánico aplicado (estiércol):
- Enriquecido
- Inseguro
- Tóxico
Paso 4: utilizar Arduino Nano como control remoto para enviar comandos a través de la comunicación en serie
Como se explicó anteriormente, SenseCAP A1101 no es compatible con la captura de imágenes y el guardado con diferentes etiquetas listas para usar. Por lo tanto, decidí construir un control remoto simple con Arduino Nano para transferir comandos (etiquetas) a SenseCAP A1101 a través de comunicación en serie, ambos conectados a LattePanda 3 Delta.
Puede descargar el archivo AIoT_Fertilizer_Contamination_Detector_remote_control.ino para probar e inspeccionar el código para transferir comandos a SenseCAP A1101 a través de la comunicación en serie.
#1 En primer lugar, descargue las bibliotecas necesarias para utilizar la pantalla OLED SH1106 con Arduino Nano:
Adafruta_SH1106 | Descargar
Biblioteca Adafruit-GFX | Descargar
⭐ Incluir las librerías requeridas.
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
⭐ Defina la configuración de la pantalla OLED SH1106 (128×64).
⭐ Definir gráficos monocromáticos.
#define OLED_MOSI 11 // MOSI (SDA)
#define OLED_CLK 13 // SCK
#define OLED_DC 9
#define OLED_CS 10
#define OLED_RESET 8
Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
⭐ Defina los nombres de la clase de contaminación del fertilizante (etiqueta) y los códigos de color.
String classes[] = {“Enriched”, “Unsafe”, “Toxic”};
int color_codes[3][3] = {{0,255,0}, {255,255,0}, {255,0,0}};
⭐ Inicialice el puerto serie predeterminado (Serial) para comunicarse con LattePanda 3 Delta.
Serial.begin(115200);
⭐ Inicialice la pantalla OLED SH1106.
display.begin(SH1106_SWITCHCAPVCC);
display.display();
delay(1000);
⭐ En la función home_screen , muestra la interfaz del menú en la pantalla OLED SH1106, demostrando clases (etiquetas).
void home_screen(){
display.clearDisplay();
display.drawBitmap((128 – 40), 20, _home, 40, 40, WHITE);
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(10,5);
display.println(” Select Label: “);
display.setTextColor(WHITE);
display.setCursor(10,25);
display.println(“A) Enriched”);
display.setCursor(10,40);
display.println(“B) Unsafe”);
display.setCursor(10,55);
display.println(“C) Toxic”);
display.display();
delay(100);
}
⭐ En la función data_screen , muestre la clase de contaminación de fertilizante seleccionada con su ícono único en la pantalla OLED SH1106.
⭐ Luego, ajusta el LED RGB al código de color de la clase seleccionada.
void data_screen(int i){
display.clearDisplay();
if(i==0) display.drawBitmap((128 – 40) / 2, 0, enriched, 40, 40, WHITE);
if(i==1) display.drawBitmap((128 – 40) / 2, 0, unsafe, 40, 40, WHITE);
if(i==2) display.drawBitmap((128 – 40) / 2, 0, toxic, 40, 40, WHITE);
// Print:
int str_x = classes[i].length() * 11;
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor((128 – str_x) / 2, 48);
display.println(classes[i]);
display.display();
adjustColor(color_codes[i][0], color_codes[i][1], color_codes[i][2]);
delay(4000);
adjustColor(255,0,255);
}
⭐ Si se presiona uno de los botones de control (A, B o C), transmite la clase de contaminación del fertilizante seleccionada (etiqueta) a LattePanda 3 Delta a través de la comunicación en serie.
if(!digitalRead(button_A)){ Serial.println(“Label: Enriched”); data_screen(0); delay(2000); }
if(!digitalRead(button_B)){ Serial.println(“Label: Unsafe”); data_screen(1); delay(2000); }
if(!digitalRead(button_C)){ Serial.println(“Label: Toxic”); data_screen(2); delay(2000); }
Después de cargar y ejecutar el código para transferir comandos a LattePanda 3 Delta a través de la comunicación en serie:
🌱🪴📲 Arduino Nano imprime notificaciones en el monitor serie para la depuración.
Paso 4.1: Visualización de imágenes en la pantalla OLED SH1106
Para mostrar imágenes (en blanco y negro) en la pantalla OLED SH1106 con éxito, necesitaba crear mapas de bits monocromáticos a partir de archivos PNG o JPG y convertir esos mapas de bits en matrices de datos.
#1 En primer lugar, descargue el Asistente LCD.
#2 Luego, cargue un mapa de bits monocromático y seleccione Vertical u Horizontal según el tipo de pantalla.
#3 Convierta la imagen (mapa de bits) y guarde la salida (matriz de datos).
#4 Finalmente, agregue la matriz de datos al código e imprímala en la pantalla.
static const unsigned char PROGMEM toxic [] = {
0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x06, 0x00, 0x60, 0x00, 0x00,
0x0C, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x00, 0x30,
0x00, 0x0C, 0x00, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x70, 0x00,
0x0E, 0x00, 0x00, 0x70, 0x7E, 0x0E, 0x00, 0x00, 0x71, 0xFF, 0x8E, 0x00, 0x00, 0x73, 0xFF, 0xCE,
0x00, 0x00, 0x7B, 0x81, 0xDE, 0x00, 0x00, 0xFD, 0x00, 0xBF, 0x00, 0x01, 0xFC, 0x00, 0x3F, 0x80,
0x07, 0xFF, 0x00, 0xFF, 0xE0, 0x0F, 0xFF, 0xC3, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x1E,
0x07, 0xE7, 0xE0, 0x78, 0x18, 0x31, 0xC3, 0x8C, 0x18, 0x30, 0x30, 0xC3, 0x0C, 0x0C, 0x30, 0x30,
0x00, 0x0C, 0x0C, 0x20, 0x30, 0x24, 0x0C, 0x04, 0x60, 0x38, 0x3C, 0x1C, 0x06, 0x40, 0x38, 0x3C,
0x1C, 0x02, 0x40, 0x1C, 0x3C, 0x38, 0x02, 0x40, 0x1C, 0x3C, 0x38, 0x02, 0x40, 0x0F, 0x3C, 0xF0,
0x02, 0x00, 0x07, 0xBD, 0xE0, 0x00, 0x00, 0x03, 0xBD, 0xC0, 0x00, 0x00, 0x01, 0x7E, 0x80, 0x00,
0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x08, 0x01, 0xFF, 0x80, 0x10, 0x04,
0x03, 0xFF, 0xC0, 0x20, 0x03, 0x9F, 0xE7, 0xF9, 0xC0, 0x00, 0xFF, 0x81, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
…
display.clearDisplay();
display.drawBitmap((128 – 40) / 2, 0, toxic, 40, 40, WHITE);
display.display();
Paso 5.0: Configuración de SenseCAP A1101 en LattePanda 3 Delta
Antes de continuar con los siguientes pasos, necesitaba configurar SenseCAP A1101 para programarlo con LattePanda 3 Delta en Python.
Aunque Seeed Studio proporciona firmware oficial (UF2) para capturar imágenes en Python, necesitaba actualizar BootLoader a la última versión. Si la versión de BootLoader de su dispositivo es superior a 2.0.0, no necesita actualizar BootLoader.
#1 En primer lugar, conecte SenseCAP A1101 a LattePanda 3 Delta a través de un cable USB tipo C.
#2 Luego, haga doble clic en el botón de inicio en SenseCAP A1101 para ingresar al modo de inicio y abrir la unidad de almacenamiento.
#3 Después de acceder a la unidad de almacenamiento, abra el archivo INFO_UF2.txt y verifique la versión de BootLoader.
#4 Si la versión de BootLoader es anterior a la 2.0.0, actualícela con la última versión.
#5 Descargue la última versión de BootLoader:
tinyuf2-sensecap_vision_ai_x.xxbin
#6 Este firmware controla el chip BL702 que construye la conexión entre la computadora y el chip Himax.
#7 Después de descargar la última versión de BootLoader, descargue el software BLDevCube.exe, seleccione BL702/704/706 y luego haga clic en Finalizar.
#8 Haga clic en Ver , elija MCU e ingrese la ruta del firmware de BootLoader en el archivo de imagen .
#9 Seleccione el puerto COM de SenseCAP A1101. Si BLDevCube no reconoce el puerto, conecte SenseCAP A1101 a LattePanda 3 Delta nuevamente mientras mantiene presionado el botón de inicio.
#10 Luego, haga clic en Abrir UART y configure Borrar chip en Verdadero .
#11 Finalmente, haga clic en Crear y programar y espere hasta que se actualice BootLoader.
#12 Después de actualizar BootLoader, descargue el firmware oficial (UF2) para capturar imágenes en Python.
sensecap_ai_capture_firmware_vxx-xx.uf2
#13 Luego, abra la unidad de almacenamiento y copie el firmware oficial (UF2) en la unidad.
#14 Tan pronto como el archivo uf2 se cargue en la unidad de almacenamiento, debería desaparecer.
#15 Finalmente, instale los módulos requeridos en Thonny.
pip3 instalar libusb1
pip3 instalar opencv-python
pip3 instalar numpy
Paso 5: captura de imágenes del suelo obtenidas con fertilizantes con SenseCAP A1101 y comunicación con Arduino Nano a través de comunicación en serie
Después de configurar SenseCAP A1101 e instalar las bibliotecas requeridas, programé SenseCAP A1101 a través de LattePanda 3 Delta para obtener los comandos transferidos por Arduino Nano a través de comunicación en serie y capturar imágenes de suelos con fertilizantes. Como se explicó en los pasos anteriores, SenseCAP A1101 no brinda la opción de capturar imágenes con diferentes etiquetas listas para usar.
Dado que necesitaba asignar niveles de contaminación de fertilizantes como etiquetas para cada imagen mientras capturaba imágenes de suelos extraídos con fertilizantes con integridad alterada del suelo para crear un conjunto de datos válido para mi modelo de detección de objetos, utilicé tres botones de control conectados a Arduino Nano para elegir entre clases y transferir comandos a través de comunicación serial. Después de seleccionar una clase de contaminación de fertilizante presionando un botón de control, Arduino Nano transmite la clase seleccionada a LattePanda 3 Delta a través de comunicación en serie.
Botón de control (A) ➡ Enriquecido
Botón de control (B) ➡ Inseguro
Botón de control (C) ➡ Tóxico
Puede descargar el archivo A1101_data_img_collection.py para probar e inspeccionar el código para obtener comandos a través de la comunicación en serie y capturar imágenes con SenseCAP A1101.
Para descifrar el búfer de imagen generado por SenseCAP A1101, modifiqué estas funciones proporcionadas por Seeed Studio.
Primero, creé una clase llamada A1101_data_img_collection para agrupar las siguientes funciones bajo una estructura específica.
⭐ Incluir los módulos requeridos.
import cv2
import serial
from threading import Thread
from time import sleep
import os
from PIL import Image
from io import BytesIO
import usb1
import numpy as np
import datetime
⭐ En la función __init__ :
⭐ Defina la configuración requerida para obtener paquetes de datos generados desde SenseCAP A1101.
⭐ Obtenga el contexto del dispositivo USB conectado.
⭐ Inicialice la comunicación serial con Arduino Nano para obtener los comandos transferidos.
⭐ Inicialice y pruebe la conexión USB SenseCAP A1101.
class A1101_data_img_collection():
def __init__(self):
# Define the required settings to obtain information from SenseCAP A1101 LoRaWAN Vision AI Sensor.
self.WEBUSB_JPEG = (0x2B2D2B2D)
self.WEBUSB_TEXT = 0x0F100E12
self.VendorId = 0x2886
self.ProductId = [0x8060, 0x8061]
self.img_buff = bytearray()
self.buff_size = 0
self.time_out = 1000
# Get the connected USB device context.
self.context = usb1.USBContext()
# Initialize serial communication with Arduino Nano to obtain the given commands.
self.arduino_nano = serial.Serial(“COM7”, 115200, timeout=2000)
# Initialize and test SenseCAP A1101 connection.
self.get_rlease_device(False)
self.disconnect()
⭐ En la función read_data :
⭐ Si se puede acceder a SenseCAP A1101, obtenga los puntos finales de datos y todos los objetos de datos transferidos.
⭐ Compruebe si hay algún objeto de datos
enviado en el paquete de datos recibido.
def read_data(self):
# If SenseCAP A1101 is accessible:
with self.handle.claimInterface(2):
# Get the data endpoints.
self.handle.setInterfaceAltSetting(2, 0)
self.handle.controlRead(0x01 << 5, request=0x22, value=0x01, index=2, length=2048, timeout=self.time_out)
# Get all transferred data objects.
transfer_list = []
for _ in range(1):
transfer = self.handle.getTransfer()
transfer.setBulk(usb1.ENDPOINT_IN | 2, 2048, callback=self.processReceivedData, timeout=self.time_out)
transfer.submit()
transfer_list.append(transfer)
# Check for any submitted data object in the received data packet.
while any(x.isSubmitted() for x in transfer_list):
self.context.handleEvents()
⭐ En la función processReceivedData :
⭐ Si SenseCAP A1101 genera un paquete de datos con éxito, procese el paquete de datos recibido.
⭐ Descifrar el búfer de la imagen capturada del paquete de datos procesado.
⭐ Vuelva a enviar el paquete de datos después del procesamiento para evitar errores.
def processReceivedData(self, transfer):
# If SenseCAP A1101 generates a data packet successfully, process the received information.
if transfer.getStatus() != usb1.TRANSFER_COMPLETED:
# transfer.close()
return
# Extract the captured image from the processed data packet.
data = transfer.getBuffer()[:transfer.getActualLength()]
self.convert_and_show_img(data)
# Resubmit the data packet after processing to avoid errors.
transfer.submit()
⭐ En la función convert_and_show_img :
⭐ Convierta el paquete de datos recibido en un búfer de imagen.
⭐ Si el paquete de datos recibido se convierte en un búfer de imagen con éxito, muestre la imagen generada en la pantalla para crear una transmisión de video en tiempo real.
⭐ Detenga la transmisión de video cuando se le solicite.
⭐ Almacene el último búfer de imagen (fotograma) capturado por SenseCAP A1101.
def convert_and_show_img(self, data: bytearray):
# Convert the received data packet.
if (len(data) == 8) and (int.from_bytes(bytes(data[:4]), ‘big’) == self.WEBUSB_JPEG):
self.buff_size = int.from_bytes(bytes(data[4:]), ‘big’)
self.img_buff = bytearray()
elif (len(data) == 8) and (int.from_bytes(bytes(data[:4]), ‘big’) == self.WEBUSB_TEXT):
self.buff_size = int.from_bytes(bytes(data[4:]), ‘big’)
self.img_buff = bytearray()
else:
self.img_buff = self.img_buff + data
# If the received data packet is converted to an image buffer successfully, display the generated image on the screen.
if self.buff_size == len(self.img_buff):
try:
img = Image.open(BytesIO(self.img_buff))
img = np.array(img)
cv2.imshow(‘A1101_data_img_collection’, cv2.cvtColor(img,cv2.COLOR_RGB2BGR))
# Stop the video stream if requested.
if cv2.waitKey(1) != -1:
cv2.destroyAllWindows()
print(“\nCamera Feed Stopped!”)
# Store the latest frame captured by SenseCAP A1101.
self.latest_frame = img
except:
self.img_buff = bytearray()
return
⭐ En la función de conexión , conéctese a SenseCAP A1101 si se detecta correctamente.
def connect(self):
# Connect to SenseCAP A1101.
self.handle = self.get_rlease_device(True)
if self.handle is None:
print(‘\nSenseCAP A1101 not detected!’)
return False
with self.handle.claimInterface(2):
self.handle.setInterfaceAltSetting(2, 0)
self.handle.controlRead(0x01 << 5, request=0x22, value=0x01, index=2, length=2048, timeout=self.time_out)
print(‘\nSenseCAP A1101 detected successfully!’)
return True
⭐ En la función de desconexión , restablece la conexión USB entre SenseCAP A1101 y LattePanda 3 Delta.
def disconnect(self):
# Reset the SenseCAP A1101 connection.
try:
print(‘Resetting the device connection… ‘)
with usb1.USBContext() as context:
handle = context.getByVendorIDAndProductID(self.VendorId, self.d_ProductId, skip_on_error=False).open()
handle.controlRead(0x01 << 5, request=0x22, value=0x00, index=2, length=2048, timeout=self.time_out)
handle.close()
print(‘Device connection has been reset successfully!’)
return True
except:
return False
⭐ En la función get_rlease_device :
⭐ Establezca la conexión USB entre SenseCAP A1101 y LattePanda 3 Delta.
⭐ Recupere la información del dispositivo y verifique si hay un dispositivo conectado correctamente.
⭐ Abra o cierre la transmisión de datos SenseCAP A1101.
def get_rlease_device(self, get=True):
# Establish the SenseCAP A1101 connection.
print(‘*’ * 50)
print(‘Establishing connection…’)
# Get the device information.
for device in self.context.getDeviceIterator(skip_on_error=True):
product_id = device.getProductID()
vendor_id = device.getVendorID()
device_addr = device.getDeviceAddress()
bus = ‘->’.join(str(x) for x in [‘Bus %03i’ % (device.getBusNumber(),)] + device.getPortNumberList())
# Check if there is a connected device.
if(vendor_id == self.VendorId) and (product_id in self.ProductId):
self.d_ProductId = product_id
print(‘\r’ + f’\033[4;31mID {vendor_id:04x}:{product_id:04x} {bus} Device {device_addr} \033[0m’, end=”)
# Turn on or off SenseCAP A1101.
if get:
return device.open()
else:
device.close()
print(‘\r’ + f’\033[4;31mID {vendor_id:04x}:{product_id:04x} {bus} Device {device_addr} CLOSED\033[0m’, flush=True)
⭐ En la función get_transferred_data_packets , obtenga los comandos transferidos desde Arduino Nano a través de la comunicación en serie, incluidas las clases de contaminación de fertilizantes (etiquetas).
def get_transferred_data_packets(self):
# Obtain the transferred commands from Arduino Nano via serial communication, including fertilizer hazard classes (labels).
if self.arduino_nano.in_waiting > 0:
command = self.arduino_nano.readline().decode(“utf-8”, “ignore”).rstrip()
if(command.find(“Enriched”) >= 0):
print(“\nCapturing an image! Label: Enriched”)
self.save_img_sample(“Enriched”)
if(command.find(“Unsafe”) >= 0):
print(“\nCapturing an image! Label: Unsafe”)
self.save_img_sample(“Unsafe”)
if(command.find(“Toxic”) >= 0):
print(“\nCapturing an image! Label: Toxic”)
self.save_img_sample(“Toxic”)
sleep(1)
⭐ En la función save_img_sample , según el nombre de clase obtenido, guarde el último búfer de imagen almacenada (fotograma) capturado por SenseCAP A1101 en la carpeta de muestras agregando la fecha y hora actuales a su nombre de archivo:
Enriquecido_IMG_20230530_165521.jpg
def save_img_sample(self, _class):
date = datetime.datetime.now().strftime(“%Y%m%d_%H%M%S”)
filename = ‘./samples/{}_IMG_{}.jpg’.format(_class, date)
# If requested, save the recently captured image (latest frame) as a sample.
cv2.imwrite(filename, self.latest_frame)
print(“\nSample Saved Successfully: ” + filename)
#1 Dado que mostrar un flujo de video en tiempo real generado por SenseCAP A1101 y comunicarse con Arduino Nano para obtener comandos a través de la comunicación en serie no se puede ejecutar en un solo bucle, utilicé la clase Python Thread para ejecutar procesos (funciones) simultáneos.
soil = A1101_data_img_collection()
# Define and initialize threads.
def A1101_camera_feed():
soil.collect_data()
def activate_received_commands():
while True:
soil.get_transferred_data_packets()
Thread(target=A1101_camera_feed).start()
Thread(target=activate_received_commands).start()
Paso 5.1: Guardar las imágenes capturadas como muestras en LattePanda 3 Delta
Después de cargar y ejecutar el código para obtener comandos a través de la comunicación en serie y capturar imágenes con SenseCAP A1101 en LattePanda 3 Delta:
🌱🪴📲 Si el dispositivo funciona correctamente, el control remoto muestra la interfaz del menú en la pantalla OLED SH1106 y cambia el LED RGB a magenta.
- A) Enriquecido
- B) Inseguro
- C) Tóxico
🌱🪴📲 Si se presiona el botón de control (A), Arduino Nano agrega Enriquecido como la clase de contaminación de fertilizante seleccionada al comando, transfiere el comando modificado a LattePanda 3 Delta a través de la comunicación en serie, muestra la clase de contaminación de fertilizante seleccionada con su monocromático único en la pantalla OLED SH1106 y enciende el LED RGB en verde.
🌱🪴📲 Si se presiona el botón de control (B), Arduino Nano agrega Uns afe como la clase de contaminación de fertilizante seleccionada al comando, transfiere el comando modificado a LattePanda 3 Delta a través de comunicación en serie, muestra la clase de contaminación de fertilizante seleccionada con su monocromático único en la pantalla OLED SH1106 y enciende el LED RGB en amarillo.
🌱🪴📲 Si se presiona el botón de control (C), Arduino Nano agrega Tox ic como la clase de contaminación de fertilizantes seleccionada al comando, transfiere el comando modificado a LattePanda 3 Delta a través de comunicación en serie, muestra la clase de contaminación de fertilizantes seleccionada con su monocromático único en la pantalla OLED SH1106 y enciende el LED RGB en rojo.
🌱🪴📲 Cuando LattePanda 3 Delta recibe un comando transferido por Arduino Nano a través de la comunicación en serie, incluida la clase de contaminación de fertilizante seleccionada, guarda el último búfer de imagen almacenado generado por SenseCAP A1101 en la carpeta de muestras según el nombre de clase seleccionado al agregar la fecha y hora actual a su nombre de archivo:
Video 4
🌱🪴📲 Además, LattePanda 3 Delta muestra la transmisión de video en tiempo real generada por SenseCAP A1101 mientras captura imágenes e imprime notificaciones con las rutas de archivo de imagen guardadas en el shell para la depuración.
Después de capturar imágenes de suelos sometidos a aplicación de fertilizantes en tres macetas separadas durante casi dos meses, cuya integridad y estructura del suelo se alteraron en relación con la etapa de descomposición del fertilizante orgánico aplicado (estiércol), logré construir mi conjunto de datos con eminente validez y veracidad.
Continuaremos en el próximo número de TECNOLOGIA HUMANIZADA
Sé el primero en comentar