| |
PROYECTO
: Temporizador para Insoladora v.2.0
|
|
| |
por Daniel González (RADON) |
|
|
|
Temporizador para Insoladora v.2.0
|
| |
Descripción y
características del proyecto:
|
|
|
|
|
-
Si aceptamos (abre el relé) nos pide el tiempo para insolar, este
permanece visible (multiplexando) y parpadea el digito a variar, con los
pulsadores +/-1 y aceptar para saltar al siguiente, hasta que pulsamos
siguiente. Si ya pre-insolamos al menos una vez, este rescata el tiempo de
la EEPROM.
|
|
|
-
Muestra listo, y al
pulsar de nuevo empieza a contar. Al finalizar suena una alarma en el
zumbador, y si es a dos caras muestra el texto, vuelve a contar el
tiempo y de nuevo la alarma. Al final del todo se resetea el
PIC.
|
Algunas consideraciones:
|
|
|
Esquema :
|
Pulsar sobre la imagen para
ver a tamaño completo:
|
|
Esquema del circuito de
control
|
|

|
|
Esquema del circuito de Displays
|
|
 |
| |
Placa de circuito
impreso (PCB):
|
Pulsar sobre la imagen para
ver a tamaño completo:
|
|
 |
| |
| Descargar
Fotolito
en formato PDF |
| |
Fotografía
funcionado: |
| |
Pulsar sobre las imágenes para
verlas a tamaño completo:
|
|


 |
