3 sustituciÓn de ordenador de a bordobibing.us.es/proyectos/abreproy/70354/fichero... · capítulo...

23
Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 22 3 SUSTITUCIÓN DE ORDENADOR DE A BORDO 3.1 Elección de la nueva placa En un primer momento, tras la avería de la antigua placa Hercules EBX de Diamond Systems, se pensó en adquirir la nueva versión de la misma placa. No obstante, a pesar de ser una nueva versión, esta placa estaba a punto de descatalogarse. Además, contaba con una serie de características (como el número de entradas/salidas) que superaba nuestras necesidades, un tamaño y consumo elevados y un precio bastante superior al de otras opciones que tanteamos en el mercado (alrededor de 600 ). Por estos motivos se decidió reemplazar la Hercules EBX por otro modelo que superase sus prestaciones. Las necesidades de que partíamos eran función de los sensores ya desarrollados, del modelo de helicóptero comercial de que se disponía y de los objetivos planteados: Microprocesador lo bastante potente para realizar todos los cálculos y muestreos precisos bajo fuertes restricciones de tiempo. Bajo consumo, puesto que durante el vuelo se emplearán baterías. Al menos, dos entradas analógicas (para los dos potenciómetros), dos entradas y una salida digitales (para los sensores de ultrasonidos y óptico) y un puerto serie (para la IMU). Conexión Wi-Fi. La antigua placa únicamente contaba con conexión Ethernet, lo que obligaba a la utilización de un puente Ethernet para las comunicaciones con Tierra que incrementaba el peso y el consumo. Salidas PWM. Aunque es posible generar señales PWM con dispositivos adicionales, lo ideal sería encontrar una placa que disponga, al menos, de 5 salidas PWM (una para cada servo). Tras una intensa búsqueda de nuevos modelos, nos quedamos con cuatro placas candidatas a reemplazar a la Hercules EBX. En la Tabla 1 se muestra una comparativa con las características de las candidatas que más nos convencieron a priori. Características Helios (Diamond Systems) PCM-9361 (Advantech) TS-7800 (Technologic Systems) BL5S220 (Rabbit) Procesador 300/800 MHz Vortex86DX Intel Atom N270 1.60 GHz Marvell 500MHz ARM9 Rabbit® 5000 at 73.73 MHz Consumo 300MHz: 3.5W 800MHz: 5.4W 5 V-> 0.07 A 12 V-> 1.90 A 4W 9 W (máx.) Wi-Fi No No No Dimensiones 90 x 96 mm 146 x 102 mm 90.17 × 95.89 mm 90 x 96 x 15 mm Peso 70.8 g 0.85 kg ? 70.8 g Puertos USB 4 5 2 ?

Upload: others

Post on 27-Sep-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

22

3 SUSTITUCIÓN DE ORDENADOR DE A BORDO

3.1 Elección de la nueva placa En un primer momento, tras la avería de la antigua placa Hercules EBX de Diamond Systems, se

pensó en adquirir la nueva versión de la misma placa. No obstante, a pesar de ser una nueva

versión, esta placa estaba a punto de descatalogarse. Además, contaba con una serie de

características (como el número de entradas/salidas) que superaba nuestras necesidades, un

tamaño y consumo elevados y un precio bastante superior al de otras opciones que tanteamos

en el mercado (alrededor de 600 €). Por estos motivos se decidió reemplazar la Hercules EBX

por otro modelo que superase sus prestaciones.

Las necesidades de que partíamos eran función de los sensores ya desarrollados, del modelo

de helicóptero comercial de que se disponía y de los objetivos planteados:

Microprocesador lo bastante potente para realizar todos los cálculos y muestreos

precisos bajo fuertes restricciones de tiempo.

Bajo consumo, puesto que durante el vuelo se emplearán baterías.

Al menos, dos entradas analógicas (para los dos potenciómetros), dos entradas y una

salida digitales (para los sensores de ultrasonidos y óptico) y un puerto serie (para la

IMU).

Conexión Wi-Fi. La antigua placa únicamente contaba con conexión Ethernet, lo que

obligaba a la utilización de un puente Ethernet para las comunicaciones con Tierra que

incrementaba el peso y el consumo.

Salidas PWM. Aunque es posible generar señales PWM con dispositivos adicionales, lo

ideal sería encontrar una placa que disponga, al menos, de 5 salidas PWM (una para

cada servo).

Tras una intensa búsqueda de nuevos modelos, nos quedamos con cuatro placas candidatas a

reemplazar a la Hercules EBX. En la Tabla 1 se muestra una comparativa con las características

de las candidatas que más nos convencieron a priori.

Características Helios (Diamond

Systems) PCM-9361

(Advantech)

TS-7800 (Technologic

Systems)

BL5S220 (Rabbit)

Procesador 300/800 MHz Vortex86DX

Intel Atom N270 1.60 GHz

Marvell 500MHz ARM9

Rabbit® 5000 at 73.73 MHz

Consumo 300MHz: 3.5W

800MHz: 5.4W

5 V-> 0.07 A

12 V-> 1.90 A 4W 9 W (máx.)

Wi-Fi No No No Sí

Dimensiones 90 x 96 mm 146 x 102 mm 90.17 × 95.89 mm 90 x 96 x 15 mm

Peso 70.8 g 0.85 kg ? 70.8 g

Puertos USB 4 5 2 ?

Page 2: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

23

Puertos Serie 2 2 2 2

E/S digitales y analógicas

40 E/S digitales

16/8 analógicas

8-bit GPIO 110-bit GPIO 40 E/S digitales

8 E, 2 S analóg.

Salidas PWM Ninguna Ninguna Ninguna Ninguna

Precio 966 € 231 € 163 € 199 €

Tabla 1: Placas candidatas a suplir a la Hercules EBX

Lo primero que concluimos al observar la Tabla 1 es la escasez de salidas PWM que

presentaban las placas de los fabricantes más importantes. Esta circunstancia nos llevó a la

decisión de emplear el dispositivo Mini Maestro 12-channel USB Servo Controller de Pololu,

encargado de enviar a los servos señales PWM a partir de las posiciones deseadas indicadas

