Sensor de Temperatura y programa final con la Raspberry Pi:

MANEJO SENSOR TC74:

El sensor tiene un encapsulado tipo TO220:

sensor

Con los pines correspondiente a la comunicación I2C:

  • SDA: datos
  • SCL: reloj
  • GND: tierra
  • VDD: alimentación (3,3 V)
  • NC: No conectado

Comunicación I2C:

El bus I2C, es un estándar que facilita la comunicación entre microcontroladores, memorias y otros dispositivos con cierto nivel de “inteligencia”, que requiere de dos líneas, una de señal y otra de masa.

La metodología de comunicación de datos del bus I2C es en serie y síncrona. Una de las señales del bus marca el tiempo (pulsos de reloj) y la otra se utiliza para intercambiar datos.

Descripción de las señales

    • SCL (System Clock) es la línea de los pulsos de reloj que sincronizan el sistema.
    • SDA (System Data) es la línea por la que se mueven los datos entre los dispositivos.
    • GND (Masa) común de la interconexión entre todos los dispositivos “enganchados” al bus.

Las líneas SDA y SCL son del tipo Open Drain, es decir, un estado similar al de colector abierto, pero asociadas a un transistor de efecto de campo (o FET). Se deben polarizar en estado alto (conectando a la alimentación por medio de resistencias de “pull-up”) lo que permite conectar en paralelo múltiples entradas y salidas.

Protocolo de comunicación del bus I2C:

Habiendo varios dispositivos conectados al bus, es lógico que para establecer una comunicación a través de él se deba respetar un protocolo. Para ello clasificamos los dispositivos conectados al bus en dos tipos:

  • maestros
  • esclavos

Sólo los dispositivos maestros pueden iniciar una comunicación.

La condición inicial, de bus libre, es cuando ambas señales están en estado lógico alto. En este estado cualquier dispositivo maestro puede ocuparlo, estableciendo la condición de inicio (start). Esta condición se presenta cuando un dispositivo maestro pone en estado bajo la línea de datos (SDA), pero dejando en alto la línea de reloj (SCL).

El primer byte que se transmite luego de la condición de inicio contiene siete bits que componen la dirección del dispositivo que se desea seleccionar, y un octavo bit que corresponde a la operación que se quiere realizar con él (lectura o escritura).

I2C

Si el bit de lectura/escritura (R/W) se pone a nivel lógico bajo (escritura), el dispositivo maestro envía datos al dispositivo esclavo. Esto se mantiene mientras continúe recibiendo señales de reconocimiento (ACK), y la conexión concluye cuando se hayan transmitido todos los datos.

El dispositivo maestro puede dejar libre el bus generando una condición de parada (stop).

Configurar Buildroot para poder usar la comunicación I2C:

Para poder usar conexiones I2C, el sistema embebido debe tenerlo activado, y tener las librerías o herramientas necesarias para manejarlo, por tanto, rehacemos la configuración del Buildroot que hicimos, y le indicamos en la parte de Hardware Handling, que nos añada la librería de i2c-tools, como aparece en la siguiente imagen:

Buildroot

Y guardamos los cambios, a continuación escribimos el comando make linux-menuconfig y habilitamos lo relativo a los drivers y al bus de comunicación I2C, como aparece en la  siguiente imagen:

linux kernel

Una vez hechos los cambios anteriores, volvemos a escribir el comando make, para que se queden aplicados.

configtxt

Ya tenemos listo todo lo relacionado con el i2c y el sensor, por lo que lo conectamos, y comprobamos con los siguientes comandos que recibimos la temperatura medida correctamente:

Primero escribimos el comando i2cdetect –l

Y nos lista todos los dispositivos i2c conectados.

En nuestro caso el que nos interesa es el i2c-1

(Ese 1 puesto que por defecto en la versión B de la Raspberry Pi es el que se le asigna), y si todo ha ido bien debemos recibir una respuesta como la siguiente:

i2cdetect

Donde el 0x4d representa la dirección de nuestro dispositivo i2c, la que se le asigna a  nuestro sensor, y el 1 mencionado anteriormente corresponde al busI2C a utilizar.

