Mostrando entradas con la etiqueta Circuito. Mostrar todas las entradas
Mostrando entradas con la etiqueta Circuito. Mostrar todas las entradas

PIC-Cal, un PIC hecho calculadora.

... O una calculadora hecha con PIC.
En esta ocación les presento una calculadora hecha con un PIC16F88 y un módulo LCD administrado con el microcontrolador Hitachi 44780 o compatible.
Esta no es una gran calculadora, pero resuelve fórmulas algebraicas reconociendo términos y utilizando parentesis. Esta versión todavía no maneja números negativos ni decimales, ya que solo el hecho de utilizar números float32 aumenta el consumo de memoria flash del PIC desde el 60% hasta cerca del 80%. Si se quisiera hacer una calculadora mas exacta y compleja se tendría que recurrir a un PIC con mas memoria.
El proyecto es una mezcla de la práctica de varios artículos que se pueden encontrar en este blog. Ya que utiliza la librería LCDGAR.c para el display, controlado con un shift register que a su vez se usa para barrer el teclado.
El código es demasiado extenso como para publicarlo en el blog, por ese motivo es que solo dejo el link para descargar el proyecto completo en CCS C y la simulación en ISIS. De todos modos pasaré a comentarlo brevemente:
El bucle principal espera a que se pulse una tecla, cuando esto sucede actua en consecuencia de la tecla pulsada. Esta es la parte sencilla.
Cuando se pulsa cualquier tecla, que no sea el signo igual, la almacena en una cadena y si se pulsa el signo igual, resuelve. Esto en teoría también es sencillo.
Ahora la pregunta es ¿cómo se resuelve?, pues bien, las calculadoras normales van haciendo las operaciones según se las vayan ingresando. Pero sabemos que en matemáticas esto no es así, una calculadora científica, reconoce términos, y eso es lo que se pretendía resolver en este proyecto, luego se agregó el uso de parentesis, pero la forma de resolverlos es igual para ambos casos.
Supongamos que la fórmula ingresada es:

15 X 3 + 8 X 4

Para resolverlo, con lápiz y papel, no podemos hacer:

15 X 3 = 45
45 + 8 = 53
53 X 4 = 212

La forma correcta sería separandolo en términos, que es de esta forma:

15 X 3 = 45
8 X 4 = 32
45 + 32 = 77

15 X 3 + 8 X 4 = 77

Eso es lo que se pretende que haga la calculadora, para eso, una vez pulsada la tecla resolver, la secuencia es como se muestra a continucación:
Paso 1Se recorre toda la fórmula. Si encuentra un + o un - corta la fórmula, de modo que queden tres términos y si hay mas de tres, en el último habrá varios términos.
Paso 2Resuelve el segundo término, dejando en este el resultado.
Paso 3Junta el primer término con el segundo en un único y primer término.
Paso 4Resuelve el primer término, dejando el resultado.
Paso 5Junta el resultado del primer término con el tercero en la fórmula.
Paso 6Si todavía hay cuentas por realizar vuelve al paso 1.
FINPresenta el resultado en pantalla.

En la práctica para la fórmula 3 X 3 + 8 X 4 - 2 X 3, pasaría lo siguiente:
Vuelta 1 Paso 1 Recorre la fórmula buscando + y -, recortándola y dejando:
Primer término: 3 X 3 +
Segundo término: 8 X 4
Tercer término: - 2 X 3
Paso 2 Resuelve el segundo término:
Segundo término: 32
Paso 3Junta el primer y el segundo término:
Primer término: 3 X 3 + 32
Paso 4Resuelve el primer término:
3 X 3 = 9
9 + 32 = 41
Primer término: 41
Paso 5Junta el primer y tercer término, en fórmula:
Fórmula: 41 - 2 X 3
Paso 6Hay cuenta, vuelve al paso 1.
Vuelta 2 Paso 1 Recorre la fórmula buscando + y -, recortándola y dejando:
Primer término: 41 -
Segundo término: 2 X 3
Tercer término: (vacío)
Paso 2 Resuelve el segundo término:
Segundo término: 6
Paso 3 Junta el primer y el segundo término:
Primer término: 41 - 6
Paso 4Resuelve el primer término:
41 - 6 = 35
Primer término: 35
Paso 5Junta el primer y tercer término, en fórmula:
Fórmula: 35 (No hay nada en el tercero)
Paso 6No hay mas cuentas, sale del bucle.
FIN Presenta el resultado en pantalla.
Los parentesis se resuelven utilizando el mismo método, con la diferencia que utiliza el contenido de los mismos como fórmulas independientes y son las primeras en resolverse. El algoritmo detecta parentesis dentro de parentesis.
Para terminar, aclarar que el código no está pulido ni probado al 100%, de modo que puede, y debe, tener muchos bugs. Pero lo comparto por si a alguien le es útil como ejemplo. Si se encuentra algún error o alguna modificación significativa, bienvenidas serán sus sugerencias.
El primer bug que sé que va a tener, es que no se puede ingresar fórmulas de mas de 64 caracteres, y el código no tiene ningún tipo de control para evitar la catástrofe cuando se ingrese el número 65.

MAX232, conectando un PIC al ordenador

Una de las comunicaciones mas comunmente utilizadas en informática y/o electrónica es la comunicación serie, y dentro de este tipo de comunicaciones se encuentra la USART (Universal Synchronous Asynchronous Receiver Transmitter o en español: Receptor y emisor síncrono o asíncrono universal).

El puerto serie del PC normalmente tiene 9 pines, pero la ventaja de este sistema es que se puede utilizar solo dos líneas de datos y una tercera de GND, para establecer una comunicación bidireccional. Dichas líneas de datos son TX, para transmitir y RX para recibir datos.

La conexión de PC a PC es tan sencilla como cruzar los cables TX de la PC1 se conectará a RX de PC2 y el TX de PC2 a RX de PC1, como se muestra en el siguiente diagrama:

Si bien esta forma de comuncicación quedó un poco anticuada, pero no obsoleta del todo, gracias a la aparición de tecnologías mas avanzadas como USB (Universal Serial Bus, Bus serie universal) es muy recurrida gracias a su compatibilidad, su poco requerimiento de hardware adicional y la sencillez de manejo, estos dos últimos puntos se deben, en gran parte, a que el gestionamiento se hace con hardware exclusivo.

Casi toda la gama de PIC dispone de USART, por no decir que toda la actual; Para comunicarnos con un ordenador vía puerto serie, los PIC disponen de dos pines para tal fin, estos son RX y TX que, dependiendo del modelo de microcontrolador están compartidos con otros recursos.

Ahora bien, sabemos que estos controladores manejan tensiones TTL a 5V, esto quiere decir que, para el PIC, un 0 lógico equivale a  un voltaje muy cercano o como mínimo a 0V y un 1 lógico a un voltaje de 5V como máximo.

El ordenador entiende un 0 lógico cuando la tensión en el pin correspondiente del puerto serie es de entre +3V y +15V, un 1 lógico es cuando esa tensión se encuentra entre -15V y -3V.

Esto solo puede significar algo, si bien el PIC entiende el lenguaje que habla el PC mediente el puerto serie, no se puede conectar directamente porque indudablemente algo no muy agradable le sucederá, es por ello que disponemos del archifamoso integrado MAX232.

Este integrado de 16 pines se encarga, el solo, de invertir y adaptar las señales procedentes tanto desde el PIC hacia el PC como las señales en sentido contrario.

El pinount del MAX232 es la siguiente:

El integrado dispone de 2 receiver y 2 transmitter. Esto puede ser un poco confuso a primera vista pero ya veremos que no lo es.