desde el PC, que veremos en el Apartado 6.2 .

En cuanto a la elección de la placa, aunque en principio la TS-7800 no contaba ni con conexión

Wi-Fi ni con entradas analógicas, el fabricante ofrecía la opción de adquirir un adaptador Wi-Fi

por USB por 25€ más, así como un periférico PC/104 para conversión ADC por otros 42€. Con

estos dos elementos adicionales cubríamos por completo nuestras necesidades iniciales.

Además, el fabricante Technologic Systems ofrecía un kit de desarrollo por 71€ más que nos

pareció de gran interés, puesto que consistía en una tarjeta SD de 2GB con el kernel 2.6 y un

Debian Linux, ambos ya compilados para la placa, lo que seguramente nos ahorraría algunas

semanas de trabajo.

Todos estos motivos, más la constatación de que Technologic Systems contaba con un foro de

desarrolladores al que poder recurrir en un futuro, nos llevaron a inclinarnos finalmente por el

PC embebido TS7800.

Figura 24: TS7800 de Technologic Systems

Conector DB9

Conector USB

Conector

Ethernet

Ranura

tarjeta SD

DIOs

Conector

PC104 Alimentación

Page 3: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

24

3.2 TS-7800 de Technologic Systems

3.2.1 Características La TS-7800 de Technologic Systems es una placa computadora o SBC (Single Board Computer)

que sigue la directiva RoHS basada en una CPU ARM9 de Marvell a 500MHz con bus PCI

interno, y que provee de un conjunto estándar de periféricos de a bordo como Gigabit

Ethernet, SATA dual y USB 2.0 maestro/esclavo dual de alta velocidad.

La TS-7800 también ofrece una FPGA de Lattice Semiconductor con LUT de 12000 puertas

lógicas programable mediante software Linux y que provee de periféricos extras, tales como

110 líneas GPIO y puertos serie adicionales.

En cuanto al software, la TS-7800 utiliza un kernel 2.6 de Linux mejorado por Technologic

Systems, que permite arrancar en 0.69 s y provee soporte para drivers para todo el hardware

de a bordo. Además, la memoria flash de 512 MB de a bordo permite la instalación de una

distribución Debian completa con un entorno de desarrollo incorporado.

La siguiente lista resume las características más destacables de la TS-7800:

CPU ARM9 a 500Mhz

Bus PCI interno, conector PC/104

FPGA programable con LUT de 12000 puertas lógicas

DDR-RAM de 128MB

Memoria Flash NAND de 512MB, alta velocidad (17MB/s)

Ranura para SD (1 Micro SD, 1 SD de tamaño completo)

Puertos SATA

2 puertos USB 2.0 maestro/esclavo a 480Mbps

Gigabit Ethernet, velocidades 10/100/1000

Canales ADC de 10 bits

10 puertos serie, 2 puertos RS-485 opcionales

110 GPIO (86 asociadas al bus PC/104)

Interfaces para teclado matricial y LCD alfanumérico

Operación entre -20° y +70°C sin ventilador

Bajo consumo: 4W@5V

Consumo de 200 microamperios en modo suspensión

Arranque al prompt del shell de Linux en 0.69 segundos

Ejecuta kernel 2.6 y Linux Debian por defecto

3.2.2 Primeras pruebas

3.2.2.1 Tipos de arranque

El primer aspecto de la nueva placa con el que nos tuvimos que familiarizar fue el de los dos

tipos de arranque que presenta:

Page 4: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

25

El primero de ellos (por defecto) dura menos de 1.1 segundos, y se realiza desde la

memoria flash de a bordo. Mediante este arranque sólo tenemos acceso a las

utilidades estándares más comunes a través del programa Busybox.

Si tecleamos exit, la placa trata de realizar un arranque desde la partición 4 de la

tarjeta SD o bien desde la Micro SD.

La SD proporcionada por Technologic Systems contiene una versión completa de la

distribución Debian de Linux compilada específicamente para la placa y contiene Apache, SSH,

PPP, servidor FTP y otras utilidades y librerías de uso común, por lo que será el entorno en que

trabajemos habitualmente. Para evitar el arranque rápido por defecto no tenemos más que

escribir el siguiente comando en el shell:

ln -sf /linuxrc-sdroot /linuxrc; save

El archivo /linuxrc es un script del shell, que es lo primero que el kernel ejecuta al

encender la placa. Con la creación de este enlace simbólico entre archivos configuramos la

placa para arrancar directamente la versión de Linux instalada en la SD.

3.2.2.2 Comunicaciones

Conexión mediante medio físico

La TS-7800 no tiene salida de vídeo, teclado o ratón, sino que está pensada para ser utilizada

como una consola a la que se accede desde un PC con un emulador de terminal. La conexión a

la TS-7800 desde el PC remoto puede realizarse bien mediante el cable null-modem incluido en

el Development Kit de la placa o bien mediante Telnet con un cable Ethernet.

Para ambos tipos de conexión podemos hacer uso del programa PuTTY, emulador de terminal

que permite conectar máquinas remotas y ejecutar programas a distancia. PuTTY se conecta

como cliente a múltiples protocolos, como SSH, Telnet o Rlogin.

La configuración inicial de la TS-7800 se hará conectándonos mediante cable Ethernet. Una vez

finalizada dicha configuración, tendremos la Wi-Fi habilitada, por lo que podremos prescindir

del cable.

Page 5: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

26

Figura 25: Emulador de terminal Putty

Configuración Wi-Fi

El driver especificado por el fabricante para poder utilizar el adaptador Wi-Fi por USB, el

ZD1211RW, ya viene instalado en la tarjeta SD, por lo que no hay más que dar los pasos

habituales para conectarse a una red Wi-Fi en Debian:

1. Averiguamos qué unidad está ligada al dispositivo inalámbrico.

>> iwconfig

2. Escaneamos las redes inalámbricas dentro de nuestro alcance.

>> iwconfig eth1 scanning

3. Editamos el fichero /etc/network/interfaces tal como muestra la Tabla 2:

iface eth1 inet static

address 192.168.123.52

network 192.168.123.0

netmask 255.255.255.0

broadcast 192.168.123.255

gateway 192.168.123.1