| |
Lista de Componentes: |
| |
Partlist
Exported from esquema.brd at 19/04/2006 18:32:45
EAGLE Version 4.13 Copyright (c) 1988-2004 CadSoft
Part Value Package
Library Position (mm)
Orientation
C1 22pF
C050-025X075 rcl
(72.39 33.02) R90
C2 22pF
C050-025X075 rcl
(74.93 33.02) R270
C3 100nF
C050-025X075 rcl
(74.93 54.61) R180
CARGA1
AK300/2 con-ptr500
(13.97 69.85) MR180
CARGA2
AK300/2 con-ptr500
(26.67 69.85) MR180
D1 1N4004 DO41-10
diode (13.97 34.29)
R0
D2 1N4148 DO35-10
diode (43.18 45.72)
R90
D3 1N4004 DO41-10
diode (26.67 34.29)
R0
IC1 PIC16876 DIL28-3
microchip (68.58 45.72) R0
JP1 ICSP 1X05
pinhead (38.1 45.72)
R90
JP2
1X12 pinhead
(104.14 46.99) R90
JP3 amarillo 1X02
pinhead (35.56 72.39)
R90
JP4 blanco 1X02
pinhead (41.91 72.39)
R90
JP5 verde 1X02
pinhead (48.26 72.39)
R90
JP6 rojo 1X02
pinhead (54.61 72.39)
R90
K1 E3206S E3206S
relay (13.97 41.275)
R90
K2 E3206S E3206S
relay (26.67 41.275)
R90
POWER
AK300/2 con-ptr500
(45.72 29.21) MR0
Q1 4 Mhz HC18U-V
crystal (80.01 33.02)
R270
Q2 BC338 TO92-EBC
transistor-npn (77.47 59.69) R270
Q3 BC338 TO92-EBC
transistor-npn (85.09 59.69) R270
Q4 BC338 TO92-EBC
transistor-npn (92.71 59.69) R270
Q5 BC338 TO92-EBC
transistor-npn (100.33 59.69) R270
Q6 2N2222A TO18
transistor-npn (30.48 29.21) R90
Q7 2N2222A TO18
transistor-npn (24.13 29.21) R90
R1 100
0207/10 rcl
(52.07 57.15) R90
R2 100
0207/10 rcl
(54.61 57.15) R90
R3 4k7
0207/10 rcl
(45.72 45.72) R270
R4 470
0207/10 rcl
(48.26 45.72) R270
R5 2k2
0207/10 rcl
(67.31 26.67) R90
R6
0207/10 rcl
(96.52 33.02) R0
R7
0207/10 rcl
(96.52 35.56) R0
R8
0207/10 rcl
(96.52 38.1) R0
R9
0207/10 rcl
(96.52 40.64) R0
R10
0207/10 rcl
(96.52 43.18) R0
R11
0207/10 rcl
(96.52 45.72) R0
R12
0207/10 rcl
(96.52 48.26) R0
R13
0207/10 rcl
(96.52 50.8) R0
R14 2k2
0207/10 rcl
(72.39 64.77) R270
R15 2k2
0207/10 rcl
(80.01 64.77) R270
R16 2k2
0207/10 rcl
(87.63 64.77) R270
R17 2k2
0207/10 rcl
(95.25 64.77) R270
R18 2k2
0207/10 rcl
(64.77 26.67) R90
S1
B3F-10XX switch-omron (40.3225 59.69)
R270
SG1 F/QMX F/QMX
buzzer (63.5 67.31)
R270
|
| |
| |
| |
Programa tempo.c |
|
| |
//*******************************************************************
//* Temporizador para insoladora, 4 displays 7 segmentos mux
//* *****************************************************************
//* Por Daniel González, Dic 2005 RADON
//********************************************************************
#include <16F876.h>
#fuses XT,NOWDT,PUT,NODEBUG, NOPROTECT,NOBROWNOUT,NOLVP
#use delay (clock=4000000) // 1uS/instrucción
#include <TONES.C> // Zumbador
#include <internal_eeprom.c>
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 5
#byte port_b = 6
#byte port_c = 7
#define Rele_On output_high(PIN_A5) // Se usará para conmutar la luz
#define Rele_Off output_low(PIN_A5)
#define Rele2_On output_high(PIN_B1) // Se usará para conmutar el ventilador
#define Rele2_Off output_low(PIN_B1)
#define Disp1_On output_high(PIN_A0) // Disp izq
#define Disp1_Off output_low(PIN_A0)
#define Disp2_On output_high(PIN_A1)
#define Disp2_Off output_low(PIN_A1)
#define Disp3_On output_high(PIN_A2)
#define Disp3_Off output_low(PIN_A2)
#define Disp4_On output_high(PIN_A3)
#define Disp4_Off output_low(PIN_A3) // Disp drcha
#define Puls_Amarillo PIN_B7 //+1
#define Puls_Blanco PIN_B6 //-1
#define Puls_Verde PIN_B5 // OK, Aceptar
#define Puls_Rojo PIN_B4 // Siguiente
#define antirebotes 50 // para los delays antirebotes en ms
// Código para los displays 7-segmentos
**************************************
#define cero 0x3F
#define uno 0x06
#define dos 0x5B
#define tres 0x4F
#define cuatro 0x66
#define cinco 0x6D
#define seis 0x7D
#define siete 0x07
#define ocho 0x7F
#define nueve 0x6F
#define a7 0x77
#define b7 0x7C
#define c7 0x39
#define d7 0x5E
#define e7 0x79
#define f7 0x71
#define g7 0x3D
#define h7 0x76
#define i7 0x06
#define j7 0x1F
#define l7 0x38
#define n7 0x54
#define o7 0x5C
#define p7 0x73
#define q7 0x67
#define r7 0x50
#define s7 0x6D
#define t7 0x78
#define u7 0x3E
#define punto 0x80
#define espacio 0x00
#define fin_mensaje 0xFF
//****************************************************************************
int1 fin_cuenta;
unsigned int16 i;
unsigned int8 min_x10=0, min=0, seg_x10=0, seg=0;
unsigned int8 contador=125, display=1, caras=1;
//*** carácteres y digitos 7-segmentos ***
// Para el correcto funcionamiento de las librerías, los vectores de
mensajes
// deben acabar por "fin_mensaje" (0xFF)
int mensaje[35];
const int numeros[]={cero,uno,dos,tres,cuatro,cinco,seis,siete,ocho,nueve};
const int bienvenida[]={i7,n7,s7,o7,l7,a7,d7,o7,r7,a7,espacio,p7,o7,r7,espacio,
d7,a7,n7,i7,e7,l7,espacio,g7+punto,espacio,espacio,fin_mensaje};
const int calentar[]={c7,a7,l7,e7,n7,t7,a7,n7,d7,o7+punto,espacio,a7,c7,c7,e7,p7,t7,a7,r7,
espacio,p7,a7,r7,a7,espacio,a7,c7,a7,b7,a7,r7+punto,espacio,
espacio,fin_mensaje};
const int una_cara[]={uno,espacio,c7,a7,r7,a7+punto,espacio,espacio,fin_mensaje};
const int dos_caras[]={dos,espacio,c7,a7,r7,a7,s7+punto,espacio,espacio,fin_mensaje};
const int msj_listo[]={l7,i7,s7,t7,o7+punto,punto,punto,espacio,espacio,fin_mensaje};
const int msj_segunda_cara[]={s7,e7,g7,u7,n7,d7,a7,espacio,c7,a7,r7,a7+punto,espacio,espacio,fin_mensaje};
#INT_RTCC
void control_rtcc(void)
{
set_timer0(131);
if(contador == 0){
contador = 125;
if(seg > 0){
--seg;
}
else{
if(seg_x10 > 0){
--seg_x10;
seg = 9;
}
else{
if(min > 0){
--min;
seg_x10 = 5;
seg = 9;
}
else{
if(min_x10 > 0){
--min_x10;
min = 9;
seg_x10 = 5;
seg = 9;
}
else{
fin_cuenta =
1;
}
}
}
}
}
--contador;
}
#INT_RB
void control_rb(void){
if(!input(Puls_Amarillo)){ // +1
switch(display){
case 1: if(min_x10 < 9) ++min_x10;
else min_x10 = 0;
break;
case 2: if(min < 9) ++min;
else min = 0;
break;
case 3: if(seg_x10 < 5) ++seg_x10;
else seg_x10 = 0;
break;
case 4: if(seg < 9) ++seg;
else seg = 0;
break;
}
while(!input(Puls_Amarillo));
delay_ms(antirebotes);
}
if(!input(Puls_Blanco)){ // -1
switch(display){
case 1: if(min_x10 > 0) --min_x10;
else min_x10 = 9;
break;
case 2: if(min > 0) --min;
else min = 9;
break;
case 3: if(seg_x10 > 0) --seg_x10;
else seg_x10 = 5;
break;
case 4: if(seg > 0) --seg;
else seg = 9;
break;
}
while(!input(Puls_Blanco));
delay_ms(antirebotes);
}
if(!input(Puls_Verde)){
if(display < 4) ++display;
else display = 1;
while(!input(Puls_Verde))
delay_ms(antirebotes);
}
}
void alarma(void){
int1 sw=0;
while(1){
generate_tone(3000,100);
if(!input(Puls_Verde) || !input(Puls_Rojo)){
while(!input(Puls_Verde) || !input(Puls_Rojo))
delay_ms(antirebotes);
return;
}
generate_tone(4000,100);
if(!input(Puls_Verde) || !input(Puls_Rojo)){
while(!input(Puls_Verde) || !input(Puls_Rojo))
delay_ms(antirebotes);
return;
}
delay_ms(100);
if(!input(Puls_Verde) || !input(Puls_Rojo)){
while(!input(Puls_Verde) || !input(Puls_Rojo))
delay_ms(antirebotes);
return;
}
}
}
void pinta_disp1(int x){
port_c = x;
Disp1_On;
delay_ms(2);
Disp1_Off;
}
void pinta_disp2(int x){
port_c = x;
Disp2_On;
delay_ms(2);
Disp2_Off;
}
void pinta_disp3(int x){
port_c = x;
Disp3_On;
delay_ms(2);
Disp3_Off;
}
void pinta_disp4(int x){
port_c = x;
Disp4_On;
delay_ms(2);
Disp4_Off;
}
// Esta función rota un mensaje en los displays 7 segmentos, el último
// elemento del array deberá ser 0xFF (siendo estos los valores para los
displays),
// acepta:
// el 1º un entero, como retardo de la rotacion (recomendado 35)
// 2º si puede devolver el boton amarillo
// 3º si puede devolver el boton blanco
// 4º si puede devolver el boton ver
// y 5º si puede devolver el boton rojo
// y retorna cuando se presiona un pulsador:
// "0" amarillo, "1" blanco, "2" verde y "3" rojo
int rotar_mensaje(int retardo, int1 amarillo, int1 blanco, int1 verde, int1
rojo){
//int1 sw_rotar_mensaje=1;
unsigned int8 no_caracteres=0;
unsigned int8 letra1=0, letra2=1, letra3=2, letra4=3; //4 displays, 4 letras
mux simultaneamente
while(mensaje[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de carácteres a rotar
}
while(1){
for(i=0;i<=retardo;++i){
pinta_disp1(mensaje[letra1]);
pinta_disp2(mensaje[letra2]);
pinta_disp3(mensaje[letra3]);
pinta_disp4(mensaje[letra4]);
if(!input(Puls_Amarillo) || !input(Puls_Blanco) || !input(Puls_Verde)
|| !input(Puls_Rojo)){ // si pulso algo
if(!input(Puls_Amarillo) && amarillo == 1){
while(!input(Puls_Amarillo) && blanco
== 1); // espera que suelte el pulsador
delay_ms(antirebotes); // antirebote
return 0;
}
if(!input(Puls_Blanco) && blanco == 1){
while(!input(Puls_Blanco));
delay_ms(antirebotes);
return 1;
}
if(!input(Puls_Verde) && verde == 1){
while(!input(Puls_Verde));
delay_ms(antirebotes);
return 2;
}
if(!input(Puls_Rojo) && rojo == 1){
while(!input(Puls_Rojo));
delay_ms(antirebotes);
return 3;
}
}
}
if(letra1 < no_caracteres-1) ++letra1; // (-1) en el array el "0" es el
primer elemento
else letra1 = 0;
if(letra2 < no_caracteres-1) ++letra2;
else letra2 = 0;
if(letra3 < no_caracteres-1) ++letra3;
else letra3 = 0;
if(letra4 < no_caracteres-1) ++letra4;
else letra4 = 0;
}
}
void mensaje_inicio(void){
unsigned int no_caracteres = 0;
while(bienvenida[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de carácteres del array "una_cara"
}
for(i=0;i<=no_caracteres;++i){ // Copiamos el array "una_cara" a
"mensaje"
// 1er elemento [0] --> copiamos inclusive 0xFF (marca final)
mensaje[i] = bienvenida[i];
}
rotar_mensaje(35,0,0,0,1); // Solo acaba al pulsar rojo (GO)
}
void calentar_bombillas(void){
unsigned int no_caracteres = 0;
Rele_On;
while(calentar[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de carácteres del array
"calentar"
}
for(i=0;i<=no_caracteres;++i){ // Copiamos el array "calentar" a
"mensaje"
// 1er elemento [0] --> copiamos inclusive 0xFF (marca final)
mensaje[i] = calentar[i];
}
rotar_mensaje(35,0,0,1,0);
Rele_Off;
}
void selec_tiempo(void){
int1 sw = 0;
if(read_eeprom(0) >=0 && read_eeprom(0) <= 9) min_x10 = read_eeprom(0);
//comprueba la ultima temporizacion
if(read_eeprom(1) >=0 && read_eeprom(1) <= 9) min = read_eeprom(1);
if(read_eeprom(2) >=0 && read_eeprom(2) <= 5) seg_x10 = read_eeprom(2);
if(read_eeprom(3) >=0 && read_eeprom(3) <= 9) seg = read_eeprom(3);
enable_interrupts(INT_RB);
do{
for(i=0; i<20;++i){
if(display == 1 && sw == 0) pinta_disp1(0);
else pinta_disp1(numeros[min_x10]);
if(display == 2 && sw == 0) pinta_disp2(punto);
else pinta_disp2(numeros[min]+punto);
if(display == 3 && sw == 0) pinta_disp3(0);
else pinta_disp3(numeros[seg_x10]);
if(display == 4 && sw == 0) pinta_disp4(0);
else pinta_disp4(numeros[seg]);
if(!input(Puls_Rojo)) break; // si pulsa rojo,
sale sin esperar a terminar el for
}
if(sw == 1) sw = 0;
else sw = 1;
} while(input(Puls_Rojo));
while(!input(Puls_Rojo)); // espera a que suelte
delay_ms(antirebotes); //antirebotes
disable_interrupts(INT_RB);
write_eeprom(0,min_x10); //guarda la temporización en la eeprom
write_eeprom(1,min); //para recuperarla la próxima vez
write_eeprom(2,seg_x10);
write_eeprom(3,seg);
}
void selec_caras(void){
int8 pulsador = 0;
unsigned int no_caracteres = 0;
do{
if(caras == 1){
while(una_cara[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de
carácteres del array "una_cara"
}
for(i=0;i<=no_caracteres;++i){ // Copiamos el
array "una_cara" a "mensaje"
// 1er elemento [0] --> copiamos inclusive 0xFF (marca final)
mensaje[i] = una_cara[i];
}
}
if(caras == 2){
while(dos_caras[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de
carácteres del array "dos_caras"
}
for(i=0;i<=no_caracteres;++i){ // Copiamos el
array "dos_caras" a "mensaje"
// 1er elemento [0] --> copiamos inclusive 0xFF (marca final)
mensaje[i] = dos_caras[i];
}
}
pulsador = rotar_mensaje(35,1,1,1,0);
if(pulsador == 0 || pulsador == 1){
if(caras == 1) caras = 2;
else caras = 1;
}
} while(pulsador != 2 && pulsador != 3); // Al pulsar verde o rojo y
devolver un 3 o 4 acepta el nº de caras
}
void listo(void){
unsigned int no_caracteres = 0;
while(msj_listo[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de carácteres del array "msj_listo"
}
for(i=0;i<=no_caracteres;++i){ // Copiamos el array "msj_listo" a
"mensaje"
// 1er elemento [0] --> copiamos inclusive 0xFF (marca final)
mensaje[i] = msj_listo[i];
}
rotar_mensaje(35,0,0,1,0);
}
void segunda_cara(void){
unsigned int no_caracteres = 0;
while(msj_segunda_cara[no_caracteres] != 0xFF){
++no_caracteres; // cuenta el nº de carácteres del array "msj_segunda_cara"
}
for(i=0;i<=no_caracteres;++i){ // Copiamos el array "msj_segunda_cara" a
"mensaje"
// 1er elemento [0] --> copiamos inclusive 0xFF (marca final)
mensaje[i] = msj_segunda_cara[i];
}
rotar_mensaje(35,0,0,1,0);
}
void cuenta(void){
fin_cuenta = 0;
min_x10 = read_eeprom(0);
min = read_eeprom(1);
seg_x10 = read_eeprom(2);
seg = read_eeprom(3);
Rele_On;
set_rtcc(131);
enable_interrupts(INT_RTCC);
do{
if(min_x10 != 0) pinta_disp1(numeros[min_x10]);
if(min_x10 == 0 && min == 0) pinta_disp2(punto);
else pinta_disp2(numeros[min]+punto);
pinta_disp3(numeros[seg_x10]);
pinta_disp4(numeros[seg]);
} while(fin_cuenta == 0);
disable_interrupts(INT_RTCC);
Rele_Off;
}
void main(void){
set_tris_a(0x00); // Puerto A todo salidas
port_b_pullups(TRUE); // Resistencias de polarización
set_tris_b(0xFC); // Todo entradas excepto RB0
(zumbador) y RB1 (Rele2)
set_tris_c(0x00); // Puerto C todo salidas
port_a=0;
port_b=0;
port_c=0;
setup_counters(RTCC_INTERNAL, RTCC_DIV_64);
setup_timer_2(T2_DIV_BY_16, 0xFF, 16);
enable_interrupts(GLOBAL);
mensaje_inicio();
Rele2_On;
calentar_bombillas();
selec_tiempo();
selec_caras();
listo();
cuenta();
alarma();
if(caras == 2){
segunda_cara();
cuenta();
alarma();
}
Rele2_Off;
reset_cpu();
}
|
|
| |
Descargar Fuentes de
tempo.c Descargar
tempo.hex |
|
Esta página se modificó el
27/12/2008
|