¿Qué es este blog?

La idea de este blog nace para compartir los avances que se vayan realizando a lo largo de un estudio sobre cómo interconectar los distintos sensores que se pueden encontrar en el mercado, o fabricar de forma casera, con la plataforma Mindstorms de LEGO. Para ello se hará uso ARDUINO, un entorno de desarrollo abierto basado en microcontrolador.

jueves, 24 de marzo de 2011

Primera comunicación NXT <--> Arduino <--> Sensor analógico


         En esta entrada se va a describir cómo conectar sensores analógicos al NXT usando Arduino como intermediario.
Aunque la conexión de sensores analógicos se puede hacer de manera directa a los puertos del NXT, cada sensor presenta unas resistencias de salida distintas, unos rangos de tensión y corriente distintos, y además, para poder conectar varios sensores a la misma entrada sería necesario un multiplexor y una circuitería que permitiera al robot elegir de qué sensor quiere leer. Todas estas funciones van a ser desempeñadas por Arduino, que será el encargado de leer los valores analógicos desde los sensores, hacer la conversión a digital, y mandar los datos al robot que éste necesite.


Sensor analógico: Ardupilot 4 DOF


El Ardupilot 4 DOF es un IMU que proviene de un proyecto original de Chris Anderson y Jordi Muñoz para crear un AHRS (Attitude Heading Reference System) para control UAV y captura general de movimiento y orientación.
Ésta es la placa principal de sensores que se usa en la placa ArduPilot. Por si sola proporciona 4 grados de libertad (4 DOF) y puede ser conectada directamente a sus pines analógicos o utilizado en cualquier otro proyecto que necesite de captura de movimiento sobre varios ejes.
El sensor viene equipado con un giroscopio LISY300AL de ±300°/s de un sólo eje y un acelerómetro ADXL335 de 3 ejes ±3g. Todo los componentes de filtrado están incorporados en la placa. No dispone de regulador de tensión, por lo que hay que aplicar una tensión de alimentación limpia de 3.3V.

Las principales características de esta placa son:
  • 4 grados de libertad:
    • ADXL335 - acelerómetro de 3 ejes, ±3g
    • LISY300AL - giroscopio de un eje para velocidad angular, ±300°/s
  • Compatible con ArduPilot 6DOF daughter board
  • Los valores analógicos de los seis ejes son accesibles
  • Espaciado de pines: 0.1"
  • Dimensiones: 2.3x1.5cm
En las figura siguiente se puede ver tanto el tamaño de la placa, como las salidas que ésta nos ofrece:










Conexiones entre Arduino Mega 2560 y el IMU

El primer paso es realizar la conexión entre la placa de Arduino que se ha utilizado (Arduino Mega 2560) y el sensor descrito anteriormente. Las conexiones que se han hecho han sido:
  • Salidas y,z,x del acelerómetro y x, y z del giróscopo a las entradas A0-A5 analógicas de la placa (en ese orden, aunque eso da igual siempre y cuando lo tengamos en cuenta en el código que se use).
  • La toma de alimentación de 3,3 V del sensor necesita una alimentación estable. Se conecta a la salida de 3,3 V de Arduino y al pin AREF. Esto último se hace para escalar correctamente el conversor A/D, ya que la referencia analógica por defecto para Arduino es de 5 V.
  • Las tierras se conectan juntas

Conexiones entre Arduino Mega 2560 y el NXT

En cuanto a las conexiones entre el sistema de desarrollo de Arduino y el NXT, éstas ya se comentaron en otra entrada del blog. Al igual que entonces, esta comunicación se va a realizar siguiendo el protocolo de comunicación I2C. Estas conexiones serían las siguientes:
  • Pines 2 y 3 del NXT (colores rojo y negro) se conectan a las entradas de tierra de Arduino (GND).
  • Pin 4 del NXT (color verde) que corresponde a la alimentación, se conecta a la entrada de 5 V de Arduino.
  •  Pin 5 del NXT (color amarillo) que corresponde a la línea de reloj del protocolo I2C se conecta al pin marcado como SCL en la placa de Arduino.
  • Pin 6 del NXT (color azul) que corresponde a la línea de datos del protocolo I2C se conecta al pin marcado como SDA en la placa de Arduino.

 Código cargado en el NXT

