Inicio » Aula » Robot WiFi NodeMCU – MOTOMAMI

Robot WiFi NodeMCU – MOTOMAMI

En esta entrada voy a explicar como hacer un robot controlado por Wi-Fi con un microcontrolador NodeMcu v2.

Primero mostraré el diseño de componentes y el porqué de estos y más tarde la programación. Las funciones que implementará el robot son:

  1. Control Manual
  2. Sigue líneas
  3. Evitar obstáculos
  4. Salir de Laberintos

DISEÑO

La estructura del robot es de base triciclo, con dos ruedas motrices, controladas por motores de corriente continua, y una tercera rueda loca. Esta base es genérica y se puede encontrar en muchas tiendas online.

Como he dicho antes, el microcontrolador será un NodeMCU v2. Este controlador se programa igual que un Arduino, la diferencia es que tiene un módulo WiFi incluido. Este módulo nos permite la conexión al controlador desde un móvil o un ordenador.

Además, el NodeMCU v2 tiene un shield que se puede usar para el control de motores. Junto a esto, podemos desarrollar el movimiento del robot.


Este shield se puede alimentar con un voltaje entre 4.5-36 V, de esta forma se puede utilizar pilas para alimentarlo y ya tiene un regulador para alimentar el microcontrolador y los motores. En mi caso he optado por un modulo de baterías 18650 ya que son recargables y duran más.


SENSORES

Para el seguimiento de líneas, me basaré en un circuito con fondo blanco y una línea negra a seguir. Por esto, utilizaré un sensor TCRT5000. Este sensor emite una señal infrarroja y mide el valor que rebota del suelo, diferenciando entre un tono negro y blanco.

Para evitar obstáculos y salir de laberintos utilizaré sensores HC-SR04. Estos sensores emiten una señal de ultrasonidos que mide el tiempo que tarde en rebotar con la pared.

Para poder anclarlo al chasis, usaré un diseño 3D.

Este tiempo se relaciona con la distancia con una formula sencilla:

Siendo 340m/s la velocidad del sonido,
340 m/s * 100 cm/m * 1/1000000 s/us = 1/29.41 cm/us //Esto es la distancia que recorre en cm por microsegundos.

Luego, como la señal va a recorrer dos veces la distancia, una para ir y otra para volver, la distancia real será:
d(cm) = tiempo(us)/(29.41*2)

Todo montado se vería de la siguiente forma:


CÓDIGO

Sensores

Empezando por lo mas sencillo, el uso de los sensores. Al tener 3 sensores de ultrasonidos iguales y poder hacer ampliable la cantidad de sensores infrarrojos para mejorar el sigue líneas, he desarrollado un archivo .h y .cpp con clases de sensores, de tal forma que en el archivo principal del proyecto solo creemos objetos de ese tipo, en este caso sensores. De esta forma, cualquiera que necesite usar estos sensores, puede introducir estos archivos en su proyecto y usar las funciones creadas para los sensores.

En la clase del ultrasonidos, hay 2 funciones. Una para crear el objeto pasándole los pines echo trigger; y otra función que devuelve la distancia. Esta función crea un pulso de salida en el pin trigger y espera una respuesta en el pin echo. El tiempo que tarda en recibir la señal es el que se usa para calcular la distancia. Si pasa mas de 5 ms, deja de esperar la señal para no añadir retraso en el tiempo de ejecución del programa. De esta forma, la distancia máxima de medida es 85cm.

Y en la clase del infrarrojo también hay 2 funciones. Una para crear el objeto pasándole el pin analógico y otra que devuelve el valor que lee mediante analogRead(pin);

 Motores

Para el control de los motores se usa el shield con el controlador L293D, de esta forma los pines para los motores ya están fijados. Para controlar estos motores hay que indicar primero la dirección de giro de los motores y luego el valor absoluto de giro. Este valor va entre 0 y 255, pero en mi caso, el motor solo empieza a girar a partir del valor 140, ya que antes no tiene la suficiente fuerza para moverse.

