Keypad 4x4 en una sola conexión

En esta nota traeré una opción sencilla para leer un teclado de 16 teclas (4x4) mediante una sola conexión, es decir, no necesitamos realizar un barrido matricial de 4x4 que requiere un puerto completo de 1byte para el control.
En este caso la lectura del teclado se realiza mediante un canal del ADC del microcontrolador.
El método utilizado es similar a un DAC ponderado con resistencias pero en sentido inverso, en nuestro caso según la configuración de las resistencias en el teclado tendremos un valor diferente de resistencia que actuara con un pulldown como un divisor resistivo entregándonos un valor de tensión diferente para cada tecla que luego sera leído por el ADC y canalizado por firmware para representar cada una de las 16 teclas.

El teclado 4x4 matricial podremos comprenderlo mejor en la siguiente imagen:



Como podemos ver en la imagen de arriba tenemos una matriz de 4x4 dividida en 4 filas y 4 columnas, donde cada intersección sera un botón que al presionarlo unirá esa intersección de la fila y la columna en cuestión. 


En este caso al presionar el botón que se encuentra señalizado de color rojo, podremos ver como le corresponde la fila y la columna en donde el botón hace intersección.
En el método estándar de lectura de teclado se utiliza un 1byte entero para realizar un barrido de columnas y en función al barrido se testea que fila ha cambiado de estado.
En nuestro caso realizamos un arreglo de resistencias que veremos en el siguiente circuito.



Como podremos ver tenemos un arreglo de resistencias que se encuentran conectadas entre si y que en función de cada botón se sumara un valor diferente de resistencia que a su vez se encuentra conectado a R4 que conforma un pull down pero a la vez la resistencia resultante del botón presionado junto a la resistencia R4 conforman un divisor de tensión resistivo, ya que como podremos ver hay una toma de tensión que sera de 5V, quedando así, el nodo de salida que ingresara al ADC del MCU.



En esta nueva imagen podemos ver el primer ejemplo donde presionábamos la misma tecla pero en este caso podremos analizar el recorrido de la corriente desde los +5V hasta el GND pasando por el nodo que sera la salida del divisor de tensión.
En este ejemplo tenemos R1=4k7, R6=1k, R5=1k y R4=10, si sumamos los valores (despreciando la impedancia de contacto del botón), tendremos R1+R5+R6=6700R si aplicamos la ecuación de divisor de tensión suponiendo Vdd=5V, Vsalida=Vdd*(R4/((R1+R5+R6)+R4))=5V*(10k/(6k7+10k))=5V*0.598=2.99V
Entonces en salida tendremos al rededor de 3V que ingresaran en el ADC para luego ser procesados en el firmware.
De esta misma manera realizaremos la combinación de las 16 tecas y los 16 valores de tensión que nos dará el divisor resistivo.



Aquí podremos ver el resto del circuito que en este caso lo he realizado con este microcontrolador porque lo he probado en protoboard y es el que tenia a mano, pero podríamos usar un MCU de 8 o 14 pines y nos alcanzaría para el teclado y alguna otra función siempre que cuente con ADC claramente.

En este gif he realizado una captura del simulador Proteus para que sea mas sencillo de comprender, pero después lo veremos en el vídeo.