El primer transmisor esta conformado por T1IN y T1OUT (Pin 11 y 14 respectivamente) y el segundo lo conforman T2IN y T2OUT (Pin 10 y 7), lo mismo sucede con el receptores, el primero R1IN y R1OUT (Pin 13 y 12) y el otro es R2IN y R2OUT (Pin 8 y 9).

Ahora bien, como este integrado esta diseñado para adaptar los niveles del RS232 a los niveles TTL (y viceversa) las nomenclaturas de los pines están expresados del lado del microcontrolador, es decir que cuando se refiere a transmitter se refiere al PIC, el TX del PIC se conectará al TnIN (n es el 1 o 2), la señal TX entra en TnIN y sale por TnOUT hacia el PC. Lo mismo pasa con el receptor, la señal RX del ordenador entra en RnIN y sale hacia el PIC por RnOUT.

La conexión del microcontrolador al PC medienate el MAX232 quedaría como en el siguiente esquema:
Aparte de los pines correspondientes a las señales, el MAX232 dispone de otros, pero son solo para conectarle los componentes adicionales necesarios para su funcionamiento, veámos:

Se observa que dichos componentes no son ni mas ni menos que 5 capacitores, mas especificamente capacitores electrolíticos de 1µF y de unos 16V, si se utilizan de tantalio aún mejor.

Bueno, eso es todo por ahora, luego faltaría algún ejemplo real del manejo de RS232 en CCS C para comunicarse con un ordenador.

Matriz de 8x8 LED controlada con 2 shift register y PIC

Muchas personas experimentan a diario con arrays de 8x8 LED y un porcentaje de esas personas reflejan sus dudas en distintos sitios desperdigados por la red destinados a este mundillo de la electrónica y los microcontroladores.

Precisamente de una duda que se me planteó hace poco por correo electrónico surgió un pequeño proyecto a modo de ejemplo de un array de 8x8 LED; El cual funciona de maravillas tanto simulado como físicamente y es por eso que lo publico en esta ocación.

Dicho proyecto está basado en una serie de artículos anteriores dedicados a los shift register, en otras palabras es una implementación de los registros para usarlos con una matriz de LED.

Aquí presento el diagrama de conexión:


El PIC utilizado en esta ocación es el PIC16F88 por ser muy fácil de implementar y contar con oscilador interno.

La línea Load se conecta al pin B0 del PIC, Clk al B1, dClm a B2 y dLin a B3.

La lista de componentes es mas cuantiosa que variada pues esta compuesta por:
R1-R88 x Resistencias de 220Ω
R9-R168 x Resistencias de 3,9KΩ
Q1-Q88 x Transistores BC547 o similar

2 x 74HC595

64 x LED rojo de 5mm brillo standard

El código, escrito en CCS C, para probar el hardware es el que sigue a continuación, solo he dejado las letras pertinentes a PICROBOT, ya que sino se hace muy largo y repetitivo para mostrarlo como ejemplo, pero desde este link te puedes descargar el código completo con las letras en mayúsculas A-Z, el .HEX, el .COF para simularlo en el ISIS de Proteus y el .DSN con el diseño.

Hay dos versiones del código en este paquete, matriz8x8Q y matriz8x8. La primera es para cuando se usen los transistores a los cátodos de los LED y la segunda si los cátodos van directamente a las salidas del registro de desplazamiento encargado de controlar las columnas.

La única diferencia entre las dos versiones es que la primer versión (Q) no invierte y la segunda si lo hace, las salidas del registro encargado de controlar las filas.

Se podría haber solucionado el problema declarando o no una macro instrucción dirán algunos, después de todo lo único que varía es un caracter de una versión a otra, pero para no confundir, y como este es un ejemplo sencillo, decidí hacerlo así. En un futuro ejemplo de la implementación tal vez incluya una macro instrucción.

/*************************************************************************
**                                                                      **
**    Ejemplo básico para controlar una matriz de 8x8 LEDs con PIC.     **
**                                                                      **
**                      (c) 2010 Gerardo Ariel Ramírez                  **
**                            picblog@hotmail.com                       **
**                       http://picrobot.blogspot.com/                  **
**                                                                      **
**************************************************************************
**                                                                      **
**  Microcontrolador: PIC16F88           Oscilador: Interno - 8 MHz     **
**          Lenguaje: CCS C                                             **
**                                                                      **
*************************************************************************/

#include <16f88.h>      // Tipo de microcontrolador
#fuses INTRC_IO,MCLR    // Oscilador interno, MCLR activo
#fuses NOPUT,NOBROWNOUT // Sin Brownout reset ni Power up timer 
#use fast_io(all)       // La configuración de los puertos solo se hace al principio.
#use delay(clock=8M)    // Velocidad del oscilador interno 8 MHz

#define Load   PIN_B0   // Load (STCP ambos integrados) B0
#define Clk    PIN_B1   // Clock (SHCP ambos integrados) B1
#define dClm   PIN_B2   // Data para las columnas (DS integrado 1) BC2
#define dLin   PIN_B3   // Data para las lineas (DS integrado 2) B3

char  Memoria[96];      // 96 Bytes para la memoria (0 - 95)
char  Visor[8];         // 8 para el visor (8 columnas)

int1  flag;             // Flags de control
int1  flag2;
int   indx;             // Indice donde almacenará las nuevas columnas.
int   line;             // Linea que a mostrar.
int   time;             // Variables para el control de
int   ptime;            // la velocidad de desplazamiento.
int   t;                // Variable auxiliar.

void CargaMem(char Ascii);
void GuardaClm(char c);

#int_rtcc
void isr(){
   int Mul=128;         // Cada vez que ocurre la interrupcion
   if(++line>7)Line=0;  // selecciona la siguiente linea, si se pasa de 7 vuelve a 0.
   
   if(++ptime>5){      // Suma 1 a ptime. Si se pasa de 20
      ptime=0;          // lo pone en 0 y suma 1 a time.
      if(++time>200){   // Si se pasa de 200
         time=0;        // lo pone en 0
         Flag=true;     // y activa el flag.
      }
   }
   
   
   for(t=0;t<8;t++){    // Bucle 0 - 7 (Lineas)
      
      output_bit(dLin,!!(Visor[Line]&Mul));  // dLin es seteado con el valor
                                             // del bit de la fila actual.     
      if (Line==t)output_high(dClm);         // Si Line es igual a t
                                             // activa el bit correspondiente
      else  output_low(dClm);                // a la columna, sino lo desactiva.
      
      output_low(Clk);  // 
      output_high(Clk); // Rota el contenido interno del 74HC595.
      
      Mul>>=1;          // Divide la mascara que compara con Visor[] (128,64,32...)
   }
      output_low(Load);
      output_high(Load);// El contenido interno del integrado pasa a las salidas.
   
}
void main(){
   int k;   
   set_tris_a(0x00);
   set_tris_b(0x00);
   for (k=0;k<8;k++){
      Visor[k]=0;
   }
   for (k=0;k<96;k++){
      Memoria[k]=0;
   }                    // Limpia la memoria y el visor
   
   flag=true;           // Activo el flag para que cargue la memoria
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  // Configuración del Timer0
   enable_interrupts(int_rtcc);              // Interrupcion por Timer0
   enable_interrupts(global);                // Interrupciones globales
   
   do{
      if (Flag){                 // Si el flag está activado
         flag2=true;             // Activa el flag2
         
         for (k=0;k<8;k++){      // Pasa el contenido de las primeras 8
            visor[k]=Memoria[k]; // columnas en memoria al visor
         }
         
         for (k=0;k<95;k++){        // Rota el contenido de toda la memoria
            Memoria[k]=Memoria[k+1];// a la izquierda 1=1+1, 2=2+1, n=n+1...
            
            if (Memoria[k]!=0){Flag2=false;} // Si hay alguna columna que no
                                             // esté vacía desactiva el flag2
         }         
         Memoria[95]=0;             // Limpia la ultima columna de la memoria
        
        if (Flag2){                 // Si flag2 está activo            
            indx=7;                 // a partir de la columna 7 
            CargaMem("PICROBOT");   // escribe PICROBOT            
         }
         Flag=false;                // Desactiva el flag
         
      }
   }while (true);    // Bucle infinito


}