En cuanto a las conexiones entre el sistema de desarrollo de Arduino y el NXT, éstas ya se comentaron el apartado 4.3 de esta memoria. Al igual que entonces, esta comunicación se va a realizar siguiendo el protocolo de comunicación I2C. Estas conexiones serían las siguientes:
-       Pines 2 y 3 del NXT (colores rojo y negro) se conectan a las entradas de tierra de Arduino (GND).
-       Pin 4 del NXT (color verde) que corresponde a la alimentación, se conecta a la entrada de 5 V de Arduino.
-       Pin 5 del NXT (color amarillo) que corresponde a la línea de reloj del protocolo I2C se conecta al pin marcado como SCL en la placa de Arduino.
-       Pin 6 del NXT (color azul) que corresponde a la línea de datos del protocolo I2C se conecta al pin marcado como SDA en la placa de Arduino.


import lejos.nxt.*;




public class ArduCom {




    public static void main(String[] args) throws Exception{
        byte [] dato = new byte[3];
        String Tipo = "";
        String ID ="";
        String Ver="";
        int err = 0;
       
        for (int i=0;i<dato.length;i++){
            dato[i] = 0;
        }
       
        I2CSensor Arduino = new I2CSensor(SensorPort.S1);
        Arduino.setAddress(1);
        Ver = Arduino.getVersion();
        System.out.println("Ver: "+Ver);
        Tipo = Arduino.getSensorType();
        System.out.println("Tipo: "+Tipo);
        ID = Arduino.getProductID();
        System.out.println("ID: "+ID);
        Thread.sleep(1000);
        while (!Button.ESCAPE.isPressed()) {
            err = Arduino.getData(3, dato, 3);
            System.out.println("Acel: "+dato[0]+" "+dato[1]+" "+dato[2]);;
            err = Arduino.getData(4, dato, 3);
            System.out.println("Giros: "+dato[0]+" "+dato[1]+" "+dato[2]);
        } //Fin del while
    }
}

Código cargado en Arduino


A continuación se va a presentar el código que se ha cargado en Arduino. Este código se ha dejado comentado para facilitar la comprensión del mismo. Las tareas que realiza son las siguientes:
-       En el apartado de configuración (setup) se configura:
o   Referencia externa de 3,3 V
o   Se marcan los pines analógicos como salidas
o   Nos unimos al bus I2C como esclavos usando la dirección 1. A través de él se realizará la comunicación con el NXT.
o   Se configura la velocidad de escritura por el puerto serie, lo que nos va a permitir ver a través de la herramienta de monitorización del propio entorno de desarrollo de Arduino los datos que vayamos leyendo y convirtiendo desde el sensor analógico.
o   Se configuran las rutinas que se ejecutarán cuando se reciba una petición de datos desde el NXT
-       El bucle principal realiza la lectura de los pines analógicos comprendidos entre el 0 y el 5, que será donde estén conectados los pines del sensor. Se les resta el valor medio del sensor en reposo para que den un valor 0 estando en reposo. Estos datos se almacenan y se dejan listos para enviarlos al NXT cuando sea necesario.
-       En las rutinas de interrupción se identifica  el tipo de dato que está pidiendo el NXT (codificado en el campo registro) y se procede al envío de dichos datos.

El código usado es el siguiente:



#include <Wire.h> //Para gestionar las comunicaciones


//Definiciones y variables globales


uint8_t SensorVersion[9] = " V0.1   ";
uint8_t SensorName[9] =    "Arduino ";
uint8_t SensorType[9] =    "Casero  ";
byte buffersalida[] = { 0, 0, 0, 0, 0, 0}; //Para enviar al RCX
byte buffgiros[] = { 0, 0, 0}; //Ejes x, y, z del giroscopo
byte buffacel[] = { 0, 0, 0}; // Ejes x, y, z del acelerometro