Antes de analizar el programa, hay que mencionar que para que este proyecto funcione, hay que tomar los 16 valores de cada tecla antes de asignarle un valor en el programa, es decir, nosotros tendremos por ejemplo para el numero 6 del teclado 3V entonces cuando el ADC lea esos 3V debemos asignarle el valor 6, ya que no es la forma en la que el microcontrolador relaciona la tensión con la tecla.
Para ello, debemos montar el circuito tal cual lo vamos a utilizar después, y presionar tecla por tecla, en el primer renglón del LCD saldrá el valor del ADC (en nuestro caso de 0 a 255, ya que esta trabajando en 8bit).
Una vez que tenemos los 16 valores de cada tecla, podremos asignar cada valor.
Pero recordemos que este es un sistema analógico, por ende, la tensión puede variar, porque simplemente puede variar la tensión de la fuente o algún otro componente.
Entonces para corregir la posible variación de tensión de cada botón, debemos definir un rango para cada asignación. 
En nuestro ejemplo medimos 2.99V para la tecla 6 pero podría ir desde 2.90 hasta 3.10V y ese rango es necesario incluirlo en el programa para que el sistema tenga tolerancia y no se asignen valores erráticos.
Para ello realizaremos un arreglo de vectores.

  1. #include <16F883.h>
  2. #device adc=8
  3. #use delay(int=4000000)
  4. #include <LCD.C>
  5. #define LED PIN_A1
  6. void main(){
  7.    setup_adc_ports(sAN0|VSS_VDD);
  8.    setup_adc(ADC_CLOCK_DIV_2);
  9.    lcd_init();
  10.    int i;
  11.    int8 salida;
  12.    char caracter;
  13.    const int keyValueMinor[17]=
  14. {0  ,54 , 56, 59, 62, 68, 73, 77, 83, 92,102,112,124,150,170,200,240};
  15.    const int keyValueMajor[17]=
  16. {53 ,56 , 58, 61, 67, 72, 76, 82, 90,100,110,120,132,160,190,220,255};
  17.    const char   KeySimbols[17]=
  18. {'_','D','#','0','*','C','9','8','7','B','6','5','4','A','3','2','1'};  
  19.    while(true){
  20.       set_adc_channel(0);
  21.       salida=read_adc();
  22.       delay_us(30);
  23.       for(i=0;i<18;i++){
  24.          if(salida>keyValueMinor[i]&&salida<keyValueMajor[i])
  25.             caracter=KeySimbols[i];
  26.          delay_ms(1);
  27.       }
  28.       lcd_gotoxy(1,1);
  29.       printf(lcd_putc,"Valor: %3u",salida);
  30.       lcd_gotoxy(1,2);
  31.       printf(lcd_putc,"Caracter: %c",caracter);
  32.       output_toggle(LED);
  33.    }
  34. }

Explicare el núcleo del programa ya que el resto es configuración y declaración.
El núcleo del programa se encuentra definido por el lazo for de iteración que va hasta 17 (cuando es 18 sale), pero porque no va hasta 16?, porque cuando no presionamos ningún botón la salida del divisor resistivo tendrá un valor de tensión por defecto, entonces ese valor para el teclado en reposo sera nuestro valor 17.
Tenemos 3 vectores que funcionaran a la par, es decir los tres vectores tendrán siempre el mismo indice que sera a la vez el valor de iteración del lazo for.
keySimbols es el vector que aloja los valores del teclado (los números, letras o símbolos) y luego tenemos otros dos vectores, keyValueMinor y keyValueMajor que serán los dos vectores que comentaba antes, con los valores máximos y mínimos de tolerancia del valor leído. 
Como podremos ver en la practica el número 6 se encuentra entre 102 y 110 (estos valores están en decimal de 0 a 255, que son los valores que entrega el ADC).
Entonces si analizamos el indice 10 del for (cuando este itere hasta llegar al 10) tendremos una pregunta mediante el if, que sera si el valor del adc (nombrado salida) es menor que keyValueMajor[10] y menor que keyValueMinor[10], entonces asignaremos a nuestra variable de salida (carácter) el valor keySimbols[10] que corresponde al numero 6. 

  1.          if(106>102&&106<110)
  2.             caracter=6;

Luego en el programa mostraremos los valores en el LCD, en el primer renglón el valor del ADC y en el segundo valor el carácter que nos devuelve el lazo for.




Fuente SMPS Boost con 555 y Feedback

Esta fuente es otra versión de la fuente SMPS con 555 que he publicado pero le he agregado un feedback que controla mediante un transistor en emisor común la entrada de control de 555 que si recordamos el diagrama de bloques del mismo, esta influye directamente en la tensión de referencia de uno de los comparadores que forma parte de la temporización del 555, entonces si nosotros dejamos la entrada de control libre sin conexión entonces el temporizador funcionara en base al valor de R1, R2 y C, pero si le modificamos la polarización en la entrada de control, esta misma influye con el comparador y modifica la tensión, por ende la frecuencia o ciclo de trabajo.



En una fuente SMPS la frecuencia y el ciclo de trabajo son vitales en el comportamiento del choque inductivo que es en consecuencia el que nos proporciona la tensión de salida.
Al utilizar el transistor en emisor común conectado al control y controlar el mismo desde la tensión de salida, lo que hacemos es variar esa tensión de control en función de la tensión que tenemos en la salida de la fuente generando un lazo re-alimentado de tensión que nos proporciona una estabilidad mayor en nuestra fuente, de otro modo la misma quedaría libre y podría ser peligroso para la carga que le conectemos como así también para los componentes de salida de la fuente.

Hay que recordar que una fuente SMPS a diferencia de una fuente lineal convencional maneja una frecuencia mucho mayor, esto se hace para reducir el tamaño y peso de los componentes, sobre todo del transformador que suele ser la parte mas pesada de una fuente, entonces si para 50Hz necesitamos un transformador de 10cm cúbicos para una fuente de 12V 4A, en una fuente SMPS necesitaríamos uno de 3cm cúbicos para la misma potencia, y esto se logra achicando el transformador, pero para usar menos cantidad de espiras en los devanados debemos aumentar la frecuencia de operación, ya que a menor cantidad de espiras sera menor la inductancia y mayor la frecuencia (si queremos mantener la misma reactancia inductiva). El uso de frecuencias altas (promedio de 100kHz) también requiere un cambio en el núcleo para que no se sature y para que la permeabilidad sea adecuada, entonces también debemos cambiar el núcleo de hierro por ferrita (Entre otros).
Entonces así reducimos el peso y el tamaño de la fuente.

En nuestro circuito de prueba estamos configurando el 555 a unos 200kHz y estamos usando una bobina con núcleo de ferrita toroidal realizadas a mano de unos 150uH para 2A.
Si alimentamos el circuito con 5V tenemos que calcular la reactanca inductiva del choque para saber que corriente esta circulando por el MOSFET (que recordemos que es un IRFZ44N, un poco grande para este proyecto pero es el que tenia a mano).
La reactancia sera XL=2*pi*f*L en nuestro caso sera XL=2*3.1415*200000Hz*0.00015H=188 Ohms, entonces si alimentamos este circuito (suponiendo que el MOSFET no tiene caída de tensión ya que en Clase E el mismo tiene una impedancia del orden de los 17mOhms aproximadamente) con 5V tendremos por ley de Ohm I=V/R=5V/188R=0.027A=27mA pero esta sera la corriente que circula por el transistor y el choque, la que se drena al diodo sera un poco menor al rededor del 80% de esta, por ende tendremos 21mA aproximadamente.
Para tener un valor de corriente mas útil, tendríamos que modificar tanto la frecuencia (reducirla) como la inductancia (reducirla), por ejemplo a 80kHz y 10uH tendremos una reactancia de unos 5 Ohms, entonces para 5V tendremos unos 800mA de corriente en la salida.



Notase que hay un puente de color amarillo para unir la masa del preset y transistor con el resto de la masa.



Placa de desarrollo USB para PIC16F876A


En esta nota les traeré un proyecto completo que a mi me ha servido para realizar algunos proyectos de forma rápida y sencilla, al igual que para dar cursos de CCS y MCUs.
Se trata de una placa de desarrollo (similar a Arduino) en base a Microchip, en este caso estoy utilizando un 16F876A (porque este micro?, porque tenia muchos, pero sinceramente tendría que actualizarlo al 16F883 o 16F886 que el costo es menor y que poseen mas prestaciones).
La placa al igual que Arduino, posee el microcontrolador, una fuente de alimentación y un puente USB/UART.
El puerto USB se encuentra gobernado por el MCP2200 también de microchip y el mismo posee una salida UART Tx y Rx. 
Para aprovechar este puerto se implementa un Bootloader (programa cargador de arranque que sirve para programar el microcontrolador desde el puerto serie en lugar de los pines dedicados para este uso). 
Al utilizar Bootloader y cargar el programa desde el puerto UART, tenemos la posibilidad de usar el USB tanto como carga de programa como también para un monitor serial (De la misma forma que Arduino). 
La carga del programa se realiza con un programa realizado en Delphi que no es mas que un lanzador del puerto serie virtual y el envió de los datos en hexadecimal (código compilado).
Para que comience la programación debemos presionar el botón Reset de la placa y luego se cargara el programa. 
Esta placa puede ser programada en cualquier lenguaje, ya que solamente necesitamos el .hex para luego cargarlo en la misma. Aunque el microcontrolador requiere una única programación con un programador de microchip para cargarle por única vez el Bootloader en su memoria.