void GuardaClm(char c){
   if (indx<94){
      Memoria[indx]=c;     // Guarda la columna en la ubicación actual de memoria
      indx++;              // y aumenta el indice
   }
}


void CargaMem(char ascii){    // Carga la memoria con el caracter deseado
   switch (ascii){    
      
      case('B'):
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b01001001);
      GuardaClm(0b01001001);
      GuardaClm(0b01111111);
      GuardaClm(0b00110110);      
      break;
      
      case('C'):
      GuardaClm(0b00111110);
      GuardaClm(0b01111111);
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);
      GuardaClm(0b01100011);
      GuardaClm(0b00100010);     
      break;

      case('I'):
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);      
      break;  

      case('O'):
      GuardaClm(0b00111110);
      GuardaClm(0b01111111);
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);
      GuardaClm(0b01111111);
      GuardaClm(0b00111110);      
      break;      
      
      case('P'):      
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b00001001);
      GuardaClm(0b00001001);
      GuardaClm(0b00001111);
      GuardaClm(0b00000110);      
      break;
      
      case('R'):
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b00001001);
      GuardaClm(0b00011001);
      GuardaClm(0b01111111);
      GuardaClm(0b01100110);
      break;
      
      case('T'):
      GuardaClm(0b00000011);
      GuardaClm(0b00000001);
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b00000001);
      GuardaClm(0b00000011);
      break;      
   }
      GuardaClm(0b00000000);
}

Controlar 8 displais de 7 segmentos con shift register

Continuando con el tema de los shift register, ofreceré algunas utilidades a dichos integrados utilizando un microcontrolador a modo de ejemplo y totalmente funcionales.

El ejemplo que aquí propongo es la utilización de los registros para controlar 8 displais de 7 segmentos, como ya vimos anteriormente en este artículo, pero con el agregado de la implementación de un teclado; Pero aquí les proporciono el ejemplo completo con el código fuente en CCS C y su respectivo .HEX para que puedan grabarlo en el PIC y probarlo.

He aquí el diagrama de conexión:

El diagrama es bastante sencillo, solo hace falta conectar cada segmento de cada display a las salidas (Q0-Q7) del shift register encargado de "dibujar" los números y el ánodo común de cada display a cada una de las salidas del segundo integrado. También este diseño es válido si los displais son de cátodo común la única diferencia está en que habría que hacer una pequeña modificación en el código.

Para probar el código que les propongo, al diagrama anterior hay que agregarle algunas cosas como por ejemplo 10 pulsadores, 10 diodos 1N4001-7 y 2 resistencias de unos 10KΩ, como se ve en el siguiente diagrama.

Cada ánodo de los diodos se conecta a una salida diferente del shift register encargado de seleccionar el display que se iluminará, de esta forma multiplexámos el teclado de modo que a cada iteración del bucle encargado de encender un display comprobamos una tecla, como esto nos da la posibilidad de conectar solo 8 pulsadores, se agrega otra entrada para comprobar una segunda línea.

A continuación les dejo el código:
/*************************************************************************
**                                                                      **
**             Ejemplo para controlar 8 display de 7 segmentos          **
**              y un teclado con dos shift register y un PIC.           **
**                                                                      **
**                      (c) 2010 Gerardo Ariel Ramírez                  **
**                            picblog@hotmail.com                       **
**                       http://picrobot.blogspot.com/                  **
**                                                                      **
**************************************************************************
**                                                                      **
**  Microcontrolador: PIC16F88           Oscilador: Interno - 8 MHz     **
**          Lenguaje: CCS C                                             **
**                                                                      **
*************************************************************************/

#include <16f88.h>         // Tipo de microcontrolador
#fuses INTRC_IO,MCLR,NOPUT,NOBROWNOUT // Fuses 
#use fast_io(all)      
#use delay(clock=8M)

#define Load      PIN_B0   // Load (STCP ambos integrados) B0
#define Clk       PIN_B1   // Clock (SHCP ambos integrados) B1
#define dDsp      PIN_B2   // Data para seleccionar display (DS integrado 1) B2
#define dSeg      PIN_B3   // Data para activar segmentos (DS integrado 2) B3
#define Teclado1  PIN_B4   // Entrada de teclas 0-7
#define Teclado2  PIN_B5   // Entrada de teclas 8 y 9

#define Seg_A  0x01
#define Seg_B  0x02
#define Seg_C  0x04
#define Seg_D  0x08
#define Seg_E  0x10
#define Seg_F  0x20        // Los bits correspondientes a cada segmento de cada display.
#define Seg_G  0x40        // Estos bits se comparan mediante la máscara Mask.

int Digit[8];
int Numero[10]={
Seg_A + Seg_B + Seg_C + Seg_D + Seg_E + Seg_F,
Seg_B + Seg_C,
Seg_A + Seg_B + Seg_D + Seg_E + Seg_G,
Seg_A + Seg_B + Seg_C + Seg_D + Seg_G,
Seg_B + Seg_C + Seg_F + Seg_G,
Seg_A + Seg_C + Seg_D + Seg_F + Seg_G,
Seg_A + Seg_C + Seg_D + Seg_E + Seg_F + Seg_G,
Seg_A + Seg_B + Seg_C 
Seg_A + Seg_B + Seg_C + Seg_D + Seg_E + Seg_F + Seg_G,
Seg_A + Seg_B + Seg_C + Seg_D + Seg_F + Seg_G
}; // Establece Numero[0-9] con los datos correspondientes a cada segmento que deberá encender.

void CargaMem(char Ascii);
void GuardaClm(char c);

void main(){
   int d;
   int b;
   int Mask;   
   int Tecla;
   int anTecla;
   
   setup_ccp1(CCP_OFF);
   set_tris_a(0);                      // Puerto A como salida
   set_tris_b(0b00110000);             // Puerto B como salida excepto B4:B5 como entradas
   
   setup_oscillator(OSC_8MHZ);   
   
   d=0;
   anTecla=10;
   
  do{      
      Mask=0x80;                       // Carga la mascara, solo el MSB en high                  
      for (b=0;b<8;b++){               // Un bucle de 8 pasos (0-7)
         
         output_bit(dSeg,!(Mask&Numero[Digit[d]]));         // Le envía los bits al shift
                                                            // register encargado de encender
                                                            // los segmentos.
         if (b==d) output_high(dDsp); else output_low(dDsp);// Pone en alto el bit corres-
                                                            // pondiente al display que se va a
                                                            // encender en esta iteración.
         
         Mask>>=1;                     // Divide la mascara por 2 : 128, 64, 32...
         output_low(Clk);              // Low-to-High en el Clk
         output_high(Clk);             // hace que la memoria del shift register rote
      }
      
      output_low(Load);                // Low-to-High en Load hace que la memoria
      output_high(Load);               // del shift register se represente en sus salidas 
      
      if (input(Teclado2)) Tecla=d+9;  // Comprueba que se haya detectado la pulsación en las
      if (input(Teclado1)) Tecla=d+1;  // entradas de teclado y lo guarda en la variable Tecla.
      
      if (++d>7){                      // Incrementa el display a mostrar
                                       // si se pasa de 7 vuelve a 0-         
         if (Tecla!=0 && AnTecla==0){  // Si Tecla es diferente a 0 (se ha pulsado una tecla)
            for (b=7;b>0;b--){
               Digit[b]=Digit[b-1];    // Hace un scroll en los display
            }
            Digit[0]=Tecla-1;          // y guarda la tecla pulsada en el ultimo display.
         }
         AnTecla=Tecla;                // Guarda la tecla pulsada y 
         Tecla=0;                      // pone Tecla a 0 para comprobar la proxima vez.
         d=0;                          // d a 0 para encender el primer display y comenzar
      }                                // otra vez.
   }while (true);                      // Bucle infinito
}

