martes, 21 de abril de 2015

Microchip PIC: I2C + BH1750 + PIC24F32KA301 + XBEE

En este capítulo, vamos a mostrar como configurar el módulo INTER-INTEGRATED CIRCUIT, en otras palabras, el bus I2C, y para ello, hemos escogido al microcontrolador PIC24F32KA301.

La idea de este programa es leer cada tres segundos el dispositivo externo BH1750 ( del fabricante ROHM ) y enviar el dato leído por el módulo UART para que pueda ser representado por pantalla.

Dicho dispositivo, BH1750, presenta un bus de comunicaciones I2C y ofrece la cantidad de luz ambiente donde el sensor está presente en Lux ( unidad de medida de la cantidad de luz en un sitio concreto ).


Y antes de presentar el código fuente, vamos a repasar de forma breve, como podemos configurar el módulo I2C de nuestro microcontrolador para que podamos establecer una comunicación con el dispositivo externo BH1750.


En el bus I2C, solo es necesario dos pines de nuestro microcontrolador: SDC ( pin de datos ) y SCL ( pin reloj del bus ), generalmente, existen dos velocidades establecidas para trabajar con este bus:


· Velocidad estándar:100 kHz
· Velocidad rápida:400 kHz


Y para ello, Microchip nos pone a nuestra disposición una expresión matemática para ajustar la velocidad de reloj del bus I2C que vamos a emplear, dicha expresión es la siguiente:


f_SCL = F_CY/[ I2CxBRG + 1 + F_CY/10000000 ]


Donde:

· f_SCL  ≡  Velocidad del reloj para el bus I2C.
· F_CY ≡ Frecuencia de ciclo de instrucción, para éste microcontrolador PIC, F_CY = f_OSC/2.
· I2CxBRG  ≡ Carga del registro I2CxBRG que satisface la velocidad del bus deseada.


Tanto los valores f_SCL como F_CY son conocidos de antemano, lo que nos interesa es saber el valor de I2CxBRG, un ejemplo práctico, tenemos el reloj principal a 32 MHz y queremos un f_SCL de 400 kHz, vamos a calcular con que valor debemos cargar al registro I2CxBRG :


400 kHz = ( 32/2 MHz )/[ I2CxBRG + 1 + ( 32/2 MHz )/10000000 ]


Despejamos en parámetro que nos interesa:


· I2CxBRG  37.4 = 37 ( 0x25 )


Como podemos observar, el valor no es exacto, esto quiere decir que tendremos un error, vamos a calcular el error que cometeremos en esta configuración:


· f_SCL Deseado =  400 kHz
· f_SCL Real =
 ( 32/2 MHz )/[ 37 + 1 + ( 32/2 MHz )/10000000 ] ≈ 404.04 kHz 


Por lo tanto, el error cometido será el siguiente:


%Error = [ ( f_SCL Real - f_SCL Deseado )/f_SCL Deseado ]·100 = ( 404.04 - 400 )/400 ≈ 1.01%


Bien, llegados a este punto, ya sabemos calcular el f_SCL para nuestro módulo I2C, solo decir una cosa más, hay que prestar especial atención al registro I2CxBRG, ya que es un registro de 8-bits. ¿Qué quiere decir esto? Pues si nuestro valor calculado es mayor a 256, la f_SCL que queremos generar NO es posible.



Y ya sin más dilación, vamos a presentar nuestro programa, éste consistirá en realizar lecturas de luz ambiente, en Lux, ofrecidas por el dispositivo externo BH1750 cada, aproximadamente, 3 segundos y enviar dicha lectura por la UART al PC para que se represente, y para hacerlo más vistoso, lo vamos a hacer de forma inalámbrica, con un par de módulos XBee.

Así que en nuestro ordenador tendremos un módulo XBee ( será el Coordinador ) y en nuestro protoboard tendremos al PIC24F32KA301 conectado al dispositivo externo BH1750, y otro módulo XBee ( será End Device ) conectado al pin Tx de la UART.

En este ejemplo, no vamos a recibir nada, así que solo nos interesa el pin de transmisión de datos Tx.



El material que vamos a necesitar y su función, es la que se muestra a continuación:

· PIC24F32KA301: Microcontrolador para este programa.

· Protoboard: Donde insertaremos nuestros componentes.

· PICKIT 3: Programador y depurador necesario para programar el código.

· Módulos XBee: Un par de ellos, en este caso, el módulo XBee es el modelo: XB24-ZB.

