Hace tiempo hice una calculadora para mi uso interno la cual calculaba los valores que había que poner a un timer de un microcontrolador PIC (con su preescaler, su frecuencia, etc) para llegar a un retardo determinado, o viceversa, dado un valor del timer calcular qué retardo provoca. Es muy sencilla y está hecha integramente en html y javascript:
Archivo de la etiqueta: pic
Interactuar con la videocámara MD80 y un microcontrolador
Hace poco escribí una reseña sobre el clon de la videocámara MINIDV MD80. Al ser una videocámara de tamaño reducido se puede usar en los proyectos de electrónica que queramos, sin embargo su autonomía viene marcada por la batería que contiene, además de que el proceso de encendido/apagado y grabación/parada es manual. Mi intención ha sido sustituir la batería por otra fuente de alimentación (una batería más grande, un transformador de la corriente eléctrica, etc) y que tanto el encendido como la grabación se hagan a través de un microcontrolador. En este artículo voy a explicar los pasos que he seguido para conseguir mi objetivo.
En principio he desmontado la carcasa de la videocámara y he extraido la electrónica y la batería:
He desoldado la batería y en su lugar he puesto dos cables para unirlos a una protoboard (aunque podrían soldarse a una placa de topos o a una pcb). Después he soldado dos cables de wrapping a los terminales traseros del botón de encendido y otro cable de wrapping al terminal trasero izquierdo del botón de grabación:
A partir de aquí ya se puede usar la cámara con un microcontrolador. Para este artículo me he decantado por un pic 12f683. La idea es usar dos transistores NPN para que hagan la simulación de pulsar tanto el botón de encendido como el de la grabación, para este artículo he usado 2 BC547. El microcontrolador activará la base del transistor a través de una resistencia de 390K. y comunicará el colector con el emisor como si de una pulsación manual del botón se tratase. Sólo hay que tener en cuenta que para el botón de encendido, el cable de wrapping de la derecha tiene que ir al colector y el cable de la izquierda al emisor, y en el botón de grabación el único cable va al colector y el emisor va a masa (GND).
La batería que trae la videocámara es una LiPo de una sola celda y tiene una capacidad de 230 mAh. Esto nos da la pista de que a la cámara debemos alimentarla con una tensión de 3,7 v. Para ello he usado un regulador Step-Down basado en el chip AX3022 de sure electronics. Este regulador ofrece hasta 1,5 A., más que suficiente para alimentar la videocámara y el microcontrolador (que puede funcionar a 3,7 v.).
Finalmente así queda el conjunto en una protoboard:
El ejemplo que he programado en el microcontrolador es muy sencillo: Espera 5 segundos, activa el transistor del botón de encendido durante medio segundo, esto hace que la videocámara se encienda, espera otros 5 segundos, activa el transistor del botón de grabación durante medio segundo, esto hace que la videocámara empiece a grabar, espera 10 segundos, activa el transistor del botón de grabación durante medio segundo, esto hace que la grabación pare, espera 5 segundos y finalmente activa el transistor del botón de encendido durante medio segundo, que provoca que la videocámara se apague:
El código fuente del programa del pic:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include "main.h" void power() { output_high(PIN_A0); delay_ms(500); output_low(PIN_A0); } void record() { output_high(PIN_A1); delay_ms(500); output_low(PIN_A1); } void main() { setup_adc_ports(NO_ANALOGS|VSS_VDD); setup_adc(ADC_OFF); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC); setup_vref(FALSE); setup_oscillator(OSC_8MHZ); // TODO: USER CODE!! set_tris_a(0); output_a(0); delay_ms(5000); power(); delay_ms(5000); record(); delay_ms(10000); record(); delay_ms(5000); power(); for(;;); } |
Cuando vayamos a conectar la videocámara a un puerto USB para ver las grabaciones, no debemos olvidarnos de desenchufar los cables de alimentación que hemos soldado, ya que la fuente de alimentación ya no es la batería original que contenía.
Alarma con un pic 16f628, un transceptor ds275, sensor de movimiento y un modem antiguo
Tenía un modem externo antiguo de 2400 b.p.s. que me regalaron y se me ocurrió la idea de usarlo para crear una alarma. Los bueno de los modems es que puedes interactuar con la línea telefónica para hacer llamadas.
La idea consiste en que un sensor de movimiento piroeléctrico de infrarrojos (PIR) detecte el movimiento de una persona en una sala, este informaría de la detección a un pic y este sería el encargado de llamar a un número de teléfono a través del modem.
El matería que he usado es:
- Sensor de movimiento piroeléctrico de infrarrojos (PIR) de sure electronics DC-SS502 ( http://www.sureelectronics.net/goods.php?id=932 )
- Microcontrolador PIC 16f628A ( http://www.microchip.com/wwwproducts/devices.aspx?ddocname=en010210 )
- Transceptor ds275 ( http://www.maxim-ic.com/datasheet/index.mvp/id/2929 )
- Una placa de topos, cable, un conector serie db9 macho y un modem externo
Para hacer el circuito lo más sencillo posible he usado un pic 16f628a dado que con él podemos ahorrarnos el poner un cristal de cuarzo externo, poder desactivar el pin MCLR y usar la USART que trae consigo (podría haber usado un pic 16f88 igualmente). También he usado el transceptor ds275 porque se puede comunicar con un puerto serie como el del modem sin añadirle ningún condensador como ocurre con el MAX232. Como no quería depender de una fuente de alimentación externa, he soldado unos cables al modem para obtener de este los 5 voltios necesarios para el pic y el transceptor y para la alimentación de 9 voltios del sensor PIR.
Este es el esquema del circuito:
El sensor PIR tiene una salida digital que va conectada al pin RB0 del pic, que se puede programar como interrupción, por lo que el pic puede permanecer en modo sleep hasta que recibe la interrupción del sensor y empezar a mandar los comandos AT para hacer la llamada de alarma. Como el PIC no puede por sí sólo interactuar con un puerto serie, el transceptor convierte las señales del PIC a señales RS232 para enviárselas al puerto serie del modem y viceversa. Una vez que se ha hecho la llamada y el modem detecta que se ha colgado la linea, devolverá un código numérico que el pic recibirá para volver a dejar el sistema en modo de detección.
Foto del conjunto:
Un video de demostración:
Lo que sucede en el video es lo siguiente: Se enciende el modem y el pic configura este para que no tenga eco los comandos, para que devuelva respuestas numéricas y que el altavoz esté desactivado, después de 15 segundos de espera para que el usuario pueda abandonar la habitación el pic se pone a esperar la detección de movimiento, cuando la detecta llama a un número de móvil prefijado para que el usuario reciba la alerta.
El código fuente del pic esta programado en CCS y es el siguiente:
main.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <16F628A.h> #FUSES NOWDT //No Watch Dog Timer #FUSES INTRC //Internal RC Osc #FUSES NOPUT //No Power Up Timer #FUSES NOPROTECT //Code not protected from reading #FUSES NOBROWNOUT //No brownout reset #FUSES NOMCLR //Master Clear pin used for I/O #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES NOCPD //No EE protection #use delay(clock=4000000) #use fast_io(b) #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8) typedef enum {INICIO, DETECTA, ALARMA, LLAMADO} ESTADOS; |
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
#include "main.h" ESTADOS estado; volatile int8 dato; // se ha detectado un movimiento y se pasa al estado de alarma #INT_EXT void movimiento() { if(estado == DETECTA) { estado = ALARMA; } } // se ha detectado un carácter en la cola la USART #INT_RDA void lectura() { int8 valor; if(kbhit()) { valor = getc(); if(valor != '\r') { dato = valor; } } } // función genérica que pasa al estado de detección borrando cualquier interrupción anterior y activándola void deteccion() { estado = DETECTA; clear_interrupt(int_ext); enable_interrupts(int_ext); } void main() { setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_oscillator(OSC_4MHZ); // Ponemos a todos los pines del puerto B como entrada excepto el de salida de la USART set_tris_b(0xFB); // Empezamos por el estado de inicio estado = INICIO; // La interrupción debe ser cuando pasa de nivel bajo a nivel alto ext_int_edge( L_TO_H ); enable_interrupts(int_rda); enable_interrupts(global); // TODO: USER CODE!! for(;;) { switch(estado) { // En el estado de inicio inicializamos el modem para que no haga eco de los comandos, // los valores de respuesta sean numéricos y apague el altavoz del modem, esperando // 15 segundos para dejar salir al usuario de la sala y pasamos al estado de detección case INICIO: delay_ms(2000); printf("ATE0V0M0\r"); delay_ms(13000); deteccion(); break; // En el estado de detección esperamos la interrupción en modo sleep para consumir menos case DETECTA: sleep(); break; // Se desactiva la interrupción y marcamos el número de teléfono que queramos alertar case ALARMA: disable_interrupts(int_ext); dato = 'A'; printf("ATDTXXXXXXXXX\r"); estado = LLAMADO; break; // Esperamos a que termine la llamada para que vuelva al estado de detección case LLAMADO: if(dato != 'A') { deteccion(); } } } } |
Sólo comentar que XXXXXXXXX hay que sustituirlo por el número de teléfono al que queramos dar la alarma.
Reloj termómetro con PIC 16F628
Recientemente he creado un reloj-termómetro hecho con un PIC 16F628A, un sensor de temperatura i2c DS1624, un reloj en tiempo real i2c DS1307 y un LCD de 16×2 compatible con Hitachi HD44780.
El sistema, una vez encendido, muestra la fecha y hora, la temperatura junto con los valores máximo y mínimo que alcanza y finalmente un mensaje personalizado. Aquí hay un video que he grabado del mismo:
El esquema del circuito es el siguiente:
Y desde aquí os podeis bajar el .hex y el código fuente (CCS C)
La fecha y hora se configuran con sólo un botón pulsador que está conectado a RB0 y que funciona por temporización e indexación. Es decir, si tu pulsas la primera vez el botón, se mostrará en el LCD la fecha y hora y el indice 0, que indica que vas a modificar el día, entónces si pulsas dentro de los dos segundos siguientes el botón, el día se incrementará, si no lo pulsas, el indice se incrementará a 1 y se podrán modificar los meses de igual manera. Así hasta llegar al indice 5 que son los segundos y después mostrará la fecha y hora actualizadas renovandose cada segundo.
A los diez segundos de mostrar la fecha y hora se muestra la temperatura actual junto con los valores máximo (M) y minimo (m) que se han alcanzado. Si son los 30 primeros segundos de medianoche se resetearán esos valores.
A los diez segundos de mostrar la temperatura, se mostrará un mensaje personalizado que se ha guardado en la EEPROM al programar el PIC. Pasados cinco segundos vuelve a mostrar la fecha y hora.
El PIC usa el oscilador interno de 4Mhz. El programa ocupa un 98% de su memoria de código. Aunque en el video vereis que hay un interruptor de encendido/apagado, un led indicador de encendido/apagado y unas resistencias variables para el LCD, con lo que hay en el esquema es suficiente para funcionar. Vcc son 5 voltios conseguidos a través de un 7805.