Ahora que sabemos dicha dirección mandamos el comando 0x00 a nuestro sensor, que es el que le indica que haga una lectura.

Comando: i2cset 1 0x4d 0x00

i2cget

Tras confirmar con una Y la pregunta que se nos formula, sobre si queremos escribir en el fichero /dev/i2c-1,  escribimos el siguiente comando: i2cget 1 0x4d
que nos devuelve la temperatura medida por el sensor en grados C, volvemos a confirmar con Y a la pregunta de si queremos leer del fichero /dev/i2c-1sobre el que escribe el sensor.

i2cset

Ahora pasamos a hacer esta misma función de leer la temperatura pero con un programa en C realizado desde Eclipse y compilado de manera cruzada para poder ejecutarlo en la Raspberry Pi.

En el programa además en el main añadimos un while(1) para que se esté ejecutando continuamente y cada vez que se lea una medida, el proceso se duerma (sleep(1)) durante los segundos que queramos, en este caso 1, y tras despertarse vuelva a realizar otra medida.

A continuación os dejamos el código fuente del programa:

test1

test2

PONER EN HORA LA RASPBERRY PI:

Para configurar correctamente la hora de la Raspberry Pi, una vez que la tenemos conectada con el ordenador, escribimos en un terminal el siguiente comando:

date –help

Y nos aparecerán las distintas opciones que tiene el comando date:

hora1

Por tanto vemos que utilizando el comando date –s seguido de la fecha y hora que queremos pasarle a la Raspberry Pi en el formato YYYY.MM.DD-hh:mm, conseguimos darle la hora y fecha correctas:

hora2

INTEGRACIÓN DEL SENSOR I2C CON LA PANTALLA TÁCTIL EN LA RPI:

Usando de nuevo el programa de Workshop4 de 4DSystems hacemos dos interfaces para la pantalla, a estas interfaces se les llama Form0 y Form1. Para ello en la barra de objetos seleccionamos la opción indicada:

workshop1

En la pantalla Form0 añadimos los objetos:

  • Angularmeter0: Se utiliza para mostrar la temperatura medida en el sensor. Para ello la RPI lee la temperatura del sensor y se lo envía al Angularmeter.
  • Leddigits0: Muestra el umbral de temperatura seleccionado con el Knob0, y envía este umbral a la RPI. Para ello tenemos que configurar el evento a “Report Message”.
  • workshop2
  • Userled0: Se ilumina cuando la temperature medida supere el umbral seleccionado.
  • Knob0: Es el dial utilizado para seleccionar el umbral y lo envía al Leddigits0 para que lo muestre. Para ello hay que configurar el evento para que cuando cambie su valor, envíe dicho valor al objeto Leddigits0.
  • workshop3
  • 4DButton0: Con este botón se cambia a la otra pantalla. Para ello se configura el evento de la siguiente forma:

workshop4

  • Statictext0: Se utiliza para dar nombre al indicador Userled0.

workshop5

Para la pantalla Form1 se añaden los siguientes objetos:

  • Leddigits1: Muestra la hora y los minutos que le envía la RPI.
  • Leddigits2: Muestra los segundos que recibe de la RPI.
  • Strings0: Muestra en formato texto la temperatura medida del sensor.
  • 4DButton1: Cambia a la pantalla Form0. Para ello se configura el evento de la siguiente forma:

workshop6

workshop7

Con esto se termina de programar la pantalla, ahora vamos con el programa en C, que se ejecutará en el sistema embebido de la RPI.

app_sensor1

app_sensor2

app_sensor3

app_sensor4

app_sensor5

En el programa en C, añadimos entre otras, la librería correspondiente a la pantalla, y una librería que nos permita manejar y crear hilos (threads):

app_sensor6

