11/29/2016

Sensores I2C con PIC12LF1840

Saludos,

después de varios días debatiéndome en que nuevo post publicar. Entre otras cosas tengo novedades que comentar, partidas que publicar y alguna que otra sorpresa.  Hoy voy a volver a trabajar con Pics.
Exactamente con el PIC12F1840, es un chip pequeño de 8 pines que tiene una particularidad, tiene I2C y es una buena oportunidad de emplear este chip para hacer sensores y actuadores “inteligentes” y poderlos colgar en el mismo bus.




En la imagen podemos ver la típica configuración de un bus i2c, el maestro es el que controla la comunicación, pregunta específicamente a cada esclavo y estos responden si es menester. Si has trabajado con Arduino los sensores i2c no te serán extraños, empleando la librería Wire(), tienes ejemplos para conectar sensores. Yo recomiendo emplear la librería I2C.h  es más eficiente y más sencilla de usar, o a mí me lo parece.


Utilizando el PIC12f1840 con el programa CCS compiler hay otros muchos editores como el MPLAB,  pero el CCS tiene una forma de iniciar los proyectos que te facilita mucho la vida a la hora de iniciar un proyecto con el PicWizard.


El primer ejemplo que voy a probar es el programa blink, controlar el encendido y apagado de un Led. Es algo totalmente innecesario para controlar un led no necesitamos utilizar i2c pero es un proyecto sencillo que nos permite probar el sistema.


El main.h tiene la siguiente configuración:

#include <12F1840.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(int=16000000)

#use i2c(Slave,Fast,sda=PIN_A2,scl=PIN_A1,address=0x50,force_hw, stream=I2CS)
#define DELAY 100

#use FIXED_IO( A_outputs=PIN_A4 )
int rcv_buf[0x10];
int cmd=0xFF;

la salida PIN_A4 es donde conectaremos el led
La dirección i2c de este proyecto será 0x50.
0X50 = 01010000b



7
6
5
4
3
2
1
0

A6
A5
A4
A3
A2
A1
A0
R/W
ACK
0
1
0
1
0
0
0
0
0
2
8



El bit de menor peso se emplea para indicar si la comunicación es de lectura o escritura. El ACK es el bit de reconocimiento que  envía el receptor 0 indica ACK, 1 indica NO ACK y 2 indica colisión.

Si habéis trabajado con sensores i2c, todos tienen registros donde podemos leer/escribir o solo leer o solo escribir. Cuando empecé a realizar este proyecto tenía en mente situar una variable en una dirección de memoria donde podría escribir y modificar el estado del led. Pues bien es más simple que esto.


#int_SSP
void  SSP_isr(void)
{
 int state, incoming;
 state = i2c_isr_state(I2CS);
    if(state < 0x80) //Maestro enviando.
    {
        incoming = i2c_read(I2CS);
        if (state == 1)  { cmd = incoming; }
        else if (state > 1) { rcv_buf[state-2]=incoming;}
    }
    else if (state>=0x80)   {  i2c_write(I2CS,input(PIN_A4)); } // Master leyendo.  
}



Ahí tenéis la interrupción según el valor de state, sabremos si hemos recibido una instrucción de lectura o de escritura. Si es menor de 128 (0x80) el máster quiere escribir en memoria, y lo guardaremos en el buffer de memoria que hemos definido, diferenciamos el primer byte como cmd, pues podemos emplearlo para diferenciar programas. Si no se quiere diferenciar, se podría hacer de la siguiente forma:


if(state < 0x80)    { rcv_buf[state-1]=i2c_read(I2CS); }



El programa principal seria.




void main()
{
   enable_interrupts(INT_SSP);  //Habilita la interrupcion de entrada i2c
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_16MHZ|OSC_TIMER1|OSC_PLL_OFF,0);

   //Example blinking LED program
   while(true)
   {
      if(rcv_buf[0]==0x01)
                       {
         output_high(PIN_A4);
      }else
     {
        output_low(PIN_A4);
      }
   }
}


Si el segundo byte que enviamos es un 1 el led se encenderá, si enviamos otra cosa se apagará. Con los pics siempre me ha funcionado una prueba antes de realizar el circuito y grabar el pic, simularlo en proteus para ello creamos un maestro con el mismo tipo de pic y le añadimos dos pulsadores.






Los pulsadores se emplean para enviar la secuencia de encendido y de apagado, no me he matado mucho a hacer programa del master. Las resistencias R2 y R3 son para poner a nivel alto el bus SDA y SCL.




                #include <main.h>
                #include "iic.c"
                int1 ctrl=false;
void main()
{
   setup_oscillator(OSC_16MHZ|OSC_TIMER1|OSC_PLL_OFF,0);
   while(TRUE)
   {
     if(input(PIN_A0))
     {
        if(!ctrl){  iic_write(0x50,0x00,0x1); }
        ctrl=true;
     }
     if(input(PIN_A3))
     {
        if(ctrl){ iic_write(0x50,0x00,0x00);}
        ctrl=false;
      }
    }
 }