· Interfaz Gráfica: Software que se ejecuta en un ordenador con independencia del sistema operativo, solo es necesario tener instalada la máquina virtual de JAVA con al menos, la versión 7 Update 45 o superior. Dicha interfaz gráfica se puede descargar más adelante junto al Firmware.

· BH1750: Dispositivo BH1750 que nos ofrece la cantidad de luz donde el sensor está presente en Lux.

· Resistor 4.7 kΩ: Un resistor que irá conectado entre los pins #MCLR y VDD.



El firmware es el que se muestra a continuación:

/**
* @file       main.c
* @author     Manuel Caballero
* @date       30/3/2015
* @brief      Archivo principal.
* \copyright
*      AqueronteBlog@gmail.com
*
* Este archivo es propiedad intelectual del blog Aqueronte,
* cuya direccion web, es la siguiente:
*
*     http://unbarquero.blogspot.com/
*
* Se permite cualquier modificacion del archivo siempre y cuando
* se mantenga la autoria del autor.
*/
#include < xc.h >
#include < stdint.h >
#include "variables.h"
#include "functions.h"
#include "interrupts.h"
#include "BH1750.h"


/**
 *  \brief     void main( void )
 *  \details   Este programa consiste en leer datos de luz ambiente procedentes
 *             del dispositivo externo BH1750 ( bus I2C ) y enviar dichos datos
 *             por la UART cada aproximadamente 3 segundos.
 *
 *
 *             Este programa se ha probado con un par de módulos XBee modelo
 *             XBee XB24-ZB ( uno Coordinator y el otro End Device ).
 * 
 *
 *  \author    Manuel Caballero
 *  \version   0.0
 *  \date      5/4/2015
 *  \pre       Este firmware está probado para el PIC24F32KA301.
 *
 *  \pre       MPLAB X IDE v2.35.
 *  \pre       Compiler XC16 v1.22.
 */
void main( void ) {

   uint16_t   aux =   0;

   conf_CLK   ();     // Configura Relojes
   conf_IO    ();     // Configura Pins
   conf_UART  ();     // Configura UART
   conf_I2C1  ();     // Configura I2C 1
   conf_TA1   ();     // Configura Timer 1

    
   while ( 1 )
   {
     // BAJO CONSUMO
     Sleep ();

     if ( opCont ==  1 )
     {
     // PETICIÓN DE CONVERSIÓN LUX
        BH1750_write   ( BH1750_ADDR_H, BH1750_ONE_TIME_HIGH_RES_MODE );
     }
     else if ( opCont == 2 )
     {
     // LECTURA DE DATOS LUX DESDE EL DISPOSITIVO EXTERNO BH1750 Y ENVÍO DE DATOS POR LA UART
        aux  =   BH1750_read    ( BH1750_ADDR_H );

        // Envía datos por la UART
        U1TXREG  =   ( aux >> 8 );
        while ( U1STAbits.TRMT == 0 );

        U1TXREG  =   aux;
        while ( U1STAbits.TRMT == 0 );
     }
   }
}

Como vemos, el ejemplo es bastante simple, se recomienda bajar los archivos disponibles más abajo para indagar entre sus librerías y leer sus funciones de manera más detallada.

Un vídeo que demuestra lo explicado anteriormente se presenta a continuación:



Os pongo a vuestra disposición el programa en lenguaje C (XC16 y CCS) para que lo podáis descargar y probar:

Microchip PIC: PIC24F32KA301 + BH1750 + I2C + XBee
Compilador XC16Compilador CCS
CC
PIC24F32KA301: BH1750 + XBee 
PIC24F32KA301: BH1750 + XBee
PIC24F32KA301: BH1750 + XBee
PIC24F32KA301: BH1750 + XBee


Podéis encontrar el código completo en nuestro repositorio GitHub:

·AqueronteBlog GitHub.


· NOTA 1: Lo comentarios están en formato doxygen. Aunque no se entrega dicha documentación ya que el MPLAB X no tiene ningún pulgin capaz de trabajar con dicho formato.

· NOTA 2: En caso de ejecutar el software UART.jar y no inicializarse, es debido a que las librerías no están instaladas debidamente. El software utiliza librerías externas como por ejemplo, para el manejo del puerto serie, dicha librería debe instalarse a mano. En el siguiente enlace hay una breve guía de como hacerlo: Instalar librerías RXTX.

· NOTA 3: El software UART.jar se ha probado satisfactoriamente en Windows 8.1 ( 64-bits ) y Windows XP ( 32-bits ). Si usáis otro sistema operativo y habéis instalado las librerías correspondientes a vuestro sistema operativo, os pediría que en el apartado de comentarios, me indiquéis si funciona o no.

0 comentarios: