Arduino, Rasperry y algo más

Autor: Juanjo Francia Página 1 de 2

El «Hola mundo» de mi brazo robótico

Conseguido el primer hito de este proyecto. He conseguido que el brazo responda a la acción de cuatro potenciómetros a través de un arduino. No tiene nada especial, ha sido casi un corta y pega de los ejemplos de la librería «servo» de arduino.

El esquema del montaje que he realizado es este:

No tiene ningún misterio. Los servos están controlados por salidas pwm y los potenciómetros son leídos por pines analógicos. He usado la alimentación del arduino por que no van a funcionar nunca dos servos a la vez.

Antes de empezar con el código, un consejo sobre el montaje: aseguraros de que montáis los servos de tal forma que coincida uno de sus topes de giro con los topes físicos del robot. Si se hace mal toca recolocar todo el servo para lo que suele hacer falta desmontar medio robot.

El código que he usado es este:

servo#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

float angulo1=90.0;
float angulo2=90.0;
float angulo3=90.0;
float angulo4=90.0;
float poten1;
float poten2;
float poten3;
float poten4;

void setup() {
    
    servo1.attach(9); // Base
    servo2.attach(10); // Brazo 1
    servo3.attach(11); // Brazo 2
    servo4.attach(12); // Pinza
    set_servo();
}

void loop() {
    poten1 = analogRead(A0); // Base
    poten2 = analogRead(A1); // Brazo 1
    poten3 = analogRead(A2); //Brazo 2
    poten4 = analogRead(A3); // Pinza

    angulo1 = map(poten1, 0, 1023, 0, 180);
    if(angulo1 >= 180){
        angulo1 = 180;
    }else if(angulo1 <= 0){
        angulo1 = 0;
    }

    angulo2 = map(poten2, 0, 1023, 0, 180);
    if(angulo2 >= 180){
        angulo2 = 180;
    }else if(angulo2 <= 0){
        angulo2 = 0;
    }

    angulo3 = map(poten3, 0, 1023, 0, 180);
    if(angulo3 >= 180){
        angulo3 = 180;
    }else if(angulo3 <= 0){
        angulo3 = 0;
    }
    
    angulo4 = map(poten4, 0, 1023, 0, 180);
    if(angulo4 >= 180){
        angulo4 = 180;
    }else if(angulo4 <= 0){
        angulo4 = 0;
    }

    set_servo();
}

void set_servo(){
    servo1.write(angulo1);
    servo2.write(angulo2);
    servo3.write(angulo3);
    servo4.write(angulo4);
}

El código es sumamente sencillo. Una vez definidos los pines, solo nos queda leer la posición de los potenciómetros, mapear su resultado del rango 0 – 1024 a 0 – 180 (180 son los grados de movimiento de los servos que yo he usado) y llevar los servos a la posición indicada.

En este punto podemos reducir el ángulo de giro de los servos. Por ejemplo, la pinza no usa el giro completo del servo. Podemos recolocar el servo para que la pinza use, un rango medio del giro del servo (de 15º a 105º). Lo conseguimos mapeando la lectura del potenciómetro en el rango de 10º a 105º, logrando poder ejercer presión (a costa de vida útil del servo) manteniendo su apertura.

Y eso es todo. El brazo se muevo como esperaba. Podría haber usado un control mas adecuado, con botones o un par de joysticks, pero el objetivo final es manejarlo desde un ordenador.

Brazo Robótico

Me han regalado un brazo robótico. Y si te regalan un juguete, lo mas correcto es jugar con el juguete. El brazo es este:

Brazo

Como se ve es de metacrilato y muy sencillo. Funciona con 4 servos SG90, pero no busco potencia, busco divertirme. Usa uno para controlar el giro, otro para la pinza y otros dos para el acionamiento del brazo:

Mi objetivo final es manejarlo desde un ordenador con linux, posiblemente una raspberry, por medio de un arduino usando el puerto USB. Para ello me pongo unos hitos:

  • Control del brazo por medio de arduino con unos potenciometros. Sobre todo para comprobar que todo funciona y refamiliarizarme con el código de Arduino.
  • Control del brazo con un mando de consola o similar. Necesito aprender como dirigir de forma efectiva el brazo. Aprender como llevarlo a unas coordenadas concretas.
  • Control desde el ordenador con el puerto serie, dando las ordenes de forma manual. Puede que la acometa directamente, saltándome el paso anterior.
  • Control del brazo desde un ordenador. No he decidido como hacerlo. Se me ocurren varias opciones:
    • Una web con php de fondo.
    • Una aplicación con python.

Seguimos con la temperatura y la humedad

