Bionic Spider Controller - Teil 2 - AZ-Delivery

En la última entrada del blog, la araña biónica se controló mediante un controlador autoconstruido a través del protocolo ESPNOW.

Esto permite una sencilla conexión de dispositivo a dispositivo sin necesidad de estar conectado a una red.

En este blog, utilizamos el protocolo de Internet UDP para intercambiar paquetes de datos entre los microcontroladores. Para ello, el mando a distancia y la araña deben estar en la misma red.

Sin embargo, esta pequeña limitación también tiene la ventaja de que el alcance con repetidores y puntos de acceso en tu red doméstica suele ser más amplio y completo, lo que significa que incluso se puede establecer una conexión a una distancia mayor que la línea de visión.

 

Hardware

Si ya ha instalado el controlador en el Blog del controlador araña puede omitir la parte siguiente y continuar con el software.

 

Existen dos versiones del joystick: por un lado, el KY-023 . Sin embargo, como esto requeriría de nuevo mucho cableado, recomendamos el PS2 Joystick Shieldque también puede conectarse directamente a un microcontrolador con Uno se puede enchufar.

Como el microcontrolador tiene que comunicarse con el robot, se requiere un microcontrolador con funcionalidad WiFi. Además, se necesitan dos ADC para cada uno de los ejes X e Y, por lo que en este caso debe utilizarse un ESP32.

(El ESP8266 sólo tiene una entrada ADC).

 

Para la realización del proyecto necesitas:

ESP32 NodoMCU D1 R32

PS2 Joystick Shield

(opcional) pila bloque de 9V + Clip para pilas

y por supuesto una montada Kit Robot Araña Biónica

 

Como las entradas analógicas de los dos ejes del joystick están conectadas a GPIO 2 y 4, que a su vez están conectadas al ADC2, no pueden utilizarse simultáneamente con el módulo WLAN. Sin embargo, las conexiones IO 34 e IO35 (ADC1) se encuentran directamente al lado de éstas, por lo que la funcionalidad puede establecerse fácilmente mediante un puente de cables.

Figura 1: Puente de cables entre las conexiones

 

Conecte las conexiones como se muestra arriba.


Como el LED de la placa está conectado a GPIO 2, el pin debe ser eliminado aquí ya que de lo contrario la conexión afectaría al valor de la tensión del eje X.

Lo mismo se aplica al pin D12, ya que interfiere con el proceso de arranque y, por lo tanto, no sería posible arrancar con el escudo conectado. El botón central del joystick está conectado a esta conexión, lo que significa que ya no se puede utilizar. Si aún se quiere implementar, se debe volver a conectar a una conexión libre.

 

Figura 2: Escudo con modificaciones

 

La pantalla puede conectarse simplemente al D1 R32. Asegúrate de que el pequeño interruptor de la esquina izquierda está en la posición 3v3 de lo contrario el ESP32 podría dañarse por el voltaje excesivo de 5V.

 

Software

Si está programando un ESP32/ESP8266 en el IDE Arduino por primera vez, copie las siguientes URLs en el IDE Arduino en: Archivo->Preferencias->Administrador de placas adicionales URLs :  https://dl.espressif.com/dl/package_esp32_index.json

http://arduino.esp8266.com/stable/package_esp8266com_index.json

 

e instalar el paquete ESP32 y ESP8266 en la administración de la placa.

 

Para la comunicación, los paquetes de datos se intercambian mediante UDP. Con este protocolo de comunicación, los paquetes simplemente se envían sin comprobar si se ha recibido el paquete.

Esto hace que el intercambio de datos sea muy rápido, pero también inseguro, ya que no es posible determinar si el destinatario recibe realmente los datos.

 

La biblioteca para la comunicación UDP ya está incluida en los extensos paquetes de placa para el ESP8266 y el ESP32.

 

En el blog de ESPnow, la dirección MAC del microcontrolador era necesaria para la comunicación.
Cuando se comunica a través de UDP, sólo se necesita la dirección IP del receptor. Ésta se asigna automáticamente a través del servidor DHCP del router al conectarse a la red doméstica (WLAN).
La dirección IP puede determinarse a través de la interfaz de usuario de su router, pero también se muestra en el monitor serie al inicio del programa receptor.

 

Código araña biónica

Cargue el siguiente código en el ESP8266 del kit Bionic Spider seleccionando el puerto y la placa correctos en el IDE de Arduino.

 

#include <ESP8266WiFi.h>
#
include <WiFiUdp.h>
#
include "commands.h"

const char* ssid = "Name";
const char* password = "PSWD";
String cmd; //recieved Command

WiFiUDP udp;