wireless-essid waplpb

wireless-channel 6

wireless-key off

wireless-mode auto

wireless-rate auto

wireless-keymode open

Tabla 2: Fichero /etc/network/interfaces

Page 6: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

27

4. Indicamos el ESSID de la red WiFi a la que queremos que se conecte por defecto

(“waplbp”), así como la dirección IP deseada para la interfaz (192.168.123.52).

>> ifconfig eth1 up

>> iwconfig eth1 essid waplpb

>> ifconfig eth1 192.168.123.52

5. Actualizamos los cambios.

>> /etc/init.d/networking restart

Conexión a Internet

Para completar la configuración de las conexiones de la TS-7800, especificamos el proxy y las

DNS para lograr la conexión a Internet mediante las dos acciones siguientes:

Escribir en línea de comandos la dirección del proxy (172.1.0.15).

>> export http_proxy=http://172.1.0.15

Incluir en el fichero /etc/resolv.conf tantas líneas como DNS queramos

especificar (150.214.186.69, 150.214.186.69).

nameserver 150.214.186.69

nameserver 150.214.186.69

3.2.2.3 Prueba de las entradas y salidas digitales

La comunicación con los sensores de ultrasonido y óptico se realiza a través de las DIOs de la

TS-7800. Para su conexión física debemos atender al conector de las DIOs que ilustra la Tabla

3.

Tabla 3: Conector de las DIOs

Para la lectura y escritura de los pines de las DIOs se dispone de los primeros 16 bits de los

registros de entrada (ubicado en la dirección física 0xe8000004 de la FPGA) y salida (ubicado

en la dirección física 0xe8000008 de la FPGA). Si escribimos un 0 en uno de los bits del registro

0xe8000008, lo ponemos a nivel bajo. Si, por el contrario, escribimos un 1, pondremos el

correspondiente pin en estado de alta impedancia; esto es, estaremos sacando un 1, pero a la

vez podremos utilizar el registro 0xe8000004 para leer los valores que esté recibiendo como

entrada.

Vemos un ejemplo con la DIO 01:

Page 7: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

28

Si multiplicamos el valor del registro 0xe8000008 por la cifra hexadecimal 0xFFFE,

estaremos sacando un nivel bajo por la DIO 01.

Si sumamos 0x01 al valor del registro 0xe8000008, lo ponemos en estado de alta

impedancia; así, a la vez que generamos un 1 como salida, podemos leer el contenido

del bit 0 del registro 0xe8000004 para saber qué niveles de tensión estamos

recibiendo.

Utilidad peekpoke

La utilidad peekpoke puede utilizarse para acceso directo a las direcciones de memoria. Está

especialmente diseñada para tareas de depuración hardware de bajo nivel.

Si queremos reproducir sobre la placa el ejemplo anterior no tenemos más que escribir las

siguientes órdenes en el prompt:

Sacar un nivel bajo por la DIO 01:

>> poke16 0xe8000008 0x0

Leer el valor digital a la entrada del DIO 01:

>> poke16 0xe8000008 0x1

>> peek16 0xe8000004

Código en C para lectura/escritura de una DIO

El código que aparece en la Tabla 4 muestra la sección de un programa en C que se encarga de

leer el valor de entrada al pin 1 de las DIOs.

#include <stdio.h>

#include <fcntl.h>

#include <sys/mman.h>

#define BASE7800 0xE8000000

volatile unsigned int *DATAIN, *DATAOUT;

unsigned short int state;

unsigned char *start;

int fd = open("/dev/mem", O_RDWR|O_SYNC);

start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd,

BASE7800);

DATAIN = (unsigned int *)(start + 0x04); //registro de datos de

entrada

DATAOUT= (unsigned int *)(start + 0x08); //registro de datos de salida

*DATAOUT=0xffff; //Configuramos los 16 pines como entrada

state = *DATAIN; // Lectura del estado de las DIOs

printf("%X",state); //Impresión en hexadecimal de la lectura de los 16

bits

close(fd);

Tabla 4: Código C para lectura de pin 1 de las DIOs

Page 8: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

29

En la Tabla 5 aparece un ejemplo de programación en C para sacar un valor digital bajo por el

pin 1 de las DIOs durante un segundo y un valor digital alto durante el siguiente segundo.

#include <stdio.h>

#include <fcntl.h>

#include <sys/mman.h>

#define BASE7800 0xE8000000

volatile unsigned int *DATAIN, *DATAOUT;

unsigned short int state;

unsigned char *start;

int fd = open("/dev/mem", O_RDWR|O_SYNC);

start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd,

BASE7800);

DATAIN = (unsigned int *)(start + 0x04); //registro de datos de

entrada

DATAOUT= (unsigned int *)(start + 0x08); //registro de datos de salida

*DATAOUT=*DATAOUT & 0xFFFE; //Sacamos nivel bajo por pin 1 del DIO

header

printf("\nNivel bajo en pin 1 del DIO durante 1 segundo...");

sleep(1);

*DATAOUT=*DATAOUT | 0x1; //Sacamos nivel alto por pin 1 del DIO header

printf("\nNivel alto en pin 1 del DIO durante 1 segundo...");

sleep(1);

close(fd);

Tabla 5: Código C para escritura en pin 1 de las DIOs

3.2.2.4 Pruebas de la comunicación por puerto serie

La IMU se conecta al segundo de los puertos serie que la placa trae habilitados por defecto

(COM2). La única dificultad que tuvimos al principio es que el puerto COM2 tenía activado el

programa getty, que se encarga de manejar el proceso de login cuando accedemos a un PC

Unix. Esto daba lugar a una comunicación nula través del puerto COM2 con la IMU.

Mediante la supresión de la línea del fichero /etc/inittab que activaba el getty logramos

la conexión con la IMU de forma inmediata.

3.3 TS-9700 de Technologic Systems La TS-9700 es una placa periférica con conexión al bus PC/104 que provee de puertos ADC y

DAC para la adquisición de datos en aplicaciones analógicas. Ya explicamos anteriormente que

su uso era necesario para poder leer con la TS-7800 los valores de altitud y paso colectivo

dados por los potenciómetros.