A continuación definimos las siguientes variables globales:

  • Temperatura, de tipo entero que almacenará el dato recibido del sensor TC74
  • umbral: de tipo entero también, almacenará el valor recibido del dial manejado desde la pantalla táctil. Si la temperatura medida es mayor a este umbral, saltará la alarma.
  • t: es una estructura de tipo time_t, estructura ya definida en time.h y que almacena los valores de tiempo del sistema, estos valores se devuelven desde la función time().
  • msgtemp[50]: Es un array de tipo de char de 50 elementos, que nos permite almacenar la variable temperatura (que era un entero) en una cadena de char, para poder mostrarla en formato texto por la pantalla táctil
  • timestr: es un puntero a un char que nos permite llamando a la función ctime() convertir a una cadena de caracteres los datos temporales vistos antes, y así mostrarlos por los objetos leddigits de la pantalla.

Una vez definidas las variables globales, y añadidas las cabeceras necesarias al programa, declaramos varias funciones:

  • void get_temp_sensor(void):

Nos permite actualizar la temperatura medida del sensor, y guardar el resultado en la variable temperatura, para ello, necesitamos saber la dirección i2c donde está conectado el sensor, (en nuestro caso la 0x4d, como ya se explicó y demostró en puntos anteriores de este documento).

Además necesitamos acceder al fichero /dev/i2c-1, como también se explicó anteriormente, puesto que es donde escribe el sensor, y por tanto de donde obtenemos la medida de temperatura. Por tanto en esta función abriremos el archivo, y gestionaremos los errores que puedan producirse en este paso:

app_sensor7

Y a continuación leemos del fichero el dato que nos interesa y convirtiéndolo a un entero, lo almacenamos en la variable temperatura, mientras no se produzcan errores al leer del bus i2c:

app_sensor8

Después escribimos el comando 0x00 en el buffer que mandamos por el bus i2c. Este comando es el que le manda al sensor i2c que realice una medida:

app_sensor9

  • static void *handleAngularMeter(void *data):

Es la función del controlador del angularMeter de la pantalla

touchscreen1

La primera línea de esta función es un for(;;), es decir un bucle infinito, para que esté funcionando continuamente, pero para que no consuma todos los recursos de la cpu, dormimos durante medio segundo a dicha función con un usleep(500000), que aparece al final de esta función.

En cuanto a las acciones principales de esta función, llama a la función anterior get_temp_sensor(), para obtener la temperatura, y mediante la función genieWriteObj (…) que proporciona la cabecera geniePi.h, conseguimos representar en el angularMeter de la pantalla, la temperatura pasándole a dicha función como argumentos, el objeto sobre el que queremos escribir, en nuestro caso GENIE_OBJ_ANGULAR_METER, el índice de dicho objeto, para nosotros 0x00, pues solo tenemos un angularMeter, y el dato que queremos representar, en nuestro caso la variable temperatura.

touchscreen2

Después comprobamos si la temperatura medida ha superado el umbral, pues en caso afirmativo, actualizamos también de la misma manera, es decir con la función genieWriteObj y los argumentos correspondientes, el led de la alarma, o en caso de que estuviera encendida, y ya estemos por debajo del umbral, apagamos la alarma:

touchscreen3

Ahora pasamos la temperatura a formato texto, para escribirla en el objeto Strings0 de la segunda pantalla, para ello usaremos la función genieWriteStr(…), y como argumentos le pasamos el índice de dicho string, en nuestro caso el 0x00, y el texto a mostrar en nuestro caso la cadena msgtemp ya comentada antes, y dormimos la función durante medio segundo:

touchscreen4

  • static void *handleTime(void *data):

La siguiente función es el controlador del reloj, que comienza y termina de la misma manera que la anterior, porque también necesitamos que esté funcionando continuamente (for(;;)) pero que acaparé todos los recursos de la cpu, por lo que tenemos que dormirla (usleep(500000)) una vez que actualicemos lo que nos interese.

Para obtener la hora del sistema, utilizamos la funcion localtime(), y para pasarla a formato texto, la función ctime(), que nos almacena la fecha actualizada en la cadena de caracteres timestr con el siguiente formato:

touchscreen5