Los fuentes se encuentran disponibles en el siguiente LINK

La placa se alimenta directamente del puerto USB, por lo que no podremos extraer mas de 400mA para el uso de periféricos del mismo. En caso de necesitar mas corriente debemos utilizar una fuente externa y unir las masas.

A continuación dejare el Bootloader para copiarlo desde aquí (el mismo se encuentra a 9600bps), es necesario saber el baudrate ya que cuando descarguemos el driver para el MCP2200 lo debemos configurar a 9600bps.

En este link encontrara el driver para el MCP2200.

  1. :020000040000FA
  2. :0800000000008A150A16882E83
  3. :103D00008A150A16802E8A018A150A16832E00004B
  4. :103D1000031E832E903098008316181598161930BC
  5. :103D2000990083120330FA00113090000C14EC2635
  6. :103D3000EA3A031DAF2EFA01B62EEC26F900E33A5B
  7. :103D40000319B82E7908EA3A0319B62E7908ED3A24
  8. :103D5000031D9D2EE430E7260330FA00EC26900187
  9. :103D600098018316980183128C01832EEB30E52E87
  10. :103D7000EC26F600EC26F500EC26F100FB00EC2624
  11. :103D8000F300F20121308312031376020319D12EBE
  12. :103D900075080339FC00FD000310FC0D20307C0782
  13. :103DA000D22E20308400EC268000F207840AFB0B20
  14. :103DB000D32E72087306E830031DE52EE730E726A0
  15. :103DC000FE260038E4300319E530E7269D2E640016
  16. :103DD0000C1EE72E9900080064007A080319FA2ED9
  17. :103DE0000C1CFA2E1010FA0BF62E00340C103C307E
  18. :103DF0008F0010148C1EEC2E1A0808002130760259
  19. :103E00000319502F831603178C1783120313750899
  20. :103E1000FC3903178D000313760803178F00203039
  21. :103E2000840003137D080319282F831603170C142D
  22. :103E30000000000083120E088000840A0C08800035
  23. :103E4000840A8D0A0313FD03F503F10AF10A112F09
  24. :103E50007108FC00203E84000310FC0C7608031758
  25. :103E60008F000313750803178D0003137C080317D5
  26. :103E70008D0703198F0A03170D0803390319502FF3
  27. :103E800083160C140000000083120E088000840AC0
  28. :103E90000C088000840A8D0A0313F10AF10A3B2FF3
  29. :103EA0007508F7007608F800FB010230F40071088D
  30. :103EB0007B02031801347B08203E84002130780205
  31. :103EC0000317831603196E2F8C1783011E30780297
  32. :103ED0008030031977020318B62F702F8C138301DB
  33. :103EE000770803178D0003137808031D852F04300E
  34. :103EF00077020318852F031783168C1F822F8312D6
  35. :103F000084308D0783011E30862F780803178F00B9
  36. :103F100000088E00840A00088C0083160C155530AA
  37. :103F20008D00AA308D008C140000000083018316E0
  38. :103F300003178C1BBE2F8312031364000D1E9D2FCD
  39. :103F40000D12831603170C110C14000000008312CD
  40. :103F5000840300080E06031DB22F840A00080C0615
  41. :103F60000319B62F8301F40B572F00348312031368
  42. :103F70000230FB07F70A0319F80A552F83120313BF
  43. :103F80000D12831603170C11831203170D08033942
  44. :103F9000033C031DB62F03308D028312031304303C
  45. :103FA000FC00073084020000831603170C14000085
  46. :103FB000000000000000000000000008831203174A
  47. :103FC0000E06031DE82F840A00080C060319EF2FC4
  48. :103FD00083120313FC30F7050630FB02B22F831265
  49. :103FE00003178D0A840A83120313FC0BD32FB62FF9
  50. :084000000200010000000000B5
  51. :02400E00313F40
  52. :00000001FF

Al momento de soldar la placa, debemos tener en cuenta que el MCP2200 viene en encapsulado SOIC y debe soldarse del lado de abajo del mismo (Bottom), se ha realizado asi para usar un PCB de un simple layer.
Podremos ver esto en la vista 3D Top y Bottom.





Algunas fotos de la placa funcionando