Page 9: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

30

Figura 26: TS-9700 de Technologic Systems

Para el acceso a los periféricos conectados al bus PC/104 de la TS-7800 se toma la dirección de

memoria base del bus (0xEE000000) y se añade el offset correspondiente al periférico en

cuestión. En el caso de la TS-9700, se ubica a partir de las direcciones de memoria resultantes

tras sumar 0x160 a la dirección base del bus. La Tabla 6 muestra el mapa de registros de la TS-

9700.

Tabla 6: Mapa de registros de la TS9700

Cualquier escritura en el A/D Command Register inicia una conversión A/D de 12 bits que se

almacena en los registros A/D LSB y A/D MSB.

Atendiendo, además, a la Tabla 7, observamos que para realizar una conversión A/D nos

tendremos que preocupar de:

1. Seleccionar cuál de los 8 canales de entrada a las TS-9700 queremos convertir,

haciendo uso de los bits 0-2 del A/D Command Register.

Conector

PC104

Entradas

CAD

Jumpers

selección

rango CAD

Page 10: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

31

2. Consultar el bit 7 de dicho comando para ver si está a 1, lo que significa que la placa

está preparada para realizar la conversión.

3. Leer los registros A/D MSB y A/D LSB para obtener el resultado de la conversión (los

cuatro bits superiores del A/D MSB siempre estarán a 0).

Tabla 7: Significado de los bits del A/D Command Register de la TS-9700

Por último, cabe aclarar que la placa dispone de tres jumpers para configurar el rango de la

señal de entrada en cada canal.

Para seleccionar un rango de entrada 0-10 V, sólo debe instalarse el jumper C.

Para seleccionar un rango de entrada 0-2.5 V, puede o bien instalarse sólo el jumper A

o bien no instalarse ninguno.

Para seleccionar un rango de entrada 0-20 mA, los jumpers A y B deben instalarse.

3.3.1 Código en C para conversión A/D de un canal La sección de código de la Tabla 8 muestra un ejemplo de conversión A/D de la tensión a la

entrada del canal 1 de la TS-9700 en el rango 0-2.5 V.

#include <stdio.h>

#include <fcntl.h>

#include <sys/mman.h>

#define BASE7800 0xE8000000

#define ADBASE 0x160 //Dirección base registro de control de la

TS-9700

#define ADREADYBIT 7 //7º bit del registro de control indica si se ha

completado una conversión

#define CHANNEL1 0 //Canal de la TS9700 a convertir

#define BASE 0xEE000000 //Dir. base periféricos conectados al bus

PC/104

unsigned char *base;

unsigned char *start;

volatile unsigned int *REG1, *REG2, *REG3, *REG4;

unsigned char *adcommand; //Puntero a la dirección base del registro

de control de la TS9700

double voltage; //Tensión obtenida de entrada analógica conectada al

potenciómetro

volatile unsigned char *msb;

Page 11: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

32

volatile unsigned char *lsb;

//====================================================================

//Activación de la funcionalidad ISA del bus PC/104

//====================================================================

fd = open ("/dev/mem" , O_RDWR|O_SYNC);

if (fd < 0){

perror ("open");

exit(1);

}

start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd,

BASE7800);

REG1=(unsigned int *)(start + 0x30);

REG2=(unsigned int *)(start + 0x34);

REG3=(unsigned int *)(start + 0x38);

REG4=(unsigned int *)(start + 0x3C);

*REG1 = 0x55555555;

*REG2 = 0x55555555;

*REG3 = 0x55555;

*REG4 = 0x55555;

//Dirección base de la TS-9700 vista desde la TS-7800

base = (unsigned char *)mmap(0, getpagesize(),PROT_READ | PROT_WRITE,

MAP_SHARED, fd, BASE);