Donde www corresponde a las primeras letras en inglés del día de la semana correspondiente, mmm, son las primeras letras en inglés del mes correspondiente, dd es el día del mes, así como hh es la hora en formato 24 horas, mm, los minutos, ss los segundos, y yyyy el año correspondiente.

Por tanto, y teniendo en cuenta que el índice de los arrays empieza en 0, accediendo a las posiciones 11 y 12, de timestr, obtenemos las dos cifras de la hora, y con las posiciones 14 y 15 las de los minutos.

Sin embargo, y puesto que necesitamos que dichos caracteres ASCII se visualicen como números decimales en los dígitos, le restamos 48 a cada uno de los caracteres, como el número de posiciones entre el símbolo ASCII correspondiente, y el valor decimal con el que coincide.

ascii

Después tenemos que multiplicar la cifra de las decenas de la hora, por 1000 puesto que tenemos que desplazarla tantas posiciones como 0´s de ese 1000 a lo largo de las cifras de los dígitos de los leds, y así sucesivamente con el resto de cifras.

codigo1

Lo mismo ocurre con los segundos, solo que ahora es sobre el objeto leddigits2 sobre el que debemos escribirlos y no sobre el 1.

codigo2

  • void handleGenieEvents(struct genieReplyStruct * reply):

Es la función encargada de controlar los eventos que se producen en los demás objetos de la pantalla, por tanto tiene que estar continuamente comprobando si se ha reportado algún evento, y si es así debe comprobar si el evento ha sido que se ha girado el dial que seleccionaba la temperatura umbral, es decir, comprueba si ha sido el objeto Knob0 el que ha generado el evento, y si es así guarda el dato reportado en la variable umbral.

En caso de que se produzca un error, informa de ello.

codigo3

  • main():

Es la función principal del programa, donde declaramos la estructura reportada en la función anterior, así como creamos los dos hilos que manejarán el controlador del AngularMeter, y el del reloj, por lo que irán asociados con las correspondientes funciones de handleAngularMeter, y handleTime, respectivamente y de manera que parezca que el programa funciona de forma concurrente, es decir “simultáneamente” para el usuario.

A continuación y una vez arrancado el programa informa por el monitor de que el programa está funcionando y que se pulse Ctrl + C para salir.

Después configura la velocidad de transmisión con la pantalla, dándole un baudrate de 115200, que debe coincidir por tanto con el que indicásemos al configurar la pantalla con el programa workshop4DSystems.

codigo4

Por último y de manera continua, chequea si se producen eventos en los distintos objetos de la pantalla,  en cuyo caso llama a la función handleGenieEvent() que los gestiona, y se duerme durante 10 ms.

codigo5

Con esto acaba el programa, una vez que lo compilamos de manera cruzada para la arquitectura arm correspondiente a la Raspberry Pi, ya explicado en puntos anteriores de este documento, copiamos los ficheros del proyecto a la tarjeta SD que introduciremos en la Raspberry Pi, y desde la que con el comando ./ seguido del nombre de nuestro ejecutable del programa conseguiremos arrancarlo, y obtener el programa funcionando como aparece en las siguientes imagenes:

running

final

final2

Bibliografía:

http://es.wikipedia.org/wiki/Sistema_embebido

http://es.wikipedia.org/wiki/I%C2%B2C

http://www.4dsystems.com.au/product/4D_Workshop_4_IDE/

http://www.raspberrypi.org/quick-start-guide

http://www.raspberrypi.org/faqs

http://www.raspberrypi.org/

Datasheet sensor:

http://ww1.microchip.com/downloads/en/DeviceDoc/21462D.pdf

Comunicación I2C:

http://elinux.org/Interfacing_with_I2C_Devices

http://robots-argentina.com.ar/Comunicacion_busI2C.htm

Programa final:

http://es.wikipedia.org/wiki/Time_t

http://www.cplusplus.com/reference/ctime/tm/

http://www.cplusplus.com/reference/ctime/ctime/

Primera Aplicación con la Raspberry Pi

APLICACIÓN PARA MEDIR TEMPERATURA CON UN SENSOR:

Para realizar la aplicación, se utiliza un sensor TC74 que mide la temperatura ambiente con una resolución de 1ºC, y permite conectarnos a él mediante I2C. Además dicha temperatura se mostrará en una pantalla táctil (modelo uLCD-43PT-PI). Esta pantalla se configura mediante un programa 4D System IDE workshop, que puede descargarse del siguiente enlace:

http://www.4dsystems.com.au/product/4D_Workshop_4_IDE/

CREACION DE LA APLICACIÓN PASO A PASO:

Tras haber creado un nuevo proyecto del tipo Visi Genie, de entre las 4 opciones que el programa nos indica, y habiéndole indicado el modelo de pantalla que vamos a usar, procedemos a añadir los elementos que queramos que se visualicen y formen nuestra interfaz.

Estos objetos son sensibles a acciones (tocar la pantalla, desplazar el dedo…)  que generan eventos, que se dividen en varios tipos:

  • On changing : avisa cuando esta cambiando
  • On changed: avisa cuando ha cambiando

objectInspector

Una secuencia de ejemplos de estos eventos y su interacción con la Raspberry Pi podría ser la siguiente:

pantalla1

El usuario desliza el lápiz sobre la pantalla táctil, provocando un evento sobre esta que se transmite a la Raspberry, que lo procesa, y le envía nueva información a la pantalla táctil que acaba mostrando ese cambio en un nuevo objeto de la pantalla, y a su vez la Raspberry en un proceso paralelo al anterior, envía información al “cool gauge” que desliza su aguja para ajustarse al valor recibido.

Por tanto para adaptar nuestra interfaz de la pantalla vamos a la barra de herramientas:

pantalla2

Y elegimos de entre los objetos que ya proporciona creados el programa los que nos interesen y los arrastramos a la pantalla simulada, que representa nuestro propio LCD. Los colocamos de manera gráfica en el orden que queramos, y les vamos asignando tamaños, colores, y propiedades, entre ellas los tipos de eventos que tendrá asociado cada objeto de los nombrados anteriormente.

pantalla3

pantalla4

El programa además proporciona una herramienta para analizar los mensajes entre la raspberry y el ordenador, cuando alguno de los eventos configurados ocurre. Esta herramienta se llama GTX Tool.

Pantalla5

Los mensajes en verde representan los que son transmitidos por la pantalla, y en rojo los que esta recibe.

El formato de las tramas de esta comunicación es el siguiente:

Pantalla6

Pantalla7

Los mensajes reportados entre  la Raspberry Pi y el display pueden deberse a dos motivos:

  • Mensajes de eventos, ya nombrados antes
  • Mensajes sobre objetos, que son el valor devuelto al aplicar la función de lectura sobre algún objeto.

La tabla de comandos definidos en este programa es la siguiente:

Pantalla8

Resultado final de la primera prueba con el programa:

PrimeraPrueba

Creación del sistema embebido Linux optimizado para la Raspberry Pi

¿Por qué desarrollar un sistema embebido y no utilizar Raspbian o cualquier otro sistema operativo ya creado para la Raspberry?

La principal razón para ello es que cualquiera de estas distribuciones tienen instalados muchos paquetes que no nos serán necesarios, no disponen de las suficientes librerías cruzadas (que son las que nos permiten programar y compilar desde una maquina más potente, y luego ejecutar los programas en la propia placa, en este caso la RPI),  son más lentas a la hora de arrancar y consumen más recursos, entre ellos más memoria, bastante preciada en este tipo de sistemas. Por ello es más efectivo implementar un sistema embebido Linux, que optimice nuestra aplicación sobre la Raspberry.

Por tanto ahora, y antes de detallar los pasos a seguir para crear el sistema desde 0, ¿qué es un sistema embebido?

Un sistema embebido es un sistema informático y/o electrónico desarrollado para realizar una única función o pocas funciones específicas,  y generalmente con un uso en tiempo real. En el caso concreto de Linux, al ser de código abierto nos aporta una serie de ventajas o libertades:

  • Libertad de hacer funcionar el software para cualquier propósito.
  • Libertad de estudiarlo y modificarlo.
  • Libertad de distribuir tantas copias como se quiera, sin tener que pagar por ello.
  • Libertad de redistribuir copias de una versión modificada.