Espero que les haya gustado y lo próximo que les entregaré será un artículo sobre el control de un array de 8x8 LED con el mismo sistema.

Desde este link se puede bajar el código y el .HEX

Grabador de PIC

Cuando la mayoría de la gente está empezando en la programación de PIC, casi siempre opta por comprarse el grabador, y es algo muy razonable ya que si uno no tiene demasiados conocimientos de electrónica y se construye su propio grabador y este tiene algún problema, es mas complicado saber donde está el fallo, si en el grabador, en el PIC, en la programación, etc.

Pero lo que les propongo aquí es la construcción del Programador PIC Pablin II , ya que es muy sencillo y le funciona a la gran mayoría de la gente por no decir que a todos. A este grabador se le conoce un problema y es que a veces no graba al tener poca tensión, yo lo solucioné con las recomendaciones de este artículo Programador PIC Pablin 2 Reloaded de Heli, pero aún así le encontré algunos fallos, no tantos como antes pero si que generaban contratiempos.

Ahora lo que propongo es hacer el mismo circuito, pero obtener 13V exactos a partir de cualquier fuente y para ello utilizaremos dos reguladores de tensión uno de 5V y otro de 8V conectando el GND de este último a la salida del primero.


Lista de componentes:
D1,D2 Diodos 1N4001 al 1N4007 o 1N4148
D3 LED Verde
D4 LED Rojo
R1-R6 Resistencias de 1KΩ
R7, R8 Resistencias de 10KΩ
Q1, Q2 Transistores 2N3904, 2N2222 o BC546 al BC550
IC1 Regulador de voltaje LM7805
IC2 Regulador de voltaje LM7808
IC3 Sextuple Hex inverter 74LS04 o su versión Smith Trigger 74LS14
CN1 Conector para plug de fuente de alimentación
CN2 Conector DB25 Macho
CN3 Tira de pines hembra cortada a 6 pines

El conector del ICSP aunque tenga 6 contactos solo usa 5 para que no se invierta la polaridad por error. En la placa donde se encuentra el PIC a grabar se debe quitar un contacto al conector e introducir un pin macho, soldándolo al PCB y cortarlo al raz y luego al contacto macho del grabador se le debe quitar tal pin para que entre sin problemas.

Estos son los respectivos pinout de los transistores válidos para el diseño:



Mi preferencia particular es hacer un grabador que solamente tenga ICSP (In Circuit Serial Programming) ya que podremos grabar cualquier PIC que este montado en su placa definitiva, y si lo que queremos es grabar el PIC antes de ponerlo en la placa, o la placa definitiva no tiene conector ICSP se puede hacer una placa con los 3 zócalos y agregarle el conector ICSP aparte.

A continuación, el pinout de los respectivos PIC a grabar:

PICPGDPGCVPP5VGND
18 pinesPIN 13PIN 12PIN 4PIN 14PIN 5
28 pinesPIN 28PIN 27PIN 1PIN 20PIN 8 y 19
40 pinesPIN 40PIN 39PIN 1PIN 11 y 32PIN 12 y 31

Personalmente siempre utilicé el programa IC-Prog pero el WinPic800 es notablemente mas rápido; para hacerlo funcionar con cualquiera de los dos programas, se debe configurar como ProPic 2 Programmer.

NE555

Sin lugar a dudas el NE555 es uno de los integrados mas conocidos por cualquier hobbista de la electrónica y/o robótica que se aprecie, pero para muchos puede resultar un poco complicado comprender que es lo que realmente hace. En este artículo intentaré explicar, de una manera sencilla, no tanto funcionamiento sino la utilidad, que es lo que realmente a la mayoría de los lectores les importa.

El paso obligado a la hora en empezar a comprender el funcionamiento de cualquier integrado creo que es revisar su datasheet y por eso aquí se los dejo para que lo puedan revisar, aunque como este artículo está basado en la información que ahí figura puede salteárselo el que no entienda mucho de inglés o no sepa todavía leerlos bien. Bueno, para el que no se lo leyó (y para el que se lo leyó también) en la Figura 1 se observa el patillaje o pinout del integrado en cuestión.

Figura 1. Pinout del IC NE555.

Este integrado normalmente se define como un timer, que vendría a ser algo así como un contador, pero también se lo podría definir como un oscilador. Se sabe que un oscilador es un componente capaz de marcar el tiempo, y la forma que tiene nuestro integrado de marcarlo es por medio del paso de alto a bajo del pin salida (Output) a una determinada frecuencia.

La velocidad a la que trabaje nuestro integrado dependerá de la conexión que se le haga a los componentes externos, mas concretamente a las resistencias y capacitores que se elijan. En los ejemplos que daré a continuación se explica las dos configuraciones posibles, monoestable, que es cuando el IC trabaja como un delay, y astable, que es cuando trabaja en modo oscilador o multivibrador. Las dos modalidades se basan en un principio muy fácil de entender, la frecuencia con que oscila el integrado dependerá exclusivamente de la velocidad con que se cargue y descargue el capacitor que se le conecte. Cuando el capacitor se cargue, la salida estará en nivel alto y cuando se descargue en bajo. Pero la principal diferencia entre uno y otro es la utilización del trigger.
El primer circuito que les presento (Figura 2) es para configurar el integrado como monoestable, que significa que solo en un estado, el tiempo es estable, donde se ve que el pin 2 (Trigger) queda libre para conectarlo a una señal de control, cuando dicha señal se activa, la salida (pin 3) se mantiene un tiempo determinado en estado alto para pasar luego a estado bajo hasta un nuevo disparo del pin 2.

Figura 2. Configuración monoestable.
 
El pin 4 (Activación o Reset) se puede conectar directamente a un microcontrolador para activar/desactivar la salida de la señal, esto no es tan necesario en este modo ya que el circuito queda a la espera de una pulso bajo en el pin 2 para activar la salida, pero en el modo astable el uso de activación es fundamental para activarlo cuando se desee ya que de lo contrario en la salida estaría permanentemente la señal presente, pero eso lo veremos mas adelante. Ahora bien ya sabemos como es la conexión en teoría, del integrado, pero falta algo fundamental a la hora de armar el circuito, los valores de cada componente, estos varían dependiendo de la frecuencia que queremos obtener como se habló anteriormente. Para saber que valores usaremos, primero debemos comprender el funcionamiento del circuito monoestable.

En la Figura 3 se ve una gráfica de los valores de la salida dependiendo el estado del trigger a cada momento:

Salida respecto a Trigger Figura 3. Comportamiento del pin 3 (Output) respecto al pin 2 (Trigger) en configuración monostable.
 
Como se observa a simple vista la salida pasa a estado alto durante un cierto tiempo cada vez que se pasa de alto a bajo el pin 2. Mientras el integrado no perciba ese cambio de estado, la salida permanece a estado bajo. El tiempo que la salida permanecerá en estado alto viene determinado por la fórmula tH = 1.1 R1 C1. 

