lunes, 27 de febrero de 2017

DoITCar Kit - Programación con Arduino

En este artículo vamos a empezar a programar el módulo ESP8266 del DoIT CarKit con el IDE de Arduino. La base del control, además del propio módulo, es el NodeMcu Motor Shield.
Este shield nos permite montar el NodeMCU V2 en la plataforma e incluye un chip L293D que se utiliza para el control de un par de motores de corriente continua CC.
Este módulo se compone de diferentes elementos:

Según las especificaciones técnicas, la conexión del puerto con los moteres es la siguiente:

ESP8266MotorFunción
D1APWMA
D2BPWMB
D3ADA (direction of motor A)
D4BDB (direction of motor B)

Además cuenta con una gran variedad de pines como VIN, 3.3V, DIO, AIO, SDIO. UART, etc. para conectar otros elementos al módulo ESP8266.

La tensión que debemos alimentar el módulo motor shield se encuentra entre 4,5 y 36 voltios para los motores (motor power) mientras que el módulo admite tensiones entre 4,5 y 9 voltios para alimentar el módulo ESP8266 (ESP power). Con el puente shorcut podemos hacer que la alimentación del módulo motor shield y el ESP8266 sea la misma o que se alimenten de forma diferenciada. En nuestro caso, como solo disponemos de una pila de baterías, la alimentación será la misma.

Motores de Corriente Continua

El kit cuenta con dos motores de corriente continua. La velocidad de giro (revoluciones por minuto o Rpm) de estos motores varía según la tensión que se le aplique. En nuestro primer ejemplo la velocidad siempre será la misma (valor máximo).

Para variar el sentido de la rotación deberíamos variar la polaridad de la tensión aplicada a los motores pero nuestro módulo ESP8266 no es capaz por si solo de hacerlo. Para ello el módulo motor shield cuenta con el chip L293D que es un puente en H (H-bridge) cuyo funcionamiento básico se xplica en la siguiente figura:


Cuando usamos los interruptores en la posición de la imagen izquierda el motor gira en un sentido que llamaremos directo. Pero si los colocamos en la posición de la derecha girará en sentido contrario, porque hemos invertido la polaridad de la tensión en las entradas del motor, y por tanto el sentido de giro, sin necesidad de invertir la polaridad de la tensión. Este es básicamente el módo de funcionamiento del chip L293D pero, en vez de utilizar interruptores, utiliza transistores para controlar el sentido de giro de los motores.

En suma, el motor shield es ideal para construir robots autónomos con pequeños motores y sin peso y sobre todo como elemento de aprendizaje antes de invertir una pasta gansa en otras opciones mas sofisticadas.

Programando el kit con Arduino

En este primer ejemplo voy a configurar el módulo ESP como cliente de mi red WiFi, le asignaré una dirección IP fija y levantaré un servidor web que enviará una página con los controles necesarios para mover el Kit en todos los sentidos.

Mi red es una clase C con un rango de 192.168.1.0/24. Mi router es la primera IP disponible que es la 192.168.1.1 y le asignaré al módulo ESP la IP 192.168.1.5 que está libre. Con un navegador web. accederé a dicha dirección y el servidor enviará la página con los controles. Cada vez que pulse uno de los botones el módulo recibe un dato (valor) y ejecuta un movimiento dependiendo del valor recibido.

El código completo es el siguiente:

// Librerías
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
// Red WiFi
const char* ssid = "WLAN_E17C";
const char* password = "ced0ccb58c84e525e35f";
// configuramos el servidor web que escuchará el puerto 80
ESP8266WebServer server(80);
// Página web (formulario)

// Configuramos botones de envío (type=submit) y con el atributo
// value indicamos el mensaje que queremos enviar 
// Cuando pulsamos por ejemplo el botón stop realizamos la siguiente
// solicitud: http://192.168.1.5/?dir=5
const char *form = "<center><form action='/'>"
"<button name='dir' type='submit' value='2'>Forward</button><br>"
"<button name='dir' type='submit' value='3'>Left</button>&nbsp;"
"<button name='dir' type='submit' value='4'>Right</button><br>"
"<button name='dir' type='submit' value='1'>Reverse
</button><p>"
"<button name='dir' type='submit' value='5'>Stop</button>"
"</form></center>";

 
void stop(void){
    analogWrite(D1, 0);
    analogWrite(D2, 0);
}
void forward(void){
    analogWrite(D1, 1023);
    analogWrite(D2, 1023);
    digitalWrite(D3, HIGH);
    digitalWrite(D4, HIGH);
}
void backward(void){
    analogWrite(D1, 1023);
    analogWrite(D2, 1023);
    digitalWrite(D3, LOW);
    digitalWrite(D4, LOW);
}
void left(void){
    analogWrite(D1, 1023);
    analogWrite(D2, 1023);
    digitalWrite(D3, LOW);
    digitalWrite(D4, HIGH);
}
void right(void){
    analogWrite(D1, 1023);
    analogWrite(D2, 1023);
    digitalWrite(D3, HIGH);
    digitalWrite(D4, LOW);
}
void handle_form(){
    // Comprueba si el argumento es dir
    if (server.arg("dir")){
        // Obtiene el valor
        int direction = server.arg("dir").toInt();
        // Elige la dirección
        switch (direction){
            case 1:
                left();
                break;
            case 2:
                right();
                break;
            case 3:
                backward();
                break;
            case 4:
                forward();
                break;
            case 5:
                stop();
                break;
        }
        delay(300);
    }
    // en todos los casos envía el formulario nuevamente.
    server.send(200, "text/html", form);
}
void setup(){
    // Conecta con la red WiFi
    WiFi.begin(ssid, password);
    // IP estática, defalut gateway y máscara
    WiFi.config(IPAddress(192,168,1,5),IPAddress(192,168,1,1), IPAddress(255,255,255,0));
    // Espera por una conexión WiFi
    while (WiFi.status() != WL_CONNECTED){
        delay(200);
    }
    // cuando recibe / envía la página web (formulario)
    server.on("/", handle_form);
    // inicializa el servidor web
    server.begin();

    // Inicializa los Pins
    pinMode(D1, OUTPUT); // PWM motor A
    pinMode(D2, OUTPUT); // PWM motor B
    pinMode(D3, OUTPUT); // Dirección Motor A
    pinMode(D4, OUTPUT); // Dirección Motor B
}
void loop(){
    // escuchamos las conexiones entrantes
    server.handleClient();
}


La interfaz es bastante cutre pero por ahora nos vale:
 

Nota: Si el kit no se mueve según el botón pulsado, modifique el campo value para adaptarlo a las conexiones entre los motores y el módulo motor shield que usted haya realizado.

Fuentes:
ESP8266: NodeMCU Motor Shield Review
User mannual for ESP-12E motor shield
Motores eléctricos
NodeMCU Motor Shield Review
Librería ESP8266WebServer (Arduino IDE)

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.