Por todas estas ventajas, los sistemas embebidos o empotrados están presentes en muchas de las cosas que nos rodean, como los televisores, los routers personales, o lectores de tarjetas, entre otras muchas cosas.

Partes de un sistema embebido:

  1. BSP (Board Support Package), que contiene el kernel de Linux, el bootloader, con los drivers de los dispositivos físicos de la placa a usar.
  2. Aplicaciones
  3. Sistema de integración: que une las dos anteriores, las librerías y las aplicaciones al entorno de trabajo del sistema.

Para el caso de crear un sistema empotrado Linux es altamente recomendable utilizar otra máquina con el mismo sistema operativo, pues nos evitaremos posibles problemas de incompatibilidad con las herramientas, y puesto que lo que sepamos del Linux de escritorio será fácilmente aplicable al dispositivo empotrado.

Para ello, y en caso de no tener un ordenador con Linux, creamos una máquina virtual con programas como VMWare, y le instalamos los siguientes paquetes:

paquetes

Buildroot:

Una vez instalados dichos paquetes utilizaremos una herramienta llamada Buildroot, pues es una buena alternativa para crear distribuciones Linux desde cero para dispositivos empotrados, ya que nos permite crear las distribuciones a partir  del código fuente de los paquetes a utilizar y que ofrece un gran número de posibilidades a la hora de crear distribuciones. Se basa en los comandos make y defconfig para su funcionamiento.

Permite configurar entre otros parámetros, la arquitectura a utilizar, el kernel, el bootloader (en nuestro caso uboot), permite elegir que toolchain va a usarse, si una externa o la suya previa, configurándola como paso previo a la creación de la imagen del kernel. Además nos permite elegir la ABI (Application Binary Interface), en este caso la EABI para ARM. La ABI es la que nos define como se pasan los parámetros a una función, que devuelve, y como se hacen las llamadas al sistema. Además nos permite elegir la versión de Busybox, que es un conjunto básico de programas necesarios para trabajar en cualquier sistema embebido, para manipular ficheros, para configurar el sistema, un programa de inicio, una shell. Busybox es una alternativa que nos permite integrar todo esto en un solo proyecto para que sea más fácil trabajar con ello.

Buildroot ofrece utilidades de configuración tipo Menuconfig, o Xconfig, y además todas las opciones de configuración se encuentran en un único archivo .config que puede utilizarse para recrear una distribución desde cero.

Además ofrece facilidades para añadir paquetes que no se encuentran en la distribución oficial, y genera tanto el sistema de ficheros, como las librerías cruzadas y herramientas necesarias para trabajar con la nueva distribución, evitando problemas de incompatibilidades.

Además nos permite añadir directorios y archivos al sistema de ficheros de la nueva distribución, así como ejecutar scripts de pre y post instalación.

Es totalmente libre, y lo actualizar aproximadamente cada 3 meses. Además está muy bien documentado y existen muchos ejemplos de los que ayudarnos.

Una vez que le hemos indicado al Buildroot nuestra configuración, escribiendo el comando make, esta herramienta prepara el entorno para la compilación, configura los paquetes, los descarga, compila e instala.

Configuración del Kernel de Linux:

En todas las aplicaciones de Linux embebidos, es necesario configurar el kernel con el fin de dar soporte a los diferentes dispositivos físicos y a las aplicaciones del espacio de usuario. Todas las fuentes del kernel proporcionan una configuración básica para plataformas de hardware específicas. Utilizando una plataforma de hardware comercial, probablemente encontraremos una configuración del kernel adecuada, y no tendremos que definirla.

Esta es una tarea difícil pero se puede encontrar cientos de ejemplos en Internet. El Kernel de Linux tiene un directorio con las configuraciones de hardware predefinidas. La ruta relativa es la siguiente: ” ./Documents/buildroot-2013.11/output/build/linux-1587f77/arch/arm/configs”.