Sigue Líneas

Para esta función autónoma, he implementado un sistema sencillo pero seguro. Los valores que devuelve el sensor infrarrojo con el color negro son bastante altos, alrededor de 1024 que es el máximo, y para el blanco valores bajos, sobre 200. De esta forma, podemos diferenciar fácilmente entre los dos colores. Cuando el sensor mide un valor mayor a 600, que es el valor medio, el color detectado será negro y cuando es menor será blanco. Cuando detecta que es negro, gira la rueda izquierda de la forma más lenta posible y deja la derecha sin mover, y cuando detecta blanco al revés. Así, el robot se mueve lentamente pero de forma fiable.

Además, para hacerlo más completo, cuando el sensor de ultrasonidos de delante detecta un objeto, el robot gira 180º y cambia el sentido de giro, cambiando además la forma en la que giran los motores, así seguirá yendo por fuera del circuito.

Evitar objetos

Esta función es sencilla, al tener 3 sensores, uno delante y uno a cada lado, es fácil saber que decisión tiene que tomar el robot. Si detecta un objeto delante y no tiene nada a la derecha, girará a la derecha. En cambio si tiene un objeto, girará a la izquierda. Si finalmente tuviera objetos a ambos lados, giraría 180º

Laberinto

La función anterior explicada es muy parecida a esta pero cambiando un pequeño detalle, el sensor derecho es el que tiene prioridad. Si no tiene ningún objeto a la derecha, girará. De esta forma sigue siempre la pared derecha, que es la forma más sencilla de salir de un laberinto.

Todas estas tres funciones tienen incluidas funciones predefinidas de movimiento. A base de prueba y error, podemos saber cuanto tarda en girar el robot 90º en un sentido y en otro, de esta forma podemos dejar funciones hechas de antemano para simplificar todo esto, y que los giros que hace al esquivar objetos sean estas funciones ya hechas.

Control Manual

Aquí viene la parte mas compleja, mediante una librería de ESP8266, podemos hacer que el microcontrolador cree su propia red WiFi a la que conectarnos mediante un dispositivo. Esta red WiFi puede incluir una página web que añada el control del robot. En mi caso he creado una web con todo lo necesario, un joystick con el que controlar el movimiento y botones para cambiar de modo, de esta forma:

Para el uso del WiFi, primero creamos un server donde estará la página web. Luego, iniciamos el modo de WiFi, si queremos que se conecte a una red WiFi o si queremos crear una. En mi caso quería poder crear una y así no depender de conexiones externas. Esta red la he llamado MOTOMAMI y así poner este nombre al robot.

 if (0) {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
} else {
WiFi.mode(WIFI_AP);
while (!WiFi.softAP("MOTOMAMI", "carlosgb")) {
delay(100);
}
}

Luego, se crea el server con los datos de la pagina web y se añade los valores de entrada de los botones y el joystick, de esta forma podemos leer que esta pasando en la web:

//Crear server
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "text/html", webpage);
});

//Valores Joystick
server.on("/Manual", HTTP_GET, [] (AsyncWebServerRequest * request) {
modo = ControlManual;
if (request->hasParam(PARAM_INPUT_X)) {
x = request->getParam(PARAM_INPUT_X)->value();
}
else {
x = "No message sent";
}

if (request->hasParam(PARAM_INPUT_Y)) {
y = request->getParam(PARAM_INPUT_Y)->value();
}
else {
y = "No message sent";
}
request->send(200, "text/plain", "OK");
});

//Modo
server.on("/SigLin", HTTP_GET, [] (AsyncWebServerRequest * request) {
modo = Siguelineas;
request->send(200, "text/plain", "OK");
});
server.on("/Lab", HTTP_GET, [] (AsyncWebServerRequest * request) {
modo = Laberinto;
request->send(200, "text/plain", "OK");
});

// Start server
server.begin();

De esta forma se iniciaría el server y se leería constantemente que esta pasando.


Para ver el proyecto entero, dejo para descargar tanto los códigos como los archivos 3D.