Este circuito es aplicable, por ejemplo, si queremos hacer un circuito capaz de funcionar un determinado tiempo luego de activar un pulsador. Pero como ya se dijo hay otro modo de usar el integrado y es el astable. La configuración astable se utiliza mucho en robótica ya que es totalmente válida para modular la frecuencia con que parpadea un LED infrarrojo o un altavoz, por ejemplo. Se sabe que fuentes de luz como el sol o un foco incandescente producen luz infrarroja y esta puede causar errores de lectura con fototransistores, para evitar esto, la luz del emisor es modulada y por medio de un decodificador en la recepción, la frecuencia es interpretada para obtener una detección segura.

Pero esta modulación significa alternar estados altos y bajos a un ritmo muy alto, y como se ve en el modo monoestable, solo podremos asegurar el tiempo del estado en alto, para poder crear una onda que alterne entre un estado y otro, necesitaremos configurar el NE555 en modo astable. Y para ello deberemos conectarlo como se ve en la Figura 4; Para saber a que frecuencia oscila, deberemos aplicar las fórmulas de la Tabla 1.

Figura 4. Conexión del IC NE555 en modo astable.

C1 Salida (Pin 3) Fórmula
Carga Alto t1 = 0,693 (R1 + R2) C1
Descarga Bajo t2 = 0,693 R2 C1
Tabla 1. Fórmulas para calcular los tiempos del IC NE555 en configuración astable.

El diagrama y las fórmulas nos sirven también para comprender un poco el funcionamiento del circuito. De todo esto se deduce que la corriente pasa por R1, luego por R2 cargando C1, si hojeamos el datasheet verificamos que cuando C1 se carga con 2/3 de Vcc se dispara el pin 7 (descarga - discharge) poniéndose a GND, lo que hace descargar el capacitor (de ahí su nombre) hasta 1/3 de Vcc que es cuando el pin 7 vuelve a ponerse en alta impedancia, abriendo el circuito, volviendo a cargar C1 e iniciando la secuencia nuevamente.

Ahora bien, con estos datos se ve que siempre la carga es mas lenta que la descarga, ya que la carga se hace por medio de R1 + R2 y la descarga solo con R2, lo que nos impide hacer que el circuito oscile con un duty cycle del 50%, es decir que tarde lo mismo estando a nivel bajo que en alto. Para lograrlo necesitaremos impedir que la corriente circule por R2 cuando C1 se esté cargando, ¿Cómo se hace eso? Fácil, con un diodo ubicado en paralelo a R2, nuestro archifamoso compañero, el 1N4007 (o similar) nos servirá de maravilla.

En la Figura 5 se observa como quedaría el circuito para logran un duty cycle del 50% (siempre y cuando R1 sea igual a R2).

Figura 5. Circuito para lograr que el IC NE555 oscile con un duty cycle del 50%.

Y en la tabla de fórmulas lo único que varía es que, para el cálculo de la carga, no interviene R2, por lo tanto quedaría de esta forma:

C1 Salida (Pin 3) Fórmula
Carga Alto t1 = 0,693 R1 C1
Descarga Bajo t2 = 0,693 R2 C1
Tabla 2. Fórmulas para calcular los tiempos del IC NE555 con un duty cycle del 50%.

Como se observa en el diagrama de la Figura 5, para realizar la carga, la corriente pasa por R1 y luego al tener menos resistencia por D1 "corta camino" (el camino de menor resistencia) y pasa directamente a C1. En la descarga D1 impide el paso de corriente en esa dirección lo que provoca que pase por medio de R2 por lo que si las dos resistencias son del mismo valor tardará lo mismo la descarga que la carga (en teoría, ya que la realidad nunca es igual a la teoría, pero para la práctica el error es mínimo).

Bueno, eso es todo por el momento, espero que les haya servido de ayuda y recuerden que esto es a modo de apunte, cualquier corrección o duda que tengan coméntenla y será contestada con la mayor brevedad posible. También invito al público a participar haciendo sus consultas, sugerencias y/o pedidos, por los medios pertinentes, toda colaboración será bienvenida, y no olviden que aquí todo el que quiera puede aprender y/o enseñar algo...

Reguladores de voltaje 7805

La familia 78xx y 79xx son una gama de integrados dedicados a la regulación de voltaje, hay muchas variables: regulables, fijos, de tensión positiva o negativa...

Pero el mas común, y el que mayormente usaremos en el mundo de los PICs, es el famoso 7805, que es un regulador de tensión positiva de 5 Volts a 1A, la tensión justa y mucho mas corriente de la que necitan nuestros PICs para funcionar. Se sabe que el buen funcionamiento del firmware que grabemos en el PIC está sujeto, no sólo a la buena programación que hayamos hecho a la hora de diseñarlo, sino que también a una alimentación fija, constante y regulada a la hora de ejecutarlo. Entonces la manera mas segura, económica y sencilla de obtener ese voltaje, es la utilización de un integrado regulador de voltaje, y el 7805 es uno de los mas indicados ya que mantendrá fija la tensión en 5V, siempre y cuando en su entrada reciba al menos 6V. Por lo tanto a la entrada podremos despreocuparnos de la alimentación superando por mucho el voltaje de trabajo del PIC.

Para trabajar con baterías sólo basta con conectar la entrada del IC (PIN 1) al terminal positivo de la misma y el común (PIN 2) al negativo, a la salida tenemos 5V que es la tensión de trabajo del microcontrolador, podremos añadir un capacitor entre GND y la salida, como se aprecia en la Figura 1, para eliminar cualquier fluctuación de voltaje que pueda ocurrir, pero esto es siempre recomendable hacerlo con el microcontrolador independientemente del origen que tenga la alimentación.


Figura1. Conexión de un IC de la familia 78xx a una batería.

Si al IC lo usaremos para regular la tensión proveniente de una fuente de alimentación, el filtrado debe hacerse más concienzudamente, a parte del capacitor luego de la regulación, necesitará dos mas antes, en el diagrama de la figura 2 se ve el circuito para conectarlo a una fuente de alimentación regulada o estabilizada de mas de 5 V.



Figura 2. IC 7805 conectado a una fuente de alimentación regulada o estabilizada de una tensión superior.

Para hacer una fuente completa que se conecte a 220V se necesita agregar un transformador de corriente alterna y rectificar la tensión saliente para convertirla en continua y poder acoplarla al circuito antes visto, todo esto se aprecia en la Figura 3.



Figura 3. Conexión de IC a un transformador de 220V:12V.

Obsérvese que lo único que se añadió fue el transformador para obtener 12V de corriente alterna y 4 diodos que la convierten en corriente continua.

Para terminar basta con aclarar que los capacitores C1 y C2 deben ser no polarizados de .1uF y el C3 polarizado de 1000uF y al menos 16V para soportar los 12V que entrega el transformador, no está de mas aclarar que la tensión sube un poco al rectificarla y no es conveniente que los capacitores operen al límite. Los diodos pueden ser 1N4001 al 1N4007.

Los diagramas de conexión son válidos para cualquier integrado de la familia 78xx, por ser de tensión positiva, en el ejemplo de la figura 3 se necesita un transformador que entregue al menos 1V mas de lo que regule el integrado y nunca debe superar los 35V ya que es la máxima tensión que soportan los reguladores 78xx y el C3 debe ir acorde a la tensión de entrada del IC.

Atención: cuando trabaje con transformadores de tensión debe tener especial cuidado por riesgo de electrocución, ya que se está trabajando con 220V y debe utilizar el respectivo fusible de protección.

Puente H

Navegando por uno y otro lado, siempre me encuentro con el dilema de la gente a la hora de controlar un motor con un microcontrolador. Hay muchas soluciones en forma de integrados, pero estos son algo limitados y, hasta en algunos casos, demasiado costosos o difíciles de conseguir.