Ejecutando make linux-menuconfig obtenemos una ventana de configuración como la siguiente:

kernel_config

Habilitamos las configuraciones de comunicación I2C, SPI, añadimos nuevos argumentos en el bootloader del kernel,  activamos el uso de tarjetas SD entre otros. Con ello guardamos de nuevo las configuraciones y volvemos a realizar un make, y ya deberíamos conseguir que la Raspberry bootease sin problemas.

Preparando la tarjeta SD:

Una vez realizado el make, se generarán en la carpeta buildtroot/output/image los archivos necesarios que hay que copiar en la tarjeta SD. Esta tarjeta debe estar formateada en  el sistema de archivos FAT.

tarSD

A continuación se listaran los archivos necesarios que hay que copiar a la tarjeta SD:

  • scr.uimg: Este archivo es un script para automatizar el proceso del booteado de la RPI. Este fichero no se encuentra en la carpeta image mencionada antes, sino que hay que generarlo. Después se explica este proceso.
  • bin: Es un fichero binario que utiliza la GPU al arrancar.
  • txt: Es un fichero de texto que contiene los parámetros de configuración del kernel de Linux.
  • txt: Es un fichero de texto que contiene los parámetros de configuración de la GPU.
  • dat, fixup_cd.dat y fixup_x.dat: Se utiliza para configurar la memoria RAM para que pueda ser utilizada por la GPU y la CPU. Hay variaciones de este fichero para utilizarlas en diferentes modos de arranque.
  • ext2, rootfs.ext2.gz y rootfs.tar: Estos los archivos del sistema Linux. Contiene todas las capetas y archivos del S.O. embebido que se está montando. El archivo con extensión .ext2 indica que los archivos están montados en el sistema de ficheros ext2, comúnmente utilizado en sistemas operativos basados en UNIX/LINUX. El fichero acabado en .gz es el mismo que el del extensión .ext2, solo que este está comprimido. El fichero .tar contiene los mismos ficheros del sistema operativo, pero estos están sin montar en ext2.
  • elf, start_cd.elf y start_x.elf: Es el binario que la GPU utiliza para arrancar la CPU. Existen variaciones de este fichero para poder arrancar en varios modos distintos.
  • u-boot.bin: Es el binario que utiliza la CPU para cargar la imagen del kernel de Linux.
  • uImage: Es el kernel de Linux.

Antes de copiar el fichero config.txt hay que modificar un parámetro, de modo que lo abrimos con un editor de texto plano y modificamos la línea del kernel=uImage, dejándolo como se indica en la siguiente imagen:

configtxt

Preparando script de booteo (boot.scr.uimg):

Ahora se va a preparar el script encargado del proceso del booteo de la RPI. Este script es necesario porque en el arranque hay que introducir una  serie de comandos, y de esta manera este proceso queda totalmente automatizado.

  1. En la carpeta de buildroot, hay que crear un fichero de texto llamado boot_mmc.txt. En su interior se introducen las líneas tal y como se muestran en la siguiente imagen.boot_mmc
  2. Una vez guardado el fichero boot_mmc.txt abrimos una consola de comandos y nos dirigimos a la carpeta de buildroot con el comando cd. Una vez hecho esto basta con escribir el siguiente comando:

mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n “RaspBerry Pi” -d boot_mmc.txt boot.scr.uimg

Con ello se creara un fichero llamado boot.scr.uimg, que contiene el script  hecho antes…

  1. Ahora solo hay que coger el fichero boot.scr.uimg y copiarlo a la tarjeta SD con los demás archivos.

