/////////////////////////////////////////////////////////////////////////
//// ////
//// PIC_Tengu_v1.c ////
//// ////
//// Autor: jfmateos2 ////
//// Contacto: [EMAIL="jfmateos@lycos.es"]jfmateos@lycos.es[/EMAIL] ////
//// Madrid, abril 2008 ////
//// ////
/////////////////////////////////////////////////////////////////////////
#include <18F2455.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, CCP2C1
#device ADC=8
#use delay(clock=48000000)
#include <stdlib.h>
#include ".\include\usb_cdc.h"
#rom int8 0xf00000={5,0,0,0,0,0,//0-->5 (edad,copiaEdad,usos futuros,...)
12,250,1,249,251,60,61,62,63,64,65,251,254,//6-->18 (animacion: edad-vela)
29,29,25,26,21,10,48,26,10,28,10,48,10,26,10,16,10,28,48,21,10,29,48,32,14,21,10,29,48,48,//19-->48
202,17,10,35,48,27,31,18,14,23,48,26,18,14,23,29,10,48,27,31,14,48,29,25,21,25,48,31,23,48,21,
25,12,25,48,12,14,21,14,11,28,10,28,18,10,48,27,31,14,48,12,31,22,26,21,14,48,10,24,25,29,
38,48,35,48,27,31,14,48,17,10,35,48,27,31,14,48,10,26,28,25,32,14,12,17,10,28,48,26,25,28,
27,31,14,48,23,31,23,12,10,48,29,14,48,32,25,21,32,14,28,10,48,10,48,29,14,28,48,30,10,23,
48,19,25,32,14,23,38,48,10,31,23,27,31,14,48,30,10,22,26,25,12,25,48,23,31,23,12,10,48,29,
14,48,17,10,48,29,18,13,25,48,30,10,23,48,32,18,14,19,25,38,48,10,31,23,48,10,29,18,38,48,
15,14,21,18,36,48,12,31,22,26,21,14,10,24,25,29,48,10,21,22,31,37}//49-->251
#define PRECARGA_TIMER 0
#define UMBRAL_PARPADEO 100 //Max=128.Está afectado por VELOCIDAD_GESTICULACION
#define VELOCIDAD_GESTICULACION 20000
#define UMBRAL_SOPLIDO 90
#define VELOCIDAD_TEXTO 4500
#define PROPORCION_ANIMACION_AVANCE 2
#define UMBRAL_AUDICION 3
#define UMBRAL_DORMIRSE 5000
unsigned int8 i;
unsigned int8 columnaActual=5;
int1 conversorOcupado=0;
int1 modoFuncionamiento;
int1 botonPulsado=0;
int1 resetear=0;
int16 ciclosTimer1;
int filas[7]={PIN_C0,PIN_B2,PIN_B3,PIN_B4,PIN_B5,PIN_B6,PIN_B7};
int *cara, *caraEnVisualizacion;
//Atención, la longitud de cada array siguiente está codificada en el propio
//array, porque como cada columna sólo utiliza 7 bits he aprovechado
//el octavo para codificar la longitud.
//Numeros
int caracter0[3]={31,17,31+128};//0
int caracter1[3]={9,31,1+128};//1
int caracter2[3]={19,21,9+128};//2
int caracter3[3]={17,21,26+128};//3
int caracter4[3]={6,10,31+128};//4
int caracter5[3]={29,21,18+128};//5
int caracter6[3]={15,21,22+128};//6
int caracter7[3]={16,23,24+128};//7
int caracter8[3]={31,21,31+128};//8
int caracter9[3]={28,20,31+128};//9
//Letras mayúsculas
int caracter10[3]={15,20,15+128};//A
int caracter11[3]={31,21,10+128};//B
int caracter12[3]={14,17,10+128};//C
int caracter13[3]={31,17,14+128};//D
int caracter14[3]={31,21,17+128};//E
int caracter15[3]={31,20,16+128};//F
int caracter16[3]={14,17,23+128};//G
int caracter17[3]={31,4,31+128};//H
int caracter18[3]={17,31,17+128};//I
int caracter19[3]={2,17,31+128};//J
int caracter20[3]={31,12,19+128};//K
int caracter21[3]={31,1,1+128};//L
int caracter22[5]={31,8,4,8,31+128};//M
int caracter23[5]={31,8,4,2,31+128};//N
int caracter24[5]={31,72,68,66,31+128};//Ñ
int caracter25[3]={14,17,14+128};//O
int caracter26[3]={31,20,8+128};//P
int caracter27[4]={31,17,19,31+128};//Q
int caracter28[3]={31,20,11+128};//R
int caracter29[3]={9,21,18+128};//S
int caracter30[3]={16,31,16+128};//T
int caracter31[3]={31,1,31+128};//U
int caracter32[3]={30,3,30+128};//V
int caracter33[5]={31,2,4,2,31+128};//W
int caracter34[3]={27,4,27+128};//X
int caracter35[3]={24,7,24+128};//Y
int caracter36[3]={19,21,25+128};//Z
//Signos de puntuacion
int caracter37[2]={3,3+128};//.
int caracter38[2]={1,6+128};//,
int caracter39[1]={10+128};//:
int caracter40[2]={1,10+128};//;
int caracter41[1]={95+128};//¡
int caracter42[1]={125+128};//!
int caracter43[3]={14,81,2+128};//¿
int caracter44[3]={32,69,56+128};//?
int caracter45[2]={16,96+128};//´
int caracter46[2]={62,65+128};//(
int caracter47[2]={65,62+128};//)
int caracter48[2]={0,0+128};// (espacio)
//Caracteres especiales
int caracter49[5]={2,21,23,17,14+128};//@
int caracter50[3]={50,107,38+128};//$
int caracter51[5]={20,62,85,65,34+128};//€
//Signos matemáticos
int caracter52[3]={4,14,4+128};//+
int caracter53[3]={4,4,4+128};//-
int caracter54[3]={10,4,10+128};//*
int caracter55[3]={3,4,24+128};///
int caracter56[3]={19,4,25+128};//%
int caracter57[3]={4,10,17+128};//<
int caracter58[3]={17,10,4+128};//>
int caracter59[3]={10,10,10+128};//=
//Velas
int caracter60[6]={3,9,29,61,57,3+128};
int caracter61[6]={3,9,29,61,121,3+128};
int caracter62[6]={3,9,61,125,25,3+128};
int caracter63[6]={3,25,125,61,9,3+128};
int caracter64[6]={3,121,61,29,9,3+128};
int caracter65[6]={3,57,61,29,9,3+128};
int caracter66[6]={3,1,1,1,1,3+128};//vela apagada
//French
int caracter67[3]={47,74,15+128};//Á
int caracter68[3]={15,74,47+128};//À
int caracter69[3]={47,74,47+128};//Â
int caracter70[3]={63,85,17+128};//É
int caracter71[3]={31,85,49+128};//È
int caracter72[3]={63,85,49+128};//Ê
int caracter73[3]={95,21,81+128};//Ë
int caracter74[3]={41,79,9+128};//Í
int caracter75[3]={41,79,41+128};//Î
int caracter76[3]={81,31,81+128};//Ï
int caracter77[3]={38,73,6+128};//Ó
int caracter78[3]={38,73,38+128};//Ô
int caracter79[3]={47,65,15+128};//Ú
int caracter80[3]={15,47,65+128};//Ù
int caracter81[3]={47,65,47+128};//Û
int caracter82[3]={95,1,95+128};//Ü
int caracter83[3]={125,70,68+128};//Ç
//Caracteres reservados a partir del 240 (incluido)
//caracter246 -->Final de cadena transmitida por USB
//caracter247 -->Visualización inmediata del caracter siguiente (sin arrastre)
//caracter248 -->Volver al principio
//caracter249 -->Quitar espacio sufijo en caracter siguiente
//caracter250 -->Saltar a siguiente caracter
//caracter251 -->Inicio y final de animacion yo-yo
//caracter252 -->Inicio y final de animacion diente de sierra
//caracter253 -->Pausa corta/saltarse un avance
//caracter254 -->Stop
//caracter255 -->Nulo (se usa en animaciones)
int const * caracter[84]={caracter0,caracter1,caracter2,caracter3,caracter4,caracter5,
caracter6,caracter7,caracter8,caracter9,caracter10,caracter11,
caracter12,caracter13,caracter14,caracter15,caracter16,caracter17,
caracter18,caracter19,caracter20,caracter21,caracter22,caracter23,
caracter24,caracter25,caracter26,caracter27,caracter28,caracter29,
caracter30,caracter31,caracter32,caracter33,caracter34,caracter35,
caracter36,caracter37,caracter38,caracter39,caracter40,caracter41,
caracter42,caracter43,caracter44,caracter45,caracter46,caracter47,
caracter48,caracter49,caracter50,caracter51,caracter52,caracter53,
caracter54,caracter55,caracter56,caracter57,caracter58,caracter59,
caracter60,caracter61,caracter62,caracter63,caracter64,caracter65,
caracter66,caracter67,caracter68,caracter69,caracter70,caracter71,
caracter72,caracter73,caracter74,caracter75,caracter76,caracter77,
caracter78,caracter79,caracter80,caracter81,caracter82,caracter83};
#INT_EXT1
void int1_handler(){
if(!botonPulsado){
botonPulsado=1;
modoFuncionamiento=!modoFuncionamiento;
ciclosTimer1=400;
ext_int_edge(1,L_TO_H);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(0);
}else{
botonPulsado=0;
setup_timer_1(T1_DISABLED|T1_DIV_BY_1);
ext_int_edge(1,H_TO_L);
}
}
#INT_TIMER1
void timer1_handler(){
if(--ciclosTimer1==0){
resetear=1;
}
}
#INT_AD
void ad_handler(){
conversorOcupado=0;
}
#INT_TIMER0
void tmr_handler() {
//Apagar
output_a(0);
//Cambiar de columna
if (columnaActual==5){
columnaActual=0;
if(caraEnVisualizacion!=cara){
caraEnVisualizacion=cara;
}
}else{
columnaActual++;
}
//Preparar filas
for(i=0;i<7;i++){
output_bit(filas[i],*(caraEnVisualizacion+columnaActual)&(64>>i));
}
//Encender columna
output_a(1<<columnaActual);
set_timer0(PRECARGA_TIMER);
}
void int mostrarTexto (int1 tipo, int parametro, int1 salirConSoplido, int1 atenuacionUmbralSoplido,int1 salirConBoton, int1 salirSoloFinal){
unsigned int i,j;
int16 contador=1;
signed int columnasRestantes=0;//columnas que aún quedan
//por visualizar del caracterEntrante
int zonaTemporal[2][6]={0,0,0,0,0,0,0,0,0,0,0,0};//aquí se monta lo que se va a visualizan
//antes de pasárselo a *cara
//si el bit más significativo es 1 el avance dentro de la animación es hacia
//la derecha, y si es 0 el avance es hacia la izquierda (animaciones yo-yo).
//Para que una columna sea animada, siguientePropietarioColumna debe contener
//un valor distinto de 255
int1 indiceZonaTemporalActiva=0;
int1 incluirEspacioSufijo=1;
int1 actualizarVisualizacion=0;
int1 mostrarInstantaneamente=0;
int1 stopActivado=0;
int1 siguienteCaracterEsAnimado=0;
int1 sentidoDeAvance;
int* caracterEntrante;//puntero al carácter entrante
int longitudCaracterEntrante;
int posicionCaracterActual;//posición en la EEPROM del último carácter
//leído
int propietarioActualColumna[6][2]={255,1,255,1,255,1,255,1,255,1,255,1};//en una animación, posición en la eeprom
//e índice de la columna dentro del carácter
//del siguiente caracter que ocupará cada columna de zonaTemporal
unsigned int longitudMensaje;
//Apagar ojos
output_low(PIN_C1);
output_low(PIN_C2);
if(salirConSoplido){
enable_interrupts(INT_AD);
clear_interrupt(INT_AD);
conversorOcupado=1;
read_adc(ADC_START_ONLY);
}
if (tipo){
if(parametro>9){
write_eeprom(7,((int)(parametro/10)));
delay_ms(20);
}else{
write_eeprom(7,250);
delay_ms(20);
}
write_eeprom(8,parametro-((int)(parametro/10))*10);
delay_ms(20);
parametro=6;
}
longitudMensaje=read_eeprom(parametro);
posicionCaracterActual=parametro;
do{
contador++;
//Actualizar animación
if(contador % ((int16)(VELOCIDAD_TEXTO/PROPORCION_ANIMACION_AVANCE))==0){
actualizarVisualizacion=1;
for(i=0;i<6;i++){
j=read_eeprom(propietarioActualColumna[i][0]);
if(j!=255){//es una columna animada
if(zonaTemporal[indiceZonaTemporalActiva][i]>128){
sentidoDeAvance=1;
}else{
sentidoDeAvance=0;
}
j=((zonaTemporal[indiceZonaTemporalActiva][i])<128?read_eeprom(propietarioActualColumna[i][0]-1):read_eeprom(propietarioActualColumna[i][0]+1));
switch(j){
case 251: //animacion yo-yo
if (sentidoDeAvance){//Va hacia la derecha
propietarioActualColumna[i][0]-=1;
}else{//va hacia la izquierda
propietarioActualColumna[i][0]+=1;
}
sentidoDeAvance=!sentidoDeAvance;
break;
case 252: //animacion diente de sierra
while(read_eeprom(propietarioActualColumna[i][0])!=252){
propietarioActualColumna[i][0]--;
}
break;
default:
if(sentidoDeAvance){
propietarioActualColumna[i][0]=propietarioActualColumna[i][0]+1;
}else{
propietarioActualColumna[i][0]=propietarioActualColumna[i][0]-1;
}
}
//Actualizar columnas en zona temporal
//Cuidadito con el bit más significativo para mantener el sentido
//de la animación
j=(caracter[read_eeprom(propietarioActualColumna[i][0])])[propietarioActualColumna[i][1]];
if(sentidoDeAvance){
if(j<128){
zonaTemporal[indiceZonaTemporalActiva][i]=j+128;
}else{
zonaTemporal[indiceZonaTemporalActiva][i]=j;
}
}else{
if(j<128){
zonaTemporal[indiceZonaTemporalActiva][i]=j;
}else{
zonaTemporal[indiceZonaTemporalActiva][i]=j-128;
}
}
}
}
}
//Actualizar avance
if(contador>=VELOCIDAD_TEXTO){
if(!stopActivado){
actualizarVisualizacion=1;
if(columnasRestantes==0){
if(longitudMensaje>0){
longitudMensaje--;
posicionCaracterActual++;
j=read_eeprom(posicionCaracterActual);
if(j>=240){
//gestión de caracteres reservados
switch (j){
case 247:
mostrarInstantaneamente=1;
stopActivado=1;
continue;
break;
case 248:
longitudMensaje=read_eeprom(parametro);
posicionCaracterActual=parametro;
continue;
break;
case 249:
incluirEspacioSufijo=0;
continue;
break;
case 250:
continue;
break;
case 251:
siguienteCaracterEsAnimado=1;
continue;
break;
case 252:
siguienteCaracterEsAnimado=1;
continue;
break;
case 253:
contador=1;
continue;
break;
case 254:
longitudMensaje=0;
stopActivado=1;
continue;
break;
}
}else{
caracterEntrante=caracter[j];
columnasRestantes=0;
//Averiguar el número de columnas del carácter
while(!((caracterEntrante[columnasRestantes])&128)){
columnasRestantes++;
};
columnasRestantes++;
longitudCaracterEntrante=columnasRestantes;
}
}else{
if(salirConSoplido){
disable_interrupts(INT_AD);
}
return;
}
}
if(columnasRestantes>0){
for(i=0;i<5;i++){
zonaTemporal[indiceZonaTemporalActiva][i]=zonaTemporal[indiceZonaTemporalActiva][i+1];
propietarioActualColumna[i][0]=propietarioActualColumna[i+1][0];
propietarioActualColumna[i][1]=propietarioActualColumna[i+1][1];
}
if(caracterEntrante[longitudCaracterEntrante-columnasRestantes]<128){
zonaTemporal[indiceZonaTemporalActiva][5]=caracterEntrante[longitudCaracterEntrante-columnasRestantes];
}else{
zonaTemporal[indiceZonaTemporalActiva][5]=caracterEntrante[longitudCaracterEntrante-columnasRestantes]-128;
//Para evitar interferencias con el sentido de la animación
}
if(siguienteCaracterEsAnimado){
propietarioActualColumna[5][1]=longitudCaracterEntrante-columnasRestantes;
if(columnasRestantes==longitudCaracterEntrante){
propietarioActualColumna[5][0]=posicionCaracterActual;
}else{
propietarioActualColumna[5][0]=propietarioActualColumna[4][0];
}
if(caracterEntrante[longitudCaracterEntrante-columnasRestantes]<128){
zonaTemporal[indiceZonaTemporalActiva][5]=(caracter[read_eeprom(propietarioActualColumna[5][0])])[propietarioActualColumna[5][1]];
}else{
zonaTemporal[indiceZonaTemporalActiva][5]=((caracter[read_eeprom(propietarioActualColumna[5][0])])[propietarioActualColumna[5][1]])-128;
//Para evitar interferencias con el sentido de la animación
}
//Se debe sumar 128 si la animación está actualmente
//avanzando hacia la derecha, es decir, si la columna entrante
//es la primera de la animación (todas las animaciones comienzan
//hacia la derecha), o si la columna entrante es posterior a la
//primera y la columna anterior es >=128
//No puede haber caracteres animados de una sola columna
if(propietarioActualColumna[5][1]==0){
zonaTemporal[indiceZonaTemporalActiva][5]+=128;
}else{
if(zonaTemporal[indiceZonaTemporalActiva][4]>=128){
zonaTemporal[indiceZonaTemporalActiva][5]+=128;
}
}
}else{
propietarioActualColumna[5][0]=255;
}
contador=1;
columnasRestantes--;
}
if(columnasRestantes==-1){
columnasRestantes=0;
incluirEspacioSufijo=0;
for(i=0;i<5;i++){
zonaTemporal[indiceZonaTemporalActiva][i]=zonaTemporal[indiceZonaTemporalActiva][i+1];
propietarioActualColumna[i][0]=propietarioActualColumna[i+1][0];
propietarioActualColumna[i][1]=propietarioActualColumna[i+1][1];
}
zonaTemporal[indiceZonaTemporalActiva][5]=0;
propietarioActualColumna[5][0]=255;
contador=1;
}
if(columnasRestantes==0){
if (incluirEspacioSufijo==1){
columnasRestantes=-1;
}else{
if(siguienteCaracterEsAnimado){
siguienteCaracterEsAnimado=0;
//Avanzar posicionCaracterActual
while(read_eeprom(posicionCaracterActual)!=251 && read_eeprom(posicionCaracterActual)!=252){
posicionCaracterActual++;
}
}
incluirEspacioSufijo=1;
}
}
}else{
contador=1;
if(mostrarInstantaneamente){
stopActivado=0;
mostrarInstantaneamente=0;
posicionCaracterActual++;
i=read_eeprom(posicionCaracterActual);
caracterEntrante=caracter[i];
for(j=0;j<6;j++){
zonaTemporal[indiceZonaTemporalActiva][j]=caracterEntrante[j];
if(caracterEntrante[j]>=128){
zonaTemporal[indiceZonaTemporalActiva][j]-=128;
}
propietarioActualColumna[j][0]=255;
}
}
}
}
//Actualizar visualizacion
if (actualizarVisualizacion){
cara=zonaTemporal[indiceZonaTemporalActiva];
while(cara!=caraEnVisualizacion){
}
actualizarVisualizacion=0;
indiceZonaTemporalActiva=!indiceZonaTemporalActiva;
for(j=0;j<6;j++){
zonaTemporal[indiceZonaTemporalActiva][j]=zonaTemporal[!indiceZonaTemporalActiva][j];
}
}
//¿Detectar soplido?
if(salirConSoplido){
if(!salirSoloFinal || (salirSoloFinal && longitudMensaje==0 && columnasRestantes==0)){
if(!conversorOcupado){
conversorOcupado=1;
j = read_adc(ADC_READ_ONLY);
read_adc(ADC_START_ONLY);
if(atenuacionUmbralSoplido){
j+=30;
}
if (j>UMBRAL_SOPLIDO){
disable_interrupts(INT_AD);
return;
}
}
}
}
//Detectar salida
if(modoFuncionamiento){
return;
}
//Detectar reset
if(resetear){
j=read_eeprom(1);
write_eeprom(0,j);
delay_ms(40);
reset_cpu();
}
}while(true);
}
void main() {
unsigned int8 entradausb;
unsigned int8 value, max;
int comodin, comodin2;
int16 comodin3, comodin4;
int16 ciclosParaDormirse=UMBRAL_DORMIRSE;
int modoCara=0;
unsigned int8 supremo=80;
signed int caraActiva=0;
signed int8 acumuladorParpadeo;
unsigned int32 periodo, muestra;
int bostezo[5][6]={0,8,40,104,8,0,0,8,44,108,8,0,0,12,42,106,12,0,0,14,41,105,14,0,0,15,41,105,15,0};
//caras del modo nariz aguileña
int cara1[6]={0,4,108,44,4,0};
int cara2[6]={0,4,110,46,4};
int cara3[6]={0,6,106,42,6,0};
int cara4[6]={0,7,105,41,7,0};
int cara5[6]={0,14,105,41,14,0};
int cara6[6]={12,10,105,41,10,12};
int cara7[6]={14,9,105,41,9,14};
int cara8[6]={15,9,105,41,9,15};
//caras del modo nariz chata
int cara9[6]={0,8,88,88,8,0};
int cara10[6]={0,8,84,84,8,0};
int cara11[6]={0,12,82,82,12,0};
int cara12[6]={0,14,81,81,14,0};
int cara13[6]={0,30,81,81,30,0};
int cara14[6]={12,18,81,81,18,12};
int cara15[6]={14,17,81,81,17,14};
int cara16[6]={31,17,81,81,17,31};
//caras del modo sin nariz
int cara17[6]={8,8,8,8,8,8};
int cara18[6]={28,20,20,20,20,28};
int cara19[6]={62,34,34,34,34,62};
int cara20[6]={127,65,65,65,65,127};
//caras del modo luciano
int cara21[6]={0,0,0,0,0,0};
int cara22[6]={0,1,1,1,1,0};
int cara23[6]={1,2,2,2,2,1};
int cara24[6]={3,4,5,4,5,3};
int cara25[6]={7,8,10,9,10,7};
int cara26[6]={15,16,20,18,20,15};
int cara27[6]={30,33,41,37,41,30};
int cara28[6]={60,66,82,74,82,60};
int const *caras[4][8]={cara1,cara2,cara3,cara4,cara5,cara6,cara7,cara8,
cara9,cara10,cara11,cara12,cara13,cara14,cara15,cara16,
cara17,cara17,cara18,cara18,cara19,cara19,cara20,cara20,
cara21,cara22,cara23,cara24,cara25,cara26,cara27,cara28};
if(!input(PIN_B1)){
usb_cdc_init();
usb_init();
output_low(PIN_C1);
output_high(PIN_C2);
while(!usb_cdc_connected()) {
delay_ms(200);
output_toggle(PIN_C1);
output_toggle(PIN_C2);
}
do{
usb_task();
if (usb_enumerated()) {
printf(usb_cdc_putc, "PICTENGU");
break;
}
}while (TRUE);
//Enviar contenido eeprom
output_high(PIN_C1);
output_high(PIN_C2);
entradausb=get_int_usb();
if(entradausb==246){
delay_ms(1000);
for(comodin3=0;comodin3<=255;comodin3++){
value=read_eeprom(comodin3);
delay_ms(20);
printf(usb_cdc_putc,"%c",value);
}
output_toggle(PIN_C1);
output_toggle(PIN_C2);
}
comodin3=0;
do{
usb_task();
if(usb_enumerated()){
entradausb=get_int_usb();
if(entradausb!=246){
write_eeprom(comodin3,entradausb);
delay_ms(20);
comodin3++;
}else{
break;
}
}
}while(true);
}
setup_adc_ports(PIN_B0);
setup_adc(ADC_CLOCK_DIV_64 );
set_adc_channel(12);
ext_int_edge(1,H_TO_L);
setup_timer_1(T1_DISABLED|T1_DIV_BY_1);
setup_timer_0(RTCC_8_BIT|RTCC_DIV_128);
set_timer0(PRECARGA_TIMER);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_AD);
clear_interrupt(INT_AD);
enable_interrupts(INT_EXT1);
clear_interrupt(INT_EXT1);
enable_interrupts(INT_TIMER1);
clear_interrupt(INT_TIMER1);
enable_interrupts(GLOBAL);
disable_interrupts(INT_EXT1);
columnaActual=5;
output_low(PIN_C1);
output_low(PIN_C2);
//Modo 1: dormido
cara=bostezo[0];
caraEnVisualizacion=cara;
value=0;
conversorOcupado=1;
read_adc(ADC_START_ONLY);
while(value<UMBRAL_SOPLIDO-30){
if(!conversorOcupado){
conversorOcupado=1;
value = read_adc(ADC_READ_ONLY);
read_adc(ADC_START_ONLY);
}
}
disable_interrupts(INT_AD);
//Modo 2: despertar: abre un ojo, luego el otro, luego bosteza
//y pestañea 3 veces consecutivas
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 255, 16);
set_pwm2_duty(0);
for(comodin=0;comodin<40;comodin++){
set_pwm1_duty(comodin);
delay_ms(30);
}
for(comodin=0;comodin<40;comodin++){
set_pwm2_duty(comodin);
delay_ms(30);
}
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_timer_2(T2_DISABLED, 255, 16);
output_low(PIN_C1);
output_low(PIN_C2);
for (comodin=0;comodin<5;comodin++){
cara=bostezo[comodin];
delay_ms(150);
}
delay_ms(1000);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 255, 16);
for (comodin=4;comodin>0;comodin--){//Con >= falla ¿por qué?
cara=bostezo[comodin];
set_pwm1_duty((4-comodin)*10);
set_pwm2_duty((4-comodin)*10);
delay_ms(150);
}
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_timer_2(T2_DISABLED, 255, 16);
for(comodin=1;comodin<=3;comodin++){
output_low(PIN_C1);
output_low(PIN_C2);
delay_ms(300);
output_high(PIN_C1);
output_high(PIN_C2);
delay_ms(300);
}
//Si en el primer byte de la memoria hay un valor distinto de 00...
//comienza el juego del apagado de velas...
//en caso contrario salta directamente al modo 3
comodin=read_eeprom(0);
delay_ms(20);
if(comodin!=0){
write_eeprom(0,0);
delay_ms(20);
write_eeprom(1,comodin);
delay_ms(20);
mostrarTexto(0,19,0,0,0,0);
for(comodin2=1;comodin2<=comodin;comodin2++){
mostrarTexto(1,comodin2,1,1,0,1);
cara=caracter66;
delay_ms(500);
}
comodin3=read_eeprom(19);
delay_ms(20);
mostrarTexto(0,20+comodin3,0,0,0,0);
}
//Modo 3: Wilson
modoFuncionamiento=1;
output_high(PIN_C1);
output_high(PIN_C2);
cara=cara1;
caraEnVisualizacion=cara1;
acumuladorParpadeo=0;
muestra=0;
periodo=VELOCIDAD_GESTICULACION;
max=0;
enable_interrupts(INT_AD);
clear_interrupt(INT_AD);
enable_interrupts(INT_EXT1);
clear_interrupt(INT_EXT1);
conversorOcupado=1;
read_adc(ADC_START_ONLY);
do{
if(modoFuncionamiento){
muestra++;
if(!conversorOcupado){
conversorOcupado=1;
value = read_adc(ADC_READ_ONLY);
read_adc(ADC_START_ONLY);
if(value>max){
max=value;
}
}
if(muestra==periodo){
if(acumuladorParpadeo>0){
output_high(PIN_C1);
output_high(PIN_C2);
}
if(max>UMBRAL_SOPLIDO){//Soplido
cara=cara21;
if (modoCara<3){
modoCara++;
}else{
modoCara=0;
}
output_low(PIN_C1);
output_low(PIN_C2);
for(comodin2=7;comodin2>0;comodin2--){
cara=caras[modoCara][comodin2];
delay_ms(100);
}
output_high(PIN_C1);
output_high(PIN_C2);
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>supremo){
caraActiva=7;
acumuladorParpadeo+=8;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>(float)6/7*supremo){
caraActiva=6;
acumuladorParpadeo+=7;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>(float)5/7*supremo){
caraActiva=5;
acumuladorParpadeo+=6;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>(float)4/7*supremo){
caraActiva=4;
acumuladorParpadeo+=5;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>(float)3/7*supremo){
caraActiva=3;
acumuladorParpadeo+=4;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>(float)2/7*supremo){
caraActiva=2;
acumuladorParpadeo+=3;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else if(max>(float)1/7*supremo){
caraActiva=1;
acumuladorParpadeo+=2;
ciclosParaDormirse=UMBRAL_DORMIRSE;
}else{
caraActiva=0;
acumuladorParpadeo+=1;
ciclosParaDormirse--;
}
cara=caras[modoCara][caraActiva];
if(max>supremo+UMBRAL_AUDICION){
supremo=max-UMBRAL_AUDICION;
}else{
if(supremo>7*UMBRAL_AUDICION){
supremo--;
}
}
if(acumuladorParpadeo>=UMBRAL_PARPADEO){
output_low(PIN_C1);
output_low(PIN_C2);
acumuladorParpadeo=-1;
}
//printf(usb_cdc_putc, "\r\nSupremo=%6.0w",supremo );
//printf(usb_cdc_putc, "\r\nCociente=%6.4f",(float)1/7*supremo );
muestra=0;
max=0;
}
}else{
comodin3=read_eeprom(19);
delay_ms(20);
mostrarTexto(0,20+comodin3,0,0,0,0);
}
if(resetear||ciclosParaDormirse==0){
if(ciclosParaDormirse){
comodin=read_eeprom(1);
write_eeprom(0,comodin);
delay_ms(40);
}
reset_cpu();
}
}while (TRUE);
}