La mejor solución, sin lugar a dudas, es utilizar un puente H, pero con este tema surge otro problema en la gente, ¿como funcionan?, ¿como se arman?, ¿cuál es mejor?... para responder a todas esas preguntas, trataré de explicar aquí de una forma sencilla el funcionamiento de estos.

Se sabe que en un motor de corriente continua, el sentido de giro viene dado por la conexión que se le haga a sus bornes. Entonces para hacer que un robot vaya hacia adelante o hacia atrás, bastará con invertir la polaridad del motor que mueva sus ruedas, el problema es como hacer esto, el PIC solo puede suministrar 5v y 20mA por pin totalmente insuficiente para mover un motor, lo que se intenta lograr es poder controlar una tensión y una corriente superior que la que el integrado pueda darnos por medio de una señal que será enviada por el PIC.

En definitiva, el encargado de controlar esa tensión será el Puente H y el PIC controlará a este último.

Figura 1. Motor de corriente continua conectado a dos interruptores inversores.

Cuando conectamos un motor como en el gráfico de la figura 1, girará en un sentido u otro, o se parará según la combinación de los interruptores, el puente H hace lo mismo con la diferencia de que el control se realizará digitalmente y los interruptores mecánicos se reemplazarán por transistores PNP y NPN. De modo que se puede controlar el motor de una forma muy precisa, y con cambios giro/parada a una velocidad muy elevada, pudiendo controlar la velocidad de giro por una señal PWM (Pulse Width Modulation o Modulación por Ancho de Pulsos).

Figura 2. Puente en H. 

Si se compara la imagen de la figura 1 con el de la figura 2 se observa que es muy similar, puesto que los interruptores de la primera están reemplazados por un par de transistores, cada uno, en la segunda.

Buscando entre los datasheets encontramos el BD677 (NPN) y BD678 (PNP), que son unos transistores complementarios capaces de soportar 60V y 4A. Suficiente para mover cualquier robot de medianas dimensiones.

Entonces sabiendo esto podremos crear nuestro puente H del diagrama utilizando estos componentes:

Q1,Q2Transistores 2N2222
Q3,Q4Transistores BD678
Q5,Q6Transistores BD677
D1,D2,D3,D4Diodos 1N4007
R1,R2Resistores de 470Ω
R3,R4Resistores de 22Ω

Dos puentes H como el aquí mostrado son los encargados de mover al robot SiLMuP, que a su vez son controlados por señales PWM enviadas por un PIC16F876.

Aquí les dejo un vídeo con la demostración del Puente H funcionando, debido a la reductora del motor (es un potenciómetro con motor de equipo de audio) el movimiento es lento, pero el Puente H es apto para mover motores relativamente potentes, hasta 60V y 4A.

En el disipador hay un regulador de voltaje LM7805 y solo se incluyó en el circuito para suministrar la señal de activación avance/retroceso, se podría haber activado con la misma tensión que alimenta al Puente H pero lo incluí para demostrar que el Puente H puede ser perfectamente controlado con un PIC. También sería recomendable, en las enatradas de avance/retroceso, ponerle resistencias pull-down para que no se activen por alguna interferencia.

Controlar display de 7 segmentos con shift register

Ya vimos lo que es y como se controla un shift register, ahora veremos una de las tantas utilidades que tiene. Aquí se explicará como utilizar un shift register para controlar un display de 7 segmentos.

Para el que todavía no lo conozca, un display de 7 segmentos es un panel conformado por 7 LED que comparten entre si sus ánodos o cátodos según si sean de ánodo o cátodo común respectivamente.

A un display de ánodo común deberemos aplicar tensión positiva al pin compartido y GND a cada uno de los pines correspondientes a los segmentos que se quieran iluminar, para un display de cátodo común deberemos invertir la polaridad. La mayoría de displais poseen también un octavo segmento que normalmente es un punto o dos.

Hasta aquí una pequeña introducción para conocer un poco su funcionamiento, ahora bien, vimos que un shift register serial-paralelo “memoriza” el estado (0 o 1) de un pin (entrada) y va rotando esos valores por cada pulso de reloj para representar la secuencia completa, cuando se activa el pin Load, en unos pines asignados que tiene el integrado a tal fin.

Si a cada pin de salida (Q0-Q7) del integrado le conectamos un segmento del display, como en la figura 1, logramos encender y apagar dichos segmentos independientes unos de los otros. La principal utilidad es representar un número del 0 al 9 o una letra de la A a la F.

La ventaja de usar el shift register es que sólo necesitaremos 3 pines del microcontrolador: Clock (Amarillo), Data out (Verde) y Load (Rojo).


Figura 1. Conexión de un display de 7 segmentos a un shift register.

Si en lugar de emplear un solo integrado usamos dos (Figura 2), podremos multiplexar los datos. Utilizando el segundo integrado para seleccionar el display que deseamos encender en determinado momento, aumentaremos el numero de displais de 1 a 8 con un integrado mas.

8 display de 7 segmentos conectados a 2 shift register
Figura 2. Conexión de 8 display de 7 segmentos a 2 shift register.

Si encendemos un display, lo apagamos y luego encendemos otro, y hacemos todo esto de manera muy rápida el cerebro humano lo interpreta como si en realidad todos los display permanecieran encendidos al mismo tiempo. Jugando con esto podemos ahorrarnos muchísimos pines de nuestro PIC, por ejemplo si quisiéramos hacer un reloj que indique la hora, los minutos y los segundos, y conectáramos cada segmento a cada pin de un microcontrolador necesitaríamos uno con 42 pines solo para los displais.

Sin shift register también se puede multiplexar, pero aun así utilizaríamos demasiados pines, 7 para los segmentos y 1 para cada display, para diseñar el mismo reloj del ejemplo anterior necesitaríamos un total de 13 pines contra los 4 que se necesitan implementando los registros de desplazamiento.

Para usar los dos integrados, se conectan siguiendo el diagrama de la figura 2, el segmento A de todos los displais con la Q0 del primer integrado, los segmentos B con el Q1, los C con Q2… y así sucesivamente. La salida Q0 del segundo integrado se conecta al común del primer display, el pin Q1 al segundo, el Q2 al tercero… así hasta un máximo de 8 displais.

Para controlarlo enviaremos los bits que conforman el caracter del primer display al primer integrado y el bit correspondiente a dicho display en 0, a cada pulso de reloj, cuando hayamos enviado todos los bits se manda el pulso Load y es cuando aparece el caracter en el primer display, luego se repite la operación pero con el bit del segundo display en 0, de esa forma, y si los displais son de cátodo común, encenderán de a uno. A una alta frecuencia esto crea la ilusión de estar todos encendidos.

Utilizando dos shift registers y 4 pines del microcontrolador tendremos capacidad para controlar 8 displais, y si utilizáramos un integrado y un pin del microcontrolador más, aumentaríamos la cantidad de displais a 16.

Probador de PIC16F876

¿Cuantas veces se han visto con la necesidad de probar un firmware que han programado pero no tienen el circuito hecho para probar? Bueno lo que aquí propongo es una placa con todos los componentes para hacer trabajar al PIC, pero con la particularidad de que los puertos están disponibles para el uso que queramos darle.

El diagrama es el siguiente:

Circuito del probador de PIC16F876 (haga click para agrandar)

A simple vista se ven 5 conectores que 3 corresponden a los puertos del PIC (A,B y C) 1 para la alimentación, y el 5to par el ICSP (In Circuit Serial Programming). Para los que no sepan lo que es esto, les comento que es, como lo indica su nombre en inglés, la programación serial en circuito, o sea que se puede programar (grabar el firmware) directamente en la placa sin necesidad de extraer el integrado en ningún momento.