Los comandos introducidos en este script son los siguientes:

  • mmc rescan: comprueba que hay una tarjeta de memoria SD en la RPI.
  • mmc list: este comando lista los archivos que hay en la tarjeta SD.
  • setenv bootargs console=ttyAMA0,115200n8 root=/dev/ram rw ramdisk_size=16384 initrd=0x02000000,16M: En estas líneas se indica que la consola se comunicará por el puerto serie utilizando una velocidad de 115200 baudios/s y que los archivos del sistema estarán cargados en la memoria RAM de la RPI.
  • init=/sbin/init: se indica el primer proceso que se ejecuta cuando se inicia el sistema operativo.
  • fatload mmc 0 0x01000000 uImage: con este comando se carga la imagen del kernel de Linux en la memoria RAM.
  • fatload mmc 0 0x02000000 rootfs.ext2.gz: ahora se carga n los archivos del sistema operativo a la memoria RAM.
  • bootm 0x01000000: inicia el boot.

COMPILACIÓN CRUZADA:

Es la forma de compilar una aplicación en un hardware remoto. Este tipo de compilación es utilizado para dispositivos como la RPI, ya que permite utilizar las herramientas que ofrece un ordenador potente para la construcción de la aplicación que luego se ejecutará en un hardware distinto. En nuestro caso, utilizamos la máquina con el sistema operativo Ubuntu para realizar las aplicaciones, pero a la hora de compilar, los binarios se crean para el hardware de la RPI, de manera que no vamos a poder ejecutar la aplicación en el PC.

compilacion Cruzada

Aplicación de medida de la temperatura con la Raspberry Pi

Vamos a desarrollar un tutorial para explicaros como hemos hecho un sistema embebido de Linux para la Raspberry Pi, y una aplicación utilizando una pantalla táctil uLCD-43PT de 4D Systems y un sensor i2c para medir la temperatura ambiente.

Raspberry Pi es un ordenador en una única placa de bajo coste, desarrollado en Reino Unido por la Fundación Raspberry Pi fundada en 2009, cuyo objetivo es facilitar el acceso a los ordenadores y promover la educación de adultos y niños en el campo de los ordenadores, la informática y otros temas relacionados con la misma.

No es un ordenador muy potente, (tiene más o menos la potencia de un Smarthphone de baja gama), pero su sencillez y su precio hacen que se haya extendido mucho en el mercado en poco tiempo. Uno de los campos en los que más se ha implantado es en el de la domótica ya que se reducen costes y es sencillo conectarlo con Arduino. Otra gran ventaja que ofrece es la libertad de sus sistemas operativos basados en Linux. Una de las distribuciones más sencillas es Raspbian, basada en Debian, que está orientada a la enseñanza de la informática y tiene escritorio, navegadores web (como Midori), herramientas de desarrollo como IDLE para el lenguaje de programación Python o Scratch… Además Raspbian tiene una tienda de aplicaciones, “Pi Store”, con contenidos gratuitos y de pago y ha hecho que los ingenieros se hayan puesto a crear placas compatibles, lo que ha generado una oleada de diseño de placas de código abierto para usarlas con la Raspberry Pi.

Hay varios modelos de Raspberry Pi, (el A, el B y el B+) en nuestro caso utilizaremos el modelo B que cuenta con 2 puertos USB, controlador Ethernet y 512MB de RAM.

rpi1

En esta memoria en concreto, vamos a explicar los pasos seguidos para la creación de un sistema embebido implementado en la Raspberry Pi, y que a través del sensor TC74, monitorice la temperatura de la sala y la muestre en una pantalla uLCD-43PT-PI conectada también a la Raspberry Pi.

Para comunicarnos con el sensor utilizaremos conexión i2c (Inter-Integrated Circuit o Inter-Circuitos Integrados), mientras que para utilizar la pantalla táctil se desarrollara un HMI (human machine interface, o interfaz hombre maquina).

Para ello, y por optimizar la aplicación se creará un sistema Linux empotrado para la Raspberry Pi, que nos permita utilizando menos recursos, dotar al sistema de más memoria y velocidad, centrándolo en la función concreta de medida de temperatura, para la que va a ser diseñado el sistema.

Esta aplicación podría formar parte de un sistema más complejo ubicado en lo que llamaríamos un hogar digital o automatizado.

rpi_aplicacion

Se irán subiendo más partes de este tutorial en posteriores publicaciones.