int val = 0;                    //Datos que se leeran del acelerometro o giroscopo
unsigned long timer=0;          //timer
unsigned long  delta_t;         //delta o tiempo entre muestras


byte rec;


void setup(){
 
  analogReference(EXTERNAL);     //Usamos referencia externa de 3,3 V para calibrar el ADC
  Serial.begin(115200);
  DDRC = B00000000; //Marcamos los puertos analogicos como salidas
 
  Serial.println("t[ms] \t az \t ay \t ax \t gx \t gy \t gz "); //Cabeceras
   
  Wire.begin(1); //Nos unimos como esclavos con dir. 1
  Wire.onRequest(requestEvent); //Rutinas para cuando llegue algo
  Wire.onReceive(receiveEvent);
 
  timer=millis();
}




void loop(){
  delta_t = millis() - timer; // Calculamos el tiempo de adquisicion
  timer=millis();          // Actualizamos el timer
  Serial.print(delta_t);
  Serial.print ("\t");
    
  for (long i=0; i<6; i++) //Vamos a recorrer los pines analogicos
 {
  val = analogRead(i);    // Leemos el pin de entrada
 
  if(i==0) { //Le quitamos el offset al valor leido
    val = val - 601;
    buffacel[2] = val; //Eje z del acelerometro
  } else if (i==1) {
    val = val - 506;
    buffacel[1] =  val; // Eje y del acelerometro
  } else if (i==2) {
    val = val - 504;
    buffacel[0] =  val; // Eje x del acelerometro
  } else if (i==3) {
    val = val - 504;
    buffgiros[0] = val; //Eje x del giroscopo
  } else if (i==4) {
    val = val - 502; //Valor medio       
    buffgiros[1] = val; //Eje y del giroscopo
  } else if (i==5) {
    val = val - 483; //Valor medio
    buffgiros[2] = val; //Eje z del giroscopo
  }
 
  Serial.print(val);      //Imrpimimos por puerto serie
  Serial.print ("\t");
 } 


  Serial.println("");
  delay(16);             //Bucle ejecutado a ~ 50Hz o 20ms
}


void receiveEvent(int len){ //Devuelve el nº de bytes recibidos
  while (0 < Wire.available() ) {
    rec = Wire.receive();
  } //While
}


void requestEvent(){


  Serial.print(rec, BYTE);
  if (rec == 0x00){ //Version del sensor
    Wire.send(SensorVersion, 8);


  } else if (rec == 0x08){ //Nombre del sensor
    Wire.send(SensorName, 8);
  } else if (rec == 0x10){ //Tipo del sensor
    Wire.send(SensorType, 8);
  } else if (rec == 0x03) { // Lectura del acelerometro
    Wire.send(buffacel, 3);
  } else if (rec = 0x04) { //Lectura del giroscopo
    Wire.send(buffgiros, 3);
  } else {
    buffersalida[0] = 0;
    buffersalida[1] = 0;
    Wire.send(buffersalida, 2);
  }
}


Conclusiones

Se ha realizado con éxito la comunicación entre un sensor analógico y el NXT usando como intermediario el Sistema de Desarrollo Arduino, que se comunica con el robot haciendo uso del protocolo I2C. Los datos que se reciben desde el sensor analógico son correctos, y sólo se aprecia una oscilación de números algo mayor en dos ejes del giróscopo. Esta oscilación debida al ruido de medida, puede estar relacionada con el hecho de que las pruebas se hayan realizado en una placa de prototipos estándar y con hilos de conexión normales. A continuación se muestra una fotografía tomada del sistema bajo pruebas.
----------------------------------------------------------------------------------------------------------------
Referencias:


- Razor IMU and Arduino: http://voidbot.net/razor-6dof.html

No hay comentarios:

Publicar un comentario

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