void setup() {
  
Serial.begin(115200);
  
Serial.println();

  
WiFi.begin(ssid, password);
  
while (WiFi.status() != WL_CONNECTED) {
    
delay(500);
    
Serial.print(".");
    
if(millis() > 30000) ESP.restart();
  }

  udp.
begin(4210);

  
Serial.println("ESP8266 ready (Reciever)");
  
Serial.print("IP:");
  
Serial.println(WiFi.localIP());


  servo_14.
attach(14, SERVOMIN, SERVOMAX);// Connect the servo to pin 14
  servo_12.
attach(12, SERVOMIN, SERVOMAX);// Connect the servo to pin 12
  servo_13.
attach(13, SERVOMIN, SERVOMAX);// Connect the servo to pin 13
  servo_15.
attach(15, SERVOMIN, SERVOMAX);// Connect the servo to pin 15
  servo_16.
attach(16, SERVOMIN, SERVOMAX);// Connect the servo to pin 16
  servo_5.
attach(5, SERVOMIN, SERVOMAX);// Connect the servo to pin 5
  servo_4.
attach(4, SERVOMIN, SERVOMAX);// Connect the servo to pin 4
  servo_2.
attach(2, SERVOMIN, SERVOMAX);// Connect the servo to pin 2

  Servo_PROGRAM_Zero();
// Reset the servo program to zero
}

void loop() {
  
//Serial.print("IP:");
  
//Serial.println(WiFi.localIP());
  
int pSize = udp.parsePacket();
  
if (pSize) {
    
char buf[20];
    
int len = udp.read(buf, 20);
    buf[len] = 
0;

    cmd = 
String(buf);
    
Serial.println(cmd);
  }

  
if(cmd.length() > 0) {
    
if(cmd.indexOf("CMD_FWD") >= 0) {
      
Serial.println("FWD");
      forward();
    }
    
else if(cmd.indexOf("CMD_BWD") >= 0) {
      
Serial.println("BWD");
      back();
    }
    
else if(cmd.indexOf("CMD_RGT") >= 0) {
      
Serial.println("RGT");
      rightmove();
    }
    
else if(cmd.indexOf("CMD_LFT") >= 0) {
      
Serial.println("LFT");
      leftmove();
    }
    
else if(cmd.indexOf("BTN_A") >= 0) {
      
Serial.println("A");
      dance1();
    }
    
else if(cmd.indexOf("BTN_B") >= 0) {
      
Serial.println("B");
      dance2();
    }
    
else if(cmd.indexOf("BTN_C") >= 0) {
      
Serial.println("C");
      hello();
    }
    
else if(cmd.indexOf("BTN_D") >= 0) {
      
Serial.println("D");
      pushup();
    }
    
else if(cmd.indexOf("BTN_E") >= 0) {
      
Serial.println("D");
      turnright();
    }
    
else if(cmd.indexOf("BTN_F") >= 0) {
      
Serial.println("D");
      turnleft();
    }

    cmd = 
"";
    
// send ready to controller to recieve new commands
    udp.
beginPacket(udp.remoteIP(), udp.remotePort());
    udp.
print("RDY");
    udp.
endPacket();
    
Serial.println("ACK gesendet");
  }
 
}

Explicación:

Las bibliotecas necesarias se integran al principio. El archivo comandos.h con las secuencias de movimientos se puede encontrar junto con el código en la descarga al final de esta sección.

A continuación, se definen los datos de acceso WLAN y se declara una variable para el comando recibido. También se crea el objeto para la biblioteca UDP.

En setup(), el microcontrolador se conecta a la WLAN y se inicializan los servomotores individuales.

En el bucle(), los paquetes de datos entrantes se transfieren del emisor al cmd se guarda. A continuación, se analiza mediante las consultas if y se ejecuta la orden correspondiente. Una vez ejecutado el comando, se envía una confirmación al controlador.

 

Puede descargar el código completo aquí descargar.
Introduzca sus datos de acceso WLAN en el programa en lugar de los marcadores de posición.

 

Después de la carga en el microcontrolador, abra el monitor serie y anote la dirección IP que se muestra.
Si esto no se muestra al principio, puede utilizar las dos líneas al principio en el bucle() para la salida.

 

Controlador de código

 

#include <WiFi.h>
#
include <esp_wifi.h>
#
include <WiFiUdp.h>

#
define X 34
#
define Y 35

#
define A 26
#
define B 25
#
define C 17
#
define D 16
#
define E 27
#
define F 14

const char* ssid = "name";
const char* password = "pswd";
const char* rcvIP = "192.168.178.xxx";


int calibY, calibX;
bool status = true;
long sentTime;
String msg;

WiFiUDP udp;

void setup() {
  
Serial.begin(115200);
  
delay(2000);

  
WiFi.begin(ssid, password);
  
while (WiFi.status() != WL_CONNECTED) {
    
delay(500);
    
Serial.print(".");
    
if(millis() > 7000) ESP.restart();
  }

  
Serial.println("ESP32 ready (Controller)");

  calibX = 
analogRead(X); //calibrating current Position to zero
  calibY = 
analogRead(Y);

  
pinMode(A, INPUT_PULLUP);
  
pinMode(B, INPUT_PULLUP);
  
pinMode(C, INPUT_PULLUP);
  
pinMode(D, INPUT_PULLUP);
  
pinMode(E, INPUT_PULLUP);
  
pinMode(F, INPUT_PULLUP);
}