if (base == MAP_FAILED){

printf("Error de proyeccion del fichero de configuracion de la

TS9700 \n");

return 0;

}

adcommand = base + ADBASE; //Dirección del registro de control de la

TS9700 conectada al bus PC/104

lsb = base + ADBASE +2; //Dirección de memoria del byte menos

significativo de la conversión A/D

msb = base + ADBASE + 3; //Dirección de memoria del byte más

significativo de la conversión A/D

*adcommand = CHANNEL1; // Los tres primeros bits del registro de

control contienen el nº del canal a convertir

while(!(*adcommand & (1 << ADREADYBIT))) { //Si el bit 6 del registro

de control se pone a "1" se pueden leer lsb y msb

}

//Resultado de la conversión

voltage = (256.0 * *msb + *lsb) * 2.5 / 4096.0;

close(fd);

Tabla 8: Código en C para conversión A/D del canal 1 de la TS-9700

3.4 Migración de la antigua aplicación El principal problema que se presentó en la fase de migración de la aplicación a la nueva placa

fue la ausencia de un driver específico como el que estaba implantado en la Hercules para el

Page 12: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

33

uso y control tanto de la placa como de sus puertos y las funciones más útiles. Esta

circunstancia nos obligó a recurrir a funciones estándares de lectura y escritura de registros,

programación de interrupciones temporales, temporización, etc.

A continuación detallamos algunas de las modificaciones y sustituciones que hubo que realizar

en el código para trasladar la aplicación original a la TS-7800.

3.4.1 Funciones de inicialización Como ya hemos comentado, la antigua Hercules EBX disponía del driver DSCud 5.7, que

facilitaba el control de sus funcionalidades. La primera modificación del código de la aplicación

de a bordo está relacionada con las funciones de inicialización del propio driver (dscInit()) y de

la placa (dscInitBoard()). La nueva placa TS-7800 no precisa de ningún tipo de inicialización

para poder trabajar con ella, por lo que bastará con eliminar dichas funciones del programa.

3.4.2 Supresión de tensiones de salida para alimentación de sensores En la antigua aplicación, los potenciómetros se alimentaban a 10 V mediante las salidas

analógicas de la Hercules, lo que requería la gestión de dichas salidas por código. En la fase de

migración a la TS-7800 se pensó que era más conveniente alimentar los potenciómetros

directamente mediante baterías1, por lo que las secciones de código encargadas de la

alimentación fueron suprimidas.

Así, las funciones dscDASetSettings()(destinada a la configuración de la conversión D/A) y

dscDAConvert()(destinada a la conversión D/A de un canal dado) han dejado de utilizarse en

la aplicación de a bordo, sin necesidad de ser sustituidas por ninguna otra. Los potenciómetros

van a pasar a alimentarse a 5 V mediante las baterías encargadas de alimentar la TS-7800.

3.4.3 Funciones de lectura/escritura digital Las funciones de lecturas y escrituras digitales del driver DSCud de la antigua aplicación de a

bordo han sido sustituidas por los nuevos procedimientos explicados en el Apartado 3.2.2.3.

De esta manera hemos prescindido de las funciones dscDIOSetConfig() (para configuración del

puerto DIO correspondiente), dscDIOInputBit() (que recibe un valor de bit desde un puerto de

entrada digital), dscDIOSetBit (que escribe un 1 en un bit especificado de un puerto), y

dscDIOClearBit (que escribe un 0 en un bit especificado de un puerto).

3.4.4 Funciones de lecturas analógicas En la antigua aplicación se empleaban las funciones dscADSetSettings()para la configuración

de los parámetros de conversión A/D de la entrada analógica, dscADSample()para la

conversión A/D y dscADCodeToVoltage()para el paso de unidades de conversión A/D que

utiliza la placa a niveles de tensión.

A partir de ahora, este conjunto de funciones son sustituidas por las que aparecen en el

ejemplo de lectura analógica de la Tabla 8.

1 El diseño del nuevo sistema de alimentación ha corrido a cargo de Javier Galnares Arias, a excepción de

la elección de las nuevas baterías, proceso que se detalla en el Capítulo 5.

Page 13: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

34

3.4.5 Funciones de recuento de tiempo En la antigua aplicación se había recurrido al siguiente procedimiento para realizar recuentos

de tiempo:

Se generaba una señal PWM de frecuencia conocida.

Se contaba el número de pulsos de dicha señal PWM entre el principio y el fin del

periodo de tiempo cuya duración se quería conocer.

En la fase de migración a la TS-7800, se creyó conveniente emplear la función de lectura de

tiempo gettimeofday() de la librería de tiempo <sys/time.h>. Esta función devuelve la hora

actual codificada en una estructura de tipo timeval, que contiene dos campos:

El campo tv_sec contiene los segundos transcurridos desde el Epoch Unix.

El campo tv_usec contiene los microsegundos transcurridos desde el Epoch Unix.

El procedimiento que seguiremos será el mostrado en la Tabla 9, mediante el cual

obtendremos el tiempo transcurrido entre dos puntos de ejecución del código pasando la hora

en que se produce uno y otro a microsegundos y calculando su diferencia.

struct timeval now;

unsigned long t_1, t_2;

gettimeofday(&now,NULL);

t_1 = now.tv_sec * 1000000 + now.tv_usec;

// Acciones cuya duración se quiere medir

gettimeofday(&now,NULL);

t_2 = now.tv_sec * 1000000 + now.tv_usec;

printf("Tiempo invertido %d\n",(t_2-t_1));

Tabla 9: Código C para medir tiempo transcurrido entre dos instantes de tiempo

3.4.6 Funciones de programación de interrupciones periódicas Las interrupciones periódicas de usuario se programaban en la Hercules con las funciones

dscUserInt() (programa el comienzo de una interrupción de usuario asociada a una función),

dscClearUserInterruptFunction() (desvincula la función asociada a la interrupción) y

dscCancelOp () (cancela la ejecución de todas las interrupciones periódicas programadas).

Ahora tendremos que recurrir al método especificado por POSIX mediante la utilización de

temporizadores y señales que se activan con su expiración, y el consiguiente manejador de la

alarma asociada a dicho evento. La Tabla 10 muestra un ejemplo de programación de una

interrupción cada segundo.

struct itimerval it;

int main( void )

{

it.it_value.tv_sec = 1; // start in 1 second

Page 14: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

35

it.it_value.tv_usec = 0;

it.it_interval.tv_sec = 1; // repeat every second

it.it_interval.tv_usec = 0;

arranca();

}

...

//Manejador de interrupciones temporales

void sigalrm_handler(int sig)

{

//Función periódica

}

arranca (void)//Función que programa el arranque de las interrupciones

temporales

{

if (setitimer(ITIMER_REAL, &it, NULL)!=0)//Definición de los

parámetros del temporizador cuya expiración dará lugar a las

interrupciones

{

printf("Error en la configuracion del timer para las

interrupciones temporales\n");

return 0;

}

if(signal(SIGALRM, sigalrm_handler)==SIG_ERR) //Manejador de las

interrupciones temporales causadas por la finalización del

temporizador

{

printf("Error en la inicialización de las interrupciones

temporales\n");

return 0;

}

}

Tabla 10: Código C para programación de interrupciones temporales

3.5 Resolución de conflictos ocasionados por el cambio de placa Aunque han sido varios los problemas que hemos tenido que afrontar para poder conservar la

mayor parte de la aplicación existente y los sensores implementados, en esta sección

trataremos los dos más relevantes.

3.5.1 Modificación del modo de funcionamiento del sensor de

ultrasonidos El sensor de ultrasonidos empleado, el SRF05, consta de los 5 pines mostrados en la Figura 27,

cuyo significado aparece en la Tabla 11.

Page 15: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

36

Figura 27: Pinout del sensor de ultrasonidos modelo SRF05

Pin Función

+5 Vcc Tensión Positiva de Alimentación

ECO Salida del pulso cuya anchura determina el tiempo del recorrido de la señal ultrasónica.

Disparo Entrada de inicio de una nueva medida. Se aplica un pulso con una duración mínima de 10 us.

Modo (N.C.)

Sin conexión se selecciona el modo 1 de compatibilidad con SRF04.

Conectado a GND se selecciona el modo 2 de trabajo.

GND Tierra de alimentación.

Tabla 11: Significado de los pines del sensor de ultrasonidos modelo SRF05

Inicialmente, el SRF05 estaba configurado para funcionar con los pines de Eco y Disparo

unidos. Esta decisión se tomó para ahorrar conexiones en la antigua placa. Esto suponía que la

E/S digital correspondiente debía configurarse como salida, generar un nivel alto durante unos

microsegundos para activar el sensor, y, a continuación, debía funcionar como entrada para

comenzar a recibir el eco.

El problema surge con la utilización de la lógica triestado por la nueva placa. Ya hemos

explicado que para configurar un bit de las DIOs como entrada debemos escribir en él un 1

para que pase a estado de alta impedancia. Esto implica que, aunque estemos tratando dicho

bit como una entrada, en todo momento estamos sacando un nivel alto por él. Así pues, el

sensor de ultrasonidos se reinicia continuamente, y no somos capaces de recibir el eco.

Afortunadamente, el SRF05 consta de un modo de funcionamiento alternativo, con los bits de

Eco y Disparo separados, que nos permitió solventar este problema. Tal como indica la Tabla

11, para seleccionar este modo de funcionamiento no tenemos más que dejar sin conectar el

pin denominado Modo.

Page 16: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

37

3.5.2 Reconfiguración del timer del kernel para obtener mayor

granularidad Otro comportamiento anómalo que se detectó tras la migración de la aplicación a la nueva

placa fue que no se cumplían los periodos configurados para las interrupciones temporales ni

los tiempos especificados para dormir procesos con la función usleep().

Averiguamos que, por definición, la resolución máxima habilitada por defecto para los

temporizadores del kernel de Linux es de 10 milisegundos. Esta circunstancia, agravada por el

hecho de que el microprocesador tiene que atender a tareas más prioritarias que lanzar una

nueva interrupción temporal o despertar un hilo, nos obligó a reconfigurar el kernel que venía

por defecto en la tarjeta SD siguiendo las instrucciones especificadas por el fabricante. A

continuación resumimos los pasos que constituyen el proceso:

1. Loguearnos como root en un PC independiente de la TS-7800.

2. Instalarnos los paquetes libncurses5-dev y libncursesw5-dev para la compilación del

kernel.

>> sudo apt-get install libncurses5-dev libncursesw5-dev

3. Descargarnos la herramienta de desarrollo para compilación cruzada del servidor FTP

de Technologic Systems.

>> wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7800-

linux/cross-toolchains/ts7800-crosstool-linux-gnueabi-

2005q3-2.tar.gz

4. Extraer en el directorio actual y borrar el antiguo tar.

>> tar xvf ts7800-crosstool-linux-gnueabi-2005q3-2.tar.gz

&& rm ts7800-crosstool-linux-gnueabi-2005q3-2.tar.gz

5. Adquirir la fuente del kernel.

>> wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7800-

linux/sources/linux-2.6.21-ts-src-oct102008.tar.gz

6. Extraer la fuente del kernel.

>> mkdir linux-2.6.21-ts && gzip -dc linux-2.6.21-ts-src-

oct102008.tar.gz | tar xf - -C linux-2.6.21-ts/

7. Movernos hasta el nuevo directorio extraído.

>> cd linux-2.6.21-ts

8. Editar el Makefile del directorio raíz del kernel para que apunte a la ruta

correspondiente a la herramienta de compilación cruzada. En nuestro caso, con la

herramienta descomprimida en el mismo directorio que el kernel, cambiamos la línea

186 tal como sigue:

Page 17: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

38

CROSS_COMPILE ?= ../arm-none-linux-gnueabi/bin/arm-none-

linux-gnueabi-

9. Editar scripts/mod/sumversion.c para incluir una nueva definición de la variable

PATH_MAX.

#define PATH_MAX 1024

10. Editar el archivo arch/arm/kconfig y modificar la frecuencia que aparece por

defecto para el temporizador.

config HZ

default 1500

11. Escribir "make ts7800_defconfig" para construir el kernel con las opciones que

Technologic Systems usa para la TS-7800.

12. Escribir "make menuconfig" y editar las opciones deseadas (para cambiar

únicamente la resolución de los temporizadores, no hay que cambiar nada).

13. Escribir “make” para construir el kernel.

14. El nuevo kernel aparece en "arch/arm/boot" en un formato comprimido

denominado zImage.

15. Copiar la imagen comprimida en la partición 2 de la tarjeta SD.

>> dd if=arch/arm/boot/zImage of=/dev/sdb2

16. Trasladar la SD a la TS-7800 y arrancar.

La máxima resolución que pudimos configurar fue de 1500MHz (667ns), puesto que todos los

intentos con valores mayores daban un error de compilación. Dedujimos que este error se

debía a las propias limitaciones del kernel, por lo que de momento habrá que conformarse con

este valor máximo permitido. Si en un futuro se detecta la necesidad de aumentar la

resolución de los tiempos, habrá que plantearse la instalación de un parche de tiempo real.

3.6 Mejoras introducidas sobre la antigua aplicación La principal limitación que nos hemos encontrado desde el principio ha sido la de la frecuencia

de trabajo de los servos. Puesto que a los servos se le debe enviar una orden cada 20

milisegundos, ésta será la frecuencia a la que debemos muestrear nuestros sensores, obtener

la acción de control correspondiente y enviarla a los cinco servos.

Es por ello que nuestros esfuerzos se han centrado en mejorar los tiempos de ejecución de las

funciones de lectura de los distintos sensores, así como en tratar de liberar al microprocesador

de la mayor carga posible. Nuestro objetivo final es que seamos capaces de realizar una

interrupción temporal cada 20 ms, que dentro de cada interrupción leamos todos los sensores

y que en función de estas lecturas calculemos las órdenes y las enviemos a los servos.

Page 18: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

39

3.6.1 Minimización de esperas activas del sensor de ultrasonidos Las esperas activas son uno de los principales problemas que encontramos en el código

original de la aplicación. Al principio, no éramos capaces de cumplir los requerimientos

temporales porque el programa se quedaba esperando repetidamente en distintos puntos de

la lectura del sensor de ultrasonidos a que cambiara su valor. Mientras se hacía esta

verificación, la CPU no podía realizar ninguna otra tarea, y como consecuencia la aplicación no

funcionaba como debía.

Para entender mejor el problema al que nos enfrentamos, explicamos con más detalle el

funcionamiento del sensor de ultrasonidos: en primer lugar, el sensor lanza un pulso de ondas

ultrasónicas que rebotan en el objeto que tiene en frente y vuelve; su salida consistirá en una

señal que se mantiene a nivel alto durante el tiempo que tarda el pulso en volver, por lo que lo

único que habrá que hacer para calcular la distancia será tomar esta señal, calcular cuánto

tiempo se mantiene a nivel alto y hacer un sencillo cálculo para obtener la distancia a partir del

tiempo.

El problema radica en el tiempo que pasamos esperando a que dicha señal deje de estar a

nivel alto. Aunque no hemos podido eliminar las esperas activas por completo por la carencia

de interrupciones hardware, hemos adoptado la siguiente estrategia para minimizar su efecto

negativo:

En una primera iteración se realiza una “calibración” del sensor de ultrasonidos. En

este caso, la espera activa es inevitable, pues no tenemos ninguna referencia del

tiempo que la señal permanecerá a nivel alto.

En sucesivas iteraciones, no tenemos que esperar al nivel bajo de la señal durante todo

el tiempo, sino que dormimos el proceso durante un periodo en el cual estamos

seguros de que la señal no va a cambiar de estado. En concreto, se ha decidido que si

en una interrupción temporal la señal se mantiene a nivel alto un cierto tiempo, en la

siguiente dicha señal se mantendrá a nivel alto como mínimo durante un tiempo igual

al 80% del tiempo anterior. Esta idea parece razonable por las propias limitaciones

físicas del helicóptero en el ascenso y el descenso. Así pues, dormiremos el proceso

durante un 80% del tiempo que tenemos como referencia, descargando en gran

medida a la CPU.

DFLOAT medida_us (void)

{

DFLOAT altura=0; // Variable que almacenará la altura

float aux1=0.0; //Variables auxiliares empleadas para el cálculo

de la altura

float aux2=0.0;

volatile unsigned int *DATAIN, *DATAOUT;

struct timeval now; //Estructura que almacena, a la vuelta de la

función gettimeofday(), los

// segundos y microsegundos

transcurridos desde la época Unix

gettimeofday(&now,NULL);

t_0= now.tv_sec * 1000000 + now.tv_usec; // Guardamos tiempo

inicial

Page 19: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

40

printf("ACTIVACIÓN DEL SENSOR\n\n");

*DATAOUT=*DATAOUT & 0xFFFB;//Ponemos un '0' en el bit 3 de DIO

*DATAOUT=*DATAOUT | 0x4; //Sacamos nivel alto por pin 3 del DIO

header durante al menos 12 us

*DATAOUT=*DATAOUT & 0xFFFB;//Ponemos un '0' en el bit 3 de DIO

printf("LECTURA DE LA SALIDA DEL SENSOR\n\n");

do

{

gettimeofday(&now,NULL);

t_ad22 = now.tv_sec * 1000000 + now.tv_usec;

} while(!(*DATAIN & 0x10)&& (t_ad22-t_0) <= 2000);// Cuando se

detecta el nivel alto o sobrepasamos el tiempo establecido,

continuamos

//Aquí está la estrategia del usleep

if ((t_us>0) && (t_us<9000)&& (t_ad22-t_0) <= 2000) // No tiene

sentido t_us>9000 (altura>2m) -> La lectura anterior fue errónea

{

usleep((int)(0.6*t_us)); //Si pongo un porcentaje más alto

corro el riesgo de dormir más de la cuenta

printf("\nt_us= %d\n",t_us);

}

else

{

if(t_us!=0)

{

printf("\nEl valor de t_us no es válido\n");

}

}

do

{

gettimeofday(&now,NULL);

t_ad23 = now.tv_sec * 1000000 + now.tv_usec;

} while((*DATAIN & 0x10)&& (t_ad23 -t_0 <=11000)); // Contamos

mientras la señal del sensor esté a nivel alto y no hayan transcurrido

11ms

printf("\nCALCULO DE LA ALTURA\n\n");

aux1=(331.0+(calibracion)*0.6); // Vsonido(m/s) = 331.0 + T(ºC)*0.6

aux2=((t_ad23-t_ad22)/2000000.0);

altura = aux1 * aux2; // ALTURA(m) = (TIEMPO(s)/2)*Vsonido

(m/s)

if((t_ad23-t_0>11000)||(t_ad22-t_0>2000))

{

altura = 0; // Tomaremos la altura nula como dato erróneo

printf("\n ALTURA ERRÓNEA. Timeout.\n");

t_us=0;

}

else

{

t_us=t_ad23-t_ad22; //Guardamos el tiempo que ha tardado en

volver el eco para dormir el hilo la siguiente ejecución

}

printf("Tiempo desde activacion sensor hasta inicio recepcion eco:

Page 20: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

41

%u \n Duracion del eco: %u\n",t_ad22-t_0,t_ad23-t_0);

return altura;

} // Fin de la función medida_us()

Tabla 12: Código de muestra de la estrategia de minimización de esperas activas del sensor de ultrasonidos

3.6.2 Mejora de tiempos de lectura de la IMU Superado el problema de las esperas activas, la siguiente limitación, que dificultó

considerablemente nuestra tarea, fue la del tiempo que se tardaba en realizar las lecturas de la

IMU.

De los 20 ms disponibles para cada interrupción temporal, la lectura de la IMU consumía un

tiempo comprendido entre 9 y 13 ms. Teniendo en cuenta el resto de tareas que deben

incluirse dentro de una interrupción (lectura del resto de sensores, cálculo y envío de las

señales de control y envío en tiempo real a tierra o escritura en cola de los datos de los

sensores), este tiempo resultaba excesivo.

Nuestra primera idea fue la de emplear un hilo para leer cada uno de los sensores para que las

lecturas pudieran hacerse en paralelo y que dispusiéramos de los datos de todos los sensores

para calcular las órdenes y enviarlas lo antes posible.

Sin embargo, esta estrategia no funcionó porque, aunque dividiéramos el proceso en hilos, el

microprocesador estaba demasiado ocupado comprobando si la lectura de la IMU estaba lista

durante casi todo el tiempo disponible (13 ms apróx.), de manera que el hilo de la IMU

provocaba el bloqueo del resto de los hilos.

Ante esta nueva limitación, decidimos entrar en detalle en las librerías proporcionadas por el

fabricante de la IMU para tratar de mejorar sus tiempos de lectura. Dentro de dichas librerías,

averiguamos que la función empleada para comprobar si la IMU tiene datos disponibles para

ser leídos es select(), cuyo prototipo es el siguiente:

int select(int n, fd_set *readfds, fd_set *writefds, fd_set

*exceptfds, struct timeval *timeout);

En función del valor que se le pase como timeout (tiempo máximo a esperar desde que

select() comienza su ejecución hasta que devuelve el control), la función tiene tres modos de

funcionamiento distintos:

Si timeout es NULL, la función queda en espera indefinida.

Si timeout es una estructura de tiempo de tipo timeval con los segundos o los

microsegundos distintos de cero, espera un tiempo especificado.

Si timeout es una estructura de tiempo de tipo timeval con los segundos y los

microsegundos iguales a cero, no se produce espera (testeo y retorno).

Comprobamos que, originalmente, se le pasaba un cierto valor en el timeout, así que no sólo

se comprobaba si había algún dato disponible en el buffer de la IMU, sino que se bloqueaba

durante un cierto tiempo en el select() realizando otras comprobaciones.

Page 21: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

42

De acuerdo con nuestras necesidades, decidimos que era preferible que en alguna

comprobación aislada la IMU no tuviera datos en su buffer y nos diera errores de lectura a

invertir en cada interrupción más tiempo del estrictamente preciso para ver si había datos

disponibles. Así pues, pasándole a la función select() como parámetro timeout un puntero a

una estructura de tipo timeval con los segundos y microsegundos a cero, los tiempos de

lectura de la IMU se reducen a menos de 2 milisegundos, y apenas se aprecian pérdidas de

datos a lo largo de toda la ejecución.

3.7 Recalibración de los potenciómetros La alimentación de los potenciómetros tras la adquisición de la nueva placa y el rediseño de la

caja aviónica pasa a ser de 5 V en vez de los 10 V originales, por lo que se cree conveniente

realizar una nueva calibración.

Supondremos que la característica de ambos potenciómetros es aproximadamente lineal, por

lo que la calibración consistirá simplemente en asociar el valor de impedancia que presenta el

potenciómetro con la magnitud que se esté midiendo según el sensor: la altura del helicóptero

o el ángulo de paso colectivo.

En ambos casos la estrategia adoptada es la misma:

En primer lugar, medimos la impedancia a la salida del potenciómetro para un

conjunto de valores de altura del helicóptero o de ángulo del colectivo, según proceda.

A continuación, formamos una tabla de valores x e y con el programa Microsoft Excel y

calculamos los coeficientes m y b de la recta de regresión (y=b+m*x).

Realizamos una calibración inicial del potenciómetro para conocer su ángulo de giro al

comienzo de los experimentos con el helicóptero.

o Medimos la tensión a la salida del potenciómetro de altitud en la posición

inicial del helicóptero: 0.16 cm.

o Medimos la tensión a la salida del potenciómetro de paso colectivo en la

posición inicial del rotor principal: 0 grados.

3.7.1 Calibración del potenciómetro para medida de la altura del

helicóptero Los valores de altura para los que se ha medido la impedancia presentada por el

potenciómetro son los mostrados en la Tabla 13. En dichos cálculos se ha tenido en cuenta que

el potenciómetro es de 10 K y está alimentado a 5 V.

Altura (cm) Impedancia (K) Tensión (V)

16 4.8 2,41

21 4.76 2,38

26 4.66 2,33

31 4.58 2,29

36 4.52 2,26

Page 22: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

43

41 4.44 2,22

46 4.36 2,18

51 4.26 2,13

Tabla 13: Valores de calibración del potenciómetro para medida de la altura

A partir de los valores anteriores, formamos la nube de puntos representada en la Figura 28

con el programa Microsoft Excel, que calcula la recta de regresión trazada en color negro.

Figura 28: Calibración del potenciómetro para medida de la altura

Ahora bien, la recta de regresión obtenida únicamente se cumple cuando el potenciómetro se

coloca con los mismos ángulos por los que ha pasado a lo largo de la calibración para las

alturas correspondientes. Para no tener que preocuparnos de la posición con que coloquemos

el eje de giro del potenciómetro cada vez que realicemos un experimento, nos quedamos con

la pendiente obtenida (m=-1.216), y reescribimos la ecuación para incluir una calibración al

comienzo de cada experimento consistente en medir la tensión que saca el potenciómetro

para la altura inicial de 0.16 m.

) (Ecuación 3.1)

3.7.2 Calibración del potenciómetro para medida del ángulo de paso

colectivo Los valores del colectivo para los que se ha medido la impedancia presentada por el

potenciómetro son los mostrados en la Tabla 14. En este caso, la alimentación también es de 5

V, mientras que el potenciómetro es de 1K.

Page 23: 3 SUSTITUCIÓN DE ORDENADOR DE A BORDObibing.us.es/proyectos/abreproy/70354/fichero... · Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz 24 3.2 TS-7800 de Technologic

Capítulo 3: Sustitución de Ordenador de a Bordo Blanca Rubio Díaz

44

Ángulo de paso colectivo () Impedancia () Tensión (V)

12 544 2,72

6 650 3,25

3 674 3,37

0 724 3,62

-3 759 3,795

Tabla 14: Valores de calibración del potenciómetro para medida del paso colectivo

A partir de los valores anteriores, formamos la nube de puntos representada en la Figura 29

con el programa Microsoft Excel, que calcula la recta de regresión trazada en color negro.

Figura 29: Calibración del potenciómetro para medida del colectivo

De la expresión de la recta de regresión, nos quedamos de nuevo con la pendiente calculada:

m=-13.93. Para el cálculo del ángulo del colectivo a partir de la tensión que saca el

potenciómetro en un momento dado, necesitamos conocer tanto m como la tensión que saca

el potenciómetro para el ángulo de referencia, que será de 0.

(Ecuación 3.2)