Uno de los problemas es la necesidad de usar «tempered» con sudo. Para evitarlo vamos a mover las librerías y el programa a una de las carpetas que usa el sistema para buscar programas y librerias y a añadir una regla para permitir el uso del USB.

Nos movemos a la carpeta donde hemos compilado tempered y hacemos como root lo siguiente:

cp ./libtempered-util/libtempered-util.so.0 /usr/local/lib
cp ./libtempered/libtempered.so.0 /usr/local/lib/
ldconfig
cp ./tempered /usr/local/bin
nano /etc/udev/rules.d/88-tempered.rules

y ponemos

SUBSYSTEMS==»usb», ATTRS{idVendor}==»0c45″, ATTRS{idProduct}==»7402″, GROUP=»users», MODE=»0666″

cerramos el archivo, salimos de root y como el usuario que queremos que ejecute tempered ponemos:

 

sudo usermod -a -G users $USER
sudo service udev restart

Y ya está. Ya podemos usar tempered como otro usuario diferente a roo y dese cualquier sitio.

Uso del sensor de temperatura y humedad

El sensor que voy a usar es este:

Al hacer un lsusb se identifica como:  0c45:7402 Microdia TEMPerHUM Temperature & Humidity Sensor
 
Despues de mucho buscar encontré la forma de hacerlo funcionar. Toda la información está sacada de aquí. El problema viene que es una nueva versión (TEMPerHumM12V1.3) basada en otro chip.

Lo primero es instalar las dependencias:

sudo aptitude install libhidapi-hidraw0 libhidapi-libusb0 libudev-dev libusb-1.0.0-dev libfox-1.6-dev autoconf cmake libtool dh-autoreconf

Es posible que sobre alguna. Y si se usa otra distro que no sea Raspbian puede que falte algo.
Preparamos un directorio para clonar el git y compilar. Cambiamos a ese directorio y clonamos el repositorio:

sudo git clone git://github.com/edorfaus/TEMPered

Esto no nos vale directamente por que está preparado para otras versiones y modelos de sensores. Para poder usar el sensor tenemos que aplicar las correcciones que se detallan en este commit.
Hay que sustituir un archivo que modifican y añadir otros dos. Por comodidad dejo los aquí.

Ya solo nos queda compilar. Para ello seguimos las instrucciones proporcionadas en el propio proecto:

cd TEMPered

 ccmake .

make

Con esto ya lo tenemos todo listo, cambiamos al directorio utils y ejecutamos:

sudo ./tempered

Nos aparecerá la informacion del sensor:

/dev/hidraw1 0: temperature 35.99 °C, relative humidity 30.1%, dew point 15.7 °C

Hasta aquí todo bien. Pero como todo en esta vida, el programa tiene un par de fallos:

  1. A veces devuelve la información de la lectura anterior, por lo que solo nos podremos fiar de la segunda lectura.
  2. Otras veces no puede leerse la información del sensor, devolviendo «Could not open device: Read of data from the sensor failed: (null)». La solución es volver a repetir la lectura.

Obviamente la solución mas elegante no es repetir la lectura, sino que sería modificar el programa para evitar esos fallos, pero no se C, así que esa solución se la dejo a quién se anime.

Uso los relés usb en linux

Voy a usar un relé usb como este:

Y resulta que estos relés chinos siguen casi todos las mismas especificaciones, y se usan de la misma forma. Además resulta que no soy ni el primero ni el más listo de los que lo usan y hasta hay un proyecto en GitHud que es un controlador de relés usb. El proyecto se llama usbrelay y lo podéis encontrar aquí.

Para más sorpresa mía lo encontré también en los repositorios de Raspbian, por lo que el proceso de instalación es muy sencillo:

$sudo aptitude install usbrelay

 Más facil imposible.

Una vez instalado lo ejecutamos y nos saldrá algo así:

Esto nos da información sobre el aparato y el estado de los sensores. Tenemos que comprobar que donde pone type el valor sea «16c0 05df», si no es así debemos ejecutar usbrelay de la siguiente forma:

$sudo USBID=16c0:05df usbrelay

 Ahora nos tenemos que fijar en las dos ultimas lineas de la salida de usbrelay. En ellas nos enumera los relés de la placa y su estado.

          64T05_1=0
          64T05_2=0

Si el valor del estado es 0 significa que está en su estado «natural»: el puerto NC cerrado y el NO abierto y si es 1 lo contrario.
Y ahora lo encendemos con:

$sudo usbrelay 64T05_1=1

 y lo apagamos con:

$sudo usbrelay 64T05_1=0

Se pueden apagar o encender dos dispositivos a la vez, aunque sean de diferentes módulos:

$sudo usbrelay 64T05_1=1 64T05_2=0 0M70M_1=0