void loop() {
  
int valX = analogRead(X) - calibX;
  
int valY = analogRead(Y) - calibY;
  
//Serial.println(valX);
  
//Serial.println(valY);

//no acknowledgement recieved after 10 sec. -> set marker to true; reenable sending
  
if((millis() - sentTime) > 10000) {
    status = true;
  }
  
if(status) {
    
//threshold values
    
if(valX < -50 || valY < -50 || valX > 50 || valY > 50) {
      
Serial.println("trig");
      
//choose dominant coordinate
      
if(abs(valX) > abs(valY)) {
        
if(valX < 0) {
          
Serial.println("LEFT");
          msg = 
"CMD_LFT";
        }
        
else {
          
Serial.println("Right");
          msg = 
"CMD_RGT";
        }
      }
      
else {
        
if(valY < 0) {
          
Serial.println("BWD");
          msg = 
"CMD_BWD";
        }
        
else {
          
Serial.println("FWD");
          msg = 
"CMD_FWD";
        }
      }
      status = false; 
//marking sent
      sentTime = 
millis(); //store time for limitation
    }
    
//check buttons
    
else {
      
if(!digitalRead(A)) {
        
Serial.println("A");
        msg = 
"BTN_A";
        status = false; 
//marking sent
        sentTime = 
millis(); //store time for limitation
      }
      
else if(!digitalRead(B)) {
        
Serial.println("B");
        msg = 
"BTN_B";
        status = false; 
//marking sent
        sentTime = 
millis(); //store time for limitation
      }
      
else if(!digitalRead(C)) {
        
Serial.println("C");
        msg = 
"BTN_C";
        status = false; 
//marking sent
        sentTime = 
millis(); //store time for limitation
      }
      
else if(!digitalRead(D)) {
        
Serial.println("D");
        msg = 
"BTN_D";
        status = false; 
//marking sent
        sentTime = 
millis(); //store time for limitation
      }
      
else if(!digitalRead(E)) {
        
Serial.println("E");
        msg = 
"BTN_E";
        status = false; 
//marking sent
        sentTime = 
millis(); //store time for limitation
      }
      
else if(!digitalRead(F)) {
        
Serial.println("F");
        msg = 
"BTN_F";
        status = false; 
//marking sent
        sentTime = 
millis(); //store time for limitation
      }
     
    }
    udp.
beginPacket(rcvIP, 4210);
    udp.
print(msg);
    udp.
endPacket();
    msg = 
"";
  }
 
  
int pSize = udp.parsePacket();
  
if (pSize) {
    
char buf[20];
    
int len = udp.read(buf, 20);
    buf[len] = 
0//termination

    
if (String(buf) == "RDY") {
      status = true;
      
Serial.println("ACK");
     
    }
  }
  
delay(100);
}

Explicación:

En primer lugar, se integran las bibliotecas necesarias, se crean macros para los pines de los distintos botones y se declaran los datos de acceso WLAN y la dirección IP del receptor. A continuación se declaran las variables globales para la calibración de los ejes del joystick, el comando a enviar y para la implementación del mensaje de confirmación.

En setup(), se conecta el microcontrolador a la WLAN, se calibran los ejes del joystick y se definen las entradas digitales.

En el bucle(), la posición del joystick se lee primero como un valor analógico y se guarda en las variables correspondientes.

A continuación, se realiza una comprobación que restablece el estado de la transmisión tras un tiempo de espera de 10 segundos.

El algoritmo de evaluación de la dirección del movimiento comprueba si los valores de los ejes superan un valor límite de 50. Esto es necesario porque tanto los potenciómetros, que se utilizan para leer la posición de los ejes, como los convertidores analógico-digitales (ADC) se mueven mínimamente alrededor del valor cero incluso en la posición cero (lo que se denomina deriva).

Si un eje está por encima del valor umbral, los valores de la magnitud de los dos ejes se comparan entre sí. De este modo, se puede determinar el eje que más se ha desplazado y que, por tanto, es direccional.

Además, las entradas digitales se leen y el comando correspondiente (designación del botón) se guarda en la variable msg cuando se pulsa un botón.

Por último, la orden se envía al robot como un paquete UDP.

Una vez que el receptor ha ejecutado la orden, envía una confirmación al emisor. Si la recibe, la variable estado arriba otra vez verdadero que permite volver a enviar.

 

Puede descargar el programa completo aquí descargar.

Cargue esto con los datos de acceso WLAN correctos y la dirección IP al ESP32 D1 R32 seleccionando el puerto correcto.

 

Conclusión

En esta entrada del blog has aprendido a controlar el robot biónico Spider utilizando el protocolo de comunicación UDP.

Por supuesto, este proyecto sólo sienta las bases para tus propias ampliaciones y modificaciones. Por ejemplo, puedes hacer funcionar un microcontrolador en modo AP para no tener que depender de un router externo.

Así, además del propio protocolo de comunicación ESPnow con UDP, también ha conocido un protocolo muy extendido que se utiliza en muchas aplicaciones en las que el tiempo es un factor crítico.

 

Diviértete reconstruyendo :)

Esp32Esp8266Projekte für anfänger

Deja un comentario

Todos los comentarios son moderados antes de ser publicados