Aunque también se podría extraer el PIC en cualquier momento gracias a la implementación de un zócalo de 28 pines, dicho sea de paso aconsejo que cada vez que se fabrique un circuito, y sobretodo si está pensado para pruebas, que cualquier integrado que vayamos a utilizar no se suelde directamente a la placa sino que se utilicen zócalos; por económico que sea un integrado no significa que lo tengamos siempre a mano, ni sea fácil de conseguir.

Volviendo a lo que es el circuito en cuestión, es muy sencillo y lo unico que tiene de particular es que facilita la puesta en marcha del PIC, sólo con colocarle los 5volts de alimentación el PIC estaría funcionando, ya que cuenta con un cristal, también se podría utilizar varias velocidades de cristales, por medio de jumpers o zócalos.

Cuenta con protección anti inversión de polaridad, muy útil para cuando estamos haciendo pruebas, como también aislamiento de tensiones para cuando está alimentado y conjuntamente se conecta el ICSP, en tal caso una tensión no interfiere con la otra. Y está incluido el circuito de reset.
Está pensado para utilizarlo en protoboards para lo cual los pines de conexión de alimentación y puertos tendrían que ser de tira de pines acodados a 90º. Por el mismo motivo no se incluyen en el diseño resistencias de pull-up ni pull-down, se supone que el prototipo que se diseñe contendrá las resistencias necesarias.

Puede ser adaptado a cualquier modelo de PIC muy facilmente, solo basta con agragar o quitar pines a los puertos amoldandolos a las necesidades y al modelo del microcontrolador, cada uno puede pensar sus circuitos dependiendo de la necesidad que tenga...

Control de un módulo LCD con PIC y CCS C

Partiendo de saber la Conexión y funciones de un módulo LCD ahora veremos como se utiliza en la práctica. Para empezar aquí les dejo el diagrama de la conexión mas básica para poder comenzar a utilizar el display.

Conexión LCD a PIC16F84A

En el diagrama utilizamos el Pin 0 del puerto A para la señal Enable del display y el Pin 1 del mismo puerto para la señal RS.

R/W lo conectamos directamente a GND ya que en este proyecto no leeremos el estado del display en ningún momento.
El puerto B lo dedicaremos enteramente al bus de datos del LCD.

Todos los puertos que no utilizaremos, asi como el RESET del PIC, los conectamos a 5V por medio de un resistor.

Alimentamos todo a 5V por medio de una fuente que puede llegar a ser la Fuente de alimentación y cargador de baterías explicada en este blog y listo.

Pero falta algo, el programa o firmware que hace que el display haga algo... Para eso debemos crear el código, compilarlo y grabarlo en el PIC para que este lo ejecute, nosotros usaremos CCS C .

La rutina que hace esto sería esta:

#include <16f84a.h>
#use delay (clock=4000000)

#define E Pin_A0
#define RS Pin_A1

/*  Declaro las funciones antes de utilizarlas en main()
    para que sean reconocidas  */

void print(int c);
void Enviar(int8 Dato, int1 Comando);
void Iniciar_LCD(void);

//Comienzo del programa

void main(void){
   Iniciar_LCD();                // Inicio el Modulo
   print ("PICROBOT");           // Escribo PICROBOT en la pantalla
}
                                       
//Funciones

void print(int8 c){
   enviar (c,1);                 // Envio caracter c con RS a 1 (dato)
                                 // CCS C se encarga de enviar uno a uno
}                                // los caracteres contenidos en c
                                     
void Enviar(int8 Dato, int1 Comando){
   output_low(E);                // E en bajo
   output_b(Dato);               // Cargo el puerto B con Dato
   output_bit(RS,comando);       // Pongo RS en 0 o 1 dependiendo si es
                                 // un comando o dato lo que estoy
                                 // enviando
   output_high(E);               // E en alto
   delay_us(1);                  // Espero a estabilizar tensión
   output_low(E);                // E en bajo
   delay_us(40);                 // Espero 40 uS a que el LCD trabaje
                                 //
   if (Dato < 4) delay_us(1600); // Si envio un Home o un Clear display
                                 // espero otros 1600 uSegundos que
                                 // sumado a los 40 uS anteriores hacen
}                                // 1.64 mS que es lo que tardan estas
                                 // operaciones

void Iniciar_LCD(void){          //
   delay_ms(15);                 // Espero a que se estabilice
                                 // la tensión.
   
   enviar(0b00000001,0);         // Envio un CLEAR DISPLAY
                                 // (Borra la pantalla)
   
   delay_ms(5);                  // Espero 5 mS
   
   enviar(0b00111000,0);         // Envio un FUNCTION SET para bus de 8
                                 // bits, 2 lineas y caracteres de 5x7
                                 // pixeles.
   
   enviar(0b00001100,0);         // Envio un DISPLAY ON/OFF CONTROL
                                 // con pantalla encendida, Cursor
                                 //  apagado y si parpadear.
   
   enviar(0b00000110,0);         // Envio un ENTRY MODE SET con 
                                 // Incrementa cursor y desplaza cursor
}

Este programa introducido en el PIC conectado al circuito anterior hace que nuestro módulo muestre en pantalla la frase:

PICROBOT

En realidad lo único que hace es inicializar el LCD y mostrar el mensaje, se puede adaptar y hacer que muestre cualquier frase cambiando simplemente la palabra PICROBOT por lo que deseen en la línea:

print ("PICROBOT");

Hay que aclarar que para que funcione hay que respetar las comillas.

Pero si arman el circuito y graban el PIC con la rutina, verán que pueden modificar la frase, pero siempre aparecerá en la primer línea. Si volvemos a Conexión y funciones de un módulo LCD y consultamos dichas funciones, veremos que hay una que se llama SET DD RAM ADDRESS; La memoria DD RAM es la que contiene los caracteres que están en pantalla. De modo que esa función se llama Establecer la dirección de la DD RAM, o sea, que lo que hace es cambiar la posición donde se almacenará el próximo caracter, por lo tanto, lugar donde aparecerá en pantalla.

Para hacer que escriba donde queramos, antes de escribir, deberemos ejecutar un SET DD RAM ADDRESS. Continuando con nuestra rutina lo podemos hacer del siguiente modo:

void locate(x,y){
   int d=128;                // Cargo d con 128 (10000000) b7 a 1
   d+=y*64;                  // si y (linea) es 1 sumo 64 a d (11000000) b6 a 1
   d+=x;                     // a todo esto le sumo la posicion de x
   enviar (d,0);             // envio todo al display con RS a 0 (comando)
}

Entonces si, por ejemplo, queremos escribir Hola en la primer línea y Mundo en la segunda, el main() de nuestra rutina se vería así:

void main(void){
   Iniciar_LCD();             // Inicio el Módulo
   locate(6,0);               // Ubico el cursor en la columna 6
                              // de la primer línea
   print ("HOLA");            // Escribo HOLA
   locate(5,1);               // Ubico el cursor en la columna 5
                              // de la segunda línea
   print ("MUNDO");           // y escribo MUNDO
}

En un display de 16 caracteres x 2 líneas se verá centrada la frase HOLA MUNDO. Cabe destacar que antes de poder utilizar la función locate() se debe declarar mediante la sentencia:

void locate(x,y);

Luego podemos simplificar el borrado de la pantalla (CLEAR DISPLAY) con la función:

void cls(void){
   enviar (1,0);              // envio 00000001 (Clear display) 
}                             // con RS a 0 (comando)