En la página del proyecto nos dan un truco muy útil para los scrips. Con el comando

$sudo usbrelay 2>/dev/null

nos devuelve el estado de los relés.

Y esto es todo. En la siguiente entrada veremos como se controla el sensor de humedad y temperatura y luego lo integraremos todo en un script que ejecutaremos regularmente con la ayuda de cron (el «programador de tareas» de linux).

Especificaciones de Pi grow

Pi grow es  un proyecto de codigo libre con el que quiero conseguir un sistema de automatización y control de un cultivo de marihuana en un armario.

El objetivo final es controlar y regular todos los aspectos del cuidado diario del cultivo:

  • Humedad y temperaturas aereas
  • Humedad del sustrato
  • Riego y abonado
  • Encendido y apagado de las lamparas

Todos estos parámetros deben ser controlados y regulados desde una página web y otro sistema como mail o twitter.

Además se implmentará un sistema de video que nos permita ver las plantas y realizar fotografias.

Hay otra serie de funciones que se podran o no ir implementado como la deteccion de la apertura del armario, video-vigilancia del exterior, etc.

Empezemos por reunir el material necesario:

    • Una Raspberry Pi. Realmente nos vale cualquier ordenador que tenga linux instalado, pero la rapsberry consume un máximo de 5W/h y no es necesaria mayor potencia. Yo voy a usar Debian por lo que aconsejo, si se quiere replicar, usarlo tambien (o una derivada). Preferiblemente conectado en red para poder monitorizarlo.
    • Sensor de humedad y temperatura USB. Yo voy a a usar este por ser multiplataforma
       
    • Relé controlado por USB. Los hay de 1, 2, 4 y 8 relés en una sola placa. En principio voy a usar este por que está mas o menos documentado. Es de solo 2 relés por que primero quiero controlar solo tempeatura y humedad, como prueba de cocepto.

    • Una web cam. En principio voy a usar una de la PS3, que dan muy buena imagen y se encuentran baratas de segunda mano.

        Esto es lo fundamental para poder registrar temperatura y humedad y actuar sobre un humidificador y el ventilador de entrada de aire. Tambien tenemos registro fotográfico, video y una plataforma capaz de hacer de servidor web.

        Solo nos queda ponernos manos a la obra, primero con el sensor de humedad y temperatura y luego con los relés. Pero eso lo dejo para otro día.

        Como usar dos LCD con un arduino (II)

        En un post del foro español de Arduino surgió el tema de como conectar las dos LCD y expuse el método que publiqué en esta entrada (Como usar dos LCD con un arduino (I) ) y que consiste en el uso de puertas lógicas,. Entre otras cosas se comentó otro método que permite hacer lo mismo que expuse anteriormente. El post en en cuestión está aquí.

        La solución que se propuso es declarar ambas LCD en el programa de la siguiente forma:

        LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
        LiquidCrystal lcd2(12, 10, 5, 4, 3, 2);

        Dos consideraciones a este método:

        Como usar dos LCD con un arduino (I)

        En el foro español de Arduino hubo un compañero que me dijo, con razón, que con una sola pantalla de 2×16 la información que puedo mostrar es limitada. Pero no quiero subir mucho el presupuesto ni tengo mas pines libres, y dandole vueltas al asunto se me ocurrió que sería  estupendo poder poner una pantalla por cada corredor. No son muy caras (menos de 10 euros), pero no tengo tantos pines libres.

        La cuestión de los pines libres me tenia totalmente atascado, hasta que di con la solución: usar puertas lógicas y un pin de control. Os pongo un esquema (escaneado, no he sido capaz de hacer con KiCad y paso de hacerlo con un programa de dibujo):

        Especificaciones del digitalizador de mandos v1

        Su utilidad es permitir controlar el coche de una forma mas precisa que con un mando convencional, que no deja de ser una resistencia variable. Mi idea es, además, hacerlo compatible con todo tipo de mandos sencillos (los mas baratos y que van incluidos en cualquier circuito) para dotarlos de características avanzadas por poco dinero.

        ¿Que son estas características y a que necesidades responden?

        Gestor de Carreras 1.0. Código comentado

        Me encanta enseñar el código que escribo. ¿Por que?. En parte por un poco de orgullo. Pero también para que los demás puedan mostrarme mis errores o como puedo optimizar el rendimiento de lo que he escrito y para que los pocos que saben menos que yo tengan un algo que copiar, tal y como hago muchas veces. Creo que esa es una parte esencial del software libre, la reutilización de porciones de código así, por ejemplo, cuando he necesitado escribir en la LCD no he creado la librería, he utilizado una de código libre.

        Página 1 de 2

        Funciona con WordPress & Tema de Anders Norén