Empleo una librería casera para enviar el i2c, porque con la que viene en le compilar CCS no envía el ACK y la comunicación no se completa. Al finalizar este articulo os dejare los enlaces de los programas.






Para hacer la prueba en realidad he empleado como Master a una arduino  el programa  envía la orden de encendido cada 500 ms y la orden de apagado cada 500ms.


Programa de  master arduino.
Programa  blink pic.
Programa master Pic.

El Pic12F1840 funciona tanto a 3,3V como a 5.0V, esto nos permite que se adapte a cualquier sistema i2c.

Como ya os dije el blink es un proyecto de prueba, ahora toca desarrollar nuevos sensores actuadores que nos permitan liberar carga al master y potencien nuestros proyectos. Por ejemplo, un Driver para motores I2C.





A la izquierda la placa con L272M para controlar dos motores, y a la derecha la misma placa con el PIC12F1840 para controlarlo por i2c.




Aquí os muestro la placa de motores y la led conectadas por i2c al arduino que hace de master.  El led con la dirección  0x50 alimentado a 5V y el driver con dirección  0x48 alimentado a 3,3V.

Esto tiene muchas posibilidades.


Anakleto


11/10/2016

MIT app inventor 2

Saludos,

como llevo un tiempo sin publicar, tras mi “asombrosa” aplicación, que, si ha recibido visitas, pero ningún comentario… No pasa nada, yo también lo hago. Hoy os voy a comentar una herramienta online para realizar aplicaciones Android, MIT App inventor 2. Se accede mediante tu cuenta google, el entorno de trabajo puede resultar sencillo per da muchas posibilidades, para realizar algún tipo de aplicaciones.

Como siempre comento cosas relacionas con la robótica o electrónica, hoy haremos una aplicación para el móvil que nos envié la información del Giroscopio del móvil a un arduino o similar. Existen otro tipo de aplicaciones que te permiten hacer esto mismo:


Durante muchos años he empleado el Amarino para emplear los sensores de móvil a mis circuitos, bien para controlarlos o bien para tener una batería de sensores.

Las dos primeras son pasivas no puedes crear botones solo puedes crear eventos que envíen información, acelerómetro, giroscopio, compas, reloj, etc. Y siempre conexión mediante bluetooth. OscDroid es parecida, pero te permite enviar la información mediante wifi.

Pero no es de esto que tenía intención hablar, esas aplicaciones existen son gratuitas y funcionan, al menos me funcionaban hasta la actualización de mi Android. Pero eso es otra historia. Con App inventor 2 , podremos hacer menús, visualizaciones y procesos, aparte de enviar la información por bluetooth o vía web. Esta última opción aun no la he explorado.

Para comenzar una nueva aplicación nos vamos Layout y seleccionamos el Grid que más se ajuste a nuestra necesidad, si queremos poner tres label, con sus valores numéricos para mostrar en la pantalla los valores del giroscopio, ponemos una matriz de 3x2. Estas matrices pueden estar dentro de otras, hay mucha información, videos y tutoriales. El aspecto final de la aplicación será algo parecido a esto.



Lo que veremos es los tres valores de aceleración de los tres ejes, el botón test es “start” de la aplicación, tras pulsarlo veremos los valores modificacarse. En Gyro visualizamos los tres valores de la forma que los enviaremos por el bluetooth.

El botón de “Connect” en realidad es un “Listpiker” que nos mostrara la lista de elementos bluetooth que tengamos emparejados, el símbolo raro bajo el botón de “Connect” es un “slider”, que nos permite modificar la frecuencia de envió. Debajo de la pantalla tenemos el GyroscopeSensor, Clock1, BluetoothClient1 y Clock2, esto es ir a sensores y arrastrar los que queramos, sobre la pantalla.


Para realizar la programación nos iremos a bloques y mediante una interface gráfica podremos programar nuestra aplicación.  A nuestra derecha tendremos las herramientas necesarias, para generar eventos, cálculos, lógica, etc. No me extenderé y directamente pasare a mostrar las imágenes de cómo hacer los módulos.

Configuración del Bluetooth





Configuración de Botones y variables globales


Configuración de giroscopio y definición del mensaje



Empleo dos relojes uno fijo a 100 milisegundos que captura el valor del sensor y el otro reloj para configurar el envió, podría emplearse el mismo clock.

Slider y clock2





Una vez tengamos nuestra aplicación le danos al “Build” en el menú principal, nos da dos opciones o bien nos proporciona un código QR para descargarnos la aplicación o bien te la exporta al ordenador en formato .apk. Para instalarla tendremos que tener habilitado instalar aplicaciones de origen desconocido.

Este es un ejemplo simple pero que se puede complicar más o añadir más funcionalidades, como para controlar un robot más complejo o un coche de radio control.

Aquí os dejo el enlace de la aplicación en formato .aia podéis abrirla en el Mit app inventor dándole a importar.

Anakleto.