Recuerden que CLEAR DISPLAY era 00000001 que es igual a 1 en decimal. De esta forma y previamente declarado cada vez que querramos borrar la pantalla introduciremos en el código la línea cls(); Por último en la entrada Librería para el manejo de un módulo LCD en CCS C encontrarás todas las funciones y la opción para descargarla.

Fuente de alimentación y cargador de baterías.

Sin duda la mejor forma de obtener energía para nuestros robot es por medio de baterías y como ahora con el auge de los aparatos electrónicos portartiles estas han ido bajando sus precios. Hoy en día es muy fácil conseguir baterías recargables en casi cualquier lado y a un bajo costo... Nosotros nos centraremos en baterías de Ni-MH (Niquel-Hidruro Metálico) por ser la mejor opción en relación precio, capacidad, tamaño y peso.

Estas baterías deben ser cargadas al 10% de su corriente nominal durante un periodo de 10 o 12 horas. Esto significa que si tuvieramos una batería de 1000 mAh (1 Ah) deberíamos cargarla con una corriente de 100 mA (0.1 A) durante ese tiempo.

En el mercado se pueden conseguir baterías de 1.2 V y 2500 mAh, o lo que es lo mismo que son capaces de entregar una tensión de 1.2 volts con una corriente de 2,5 amperes durante 1 hora.

La tensión será costante hasta que la batería se comience a descargar pero la corriente será variable dependiendo el consumo, si el consumo es menor que 2,5 A,  la carga de la batería durará mas de 1 hora y si es mayor de 2,5 A, y si la batería lo soporta, durará menos.

Bueno, hasta aquí un poco de teoría, y seguro que muchísimos de ustedes ya lo sabrán, pero otros no y para el que le sirva, ahí queda... ahora bien, vamos a lo que prometí: La fuente con el cargador y para explicarlo nada mejor que el circuito:


Como pueden ver, es muy sencillo, y contiene componentes muy comunes que son los siguientes:

D1,D2,D3: Diodo 1N4007
C1,C2,C3: Capacitor cerámico o plástico de .1 uF
IC1: LM317
IC2:LM7805
R1: Resistor cuyo valor depende de la capacidad de la batería (ver mas abajo)

El funcionamiento del circuito es muy fácil de entender y se puede separar en dos etapas:

Primer etapa (etapa verde): es la que se encarga de filtrar y regular la tensión. El diodo D2 se encarga de evitar la inversión de polaridad en la batería, el IC2 regula la tensión en 5V y los capacitores (C1 y C2) se encargan hacer el filtrado. Con esta etapa obtenemos 2 tensiones Vcc de 5V y Vss con la misma tensión que la batería (B1) - 0,7V debido a la caída de tensión del diodo.

Segunda etapa (etapa amarilla): Se encarga de cargar la batería y alimentar la etapa amarilla cuando está presente una fuente de alimentación externa, si no hay una fuente externa esta etapa no funciona. El IC1 y la resistencia R1 proporcionan la tensión y corriente necesarias para cargar la batería, mientras que D1 se encarga de evitar que la tensión de la batería regrese al IC. D3 hace que la tensión de la batería no salga por el conector del transformador cuando este no esté conectado, pero a su vez hace que la etapa verde se alimente de la fuente de alimentación externa mientras la batería se carga. Y por último en modo carga el diodo D2 se encarga de que la tensión de la fuente de alimentación externa no ingrese directamente a la batería.

Bien hasta ahi todo claro, ¿no? pero nos queda algo en el aire: ¿y R1 que valor tiene? bueno, eso depende de la batería, en el ejemplo a continuación se supone que la batería tiene una capacidad de 2500mAh.

Para saber el valor del resistor primero debemos saber como funciona el integrado LM317, y para esto nada mejor que la hoja de datos del fabricante (Datasheet), pero como algunos no la entenderán, aquí les dejo una explicación menos técnica.

El integrado en cuestión, al igual que los de la familia LM78xx y LM79xx, es un regulador de tensión, pero la principal diferencia entre uno y otro es que el 317 es variable, obteniendo tensiones de salida desde los 1.2V hasta los 37V, pero por suerte para nosotros esta no es la única aplicación que tiene ya que a nosotros no nos interesa tanto, en este caso, regular la tensión sino regular la corriente y para eso el circuito recomendado por el fabricante es el que aparece en la siguiente figura.

Si observamos la formula dice que la corriente de salida es igual a VRef/R1, Sabemos (gracias a la hoja de datos) que VRef es 1.25 V(típico), pero el dato que nosotros necesitamos es el valor de R1 para eso debemos hacer una transposición de términos ( y es en este momento cuando nos preguntamos "¿por qué no habré prestado mas atención en la escuela primaria?") bueno desempolvando los libros de 5to grado nos enteramos como se hace. Pero ahora tenemos que trabajar con valores.

Io está expresado en amperes y nosotros estamos hablando de miliamperes. Sabemos que 1 A es igual a 1000 mA entonces para 250 mA el valor sería 0,25 A, sabiendo esto tenemos:

Io = 0.25 A
0.25 A = VRef / R1
0.25 A = 1.25 V / R1
0.25 A * R1 = 1.25 V
R1 = 1.25 V /0.25 A

Entonces ya sabemos que R1= 1.25 V/0.25 A que nos da como resultado 5, perfecto, pero... 5 ¿que? bueno son 5 ohm, hay que tener especial cuidado con esto y tener bien claro que valores estamos utilizando, en resumen la formula a usar es:

R = 1.25V / A = Ohm

En conclusión, siempre obtendremos ohmios ingresando amperes, si son 100 miliamperes debemos ingresar 0,1 A y si son 2 Mohm el resultado será 2.000.000 Ohm.

Por último está la cuestión de la asignación de pines, ya que difiere bastante con la de los clasicos LM78xx. En la siguiente figura se observa el pinout.


Hasta aquí esta explicación, y bueno, espero que sea útil, por mi parte este mismo circuito esta alimentando mi robot SiLMuP.Cualquier duda, crítica o sugerencia será bienvenida y los invito a participar...

NOTA: este artículo se ha corregido debido a un error en los datos obtenidos de este datasheet de ST. Como se observa en la siguiente figura, está apuntado el pin 2 como entrada y el pin 3 como salida siendo, en ralidad, al revés. 

LM317 circuito recomendado

Probador de PIC 16X84

Este circuito (de diseño propio, aunque esto no tenga demasiado mérito) te va a permitir probar tus programas, despues de grabarlos en el PIC, sin necesidad de hacer uno específico para cada configuración.
Circuito probador de PIC
El funcionamiento es bastante sencillo y se entiende a simple vista sin tener demasiados conocimientos de electrónica. De todas formas aca va la explicación: Se trata de 13 "puertos" conectados a los 5 RA y los 8 RB del PIC . Cada puerto se puede configurar como entrada o salida, por medio de un jumper o puente, según corresponda. Por ejemplo, si un puente está colocado sobre los pines 1 y 2 del JP1 significa que RA4 es una entrada y será activada por el pulsador S1, en cambio, si el puente se encuentra en los pines 2 y 3 del mismo jumper, RA4 será una salida que encenderá el LED1 cuando se encuentre con un "1 lógico".
Esta es una foto del probador que hice. Está montado sobre una placa perforada de 10x10cm. (esta escrita y tiene manchas de desoldadura porque es una placa reciclada) La diferencia de esta placa con el circuito, es que a la derecha se observan componentes que no figuran en el diagrama. Son los componente que conforman el regulador de voltaje que sirve para poder usar una fuente de entre 5V y 13V (el PIC funciona con 5V) y eliminar ruidos. (Pronto suibiré el circuito)

Tal vez le interese: