#include <16f1829.h>
#include <internal_eeprom.c>
#include <stdio.h>
#include <stdlib.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#use delay(clock=8M)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Canal de Comunicación : usart
///////////////////////////////////////////////////////////////////////////////////////////////////
#define TTL_TX PIN_B7
#define TTL_RX PIN_B5
#use rs232(baud=57600, xmit=TTL_TX, rcv=TTL_RX)
/*#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
#define LCD_RS PIN_B1
#define LCD_RW PIN_B2
#define LCD_E PIN_B3
#include "flex_lcd_c2.c" /// libreria para el manejo de la lcd */
//ENTRADAS
#define TANQUE PIN_C4 // PIN_A7
#define TANQUEEXTERIOR PIN_C3 // PIN_A6
#define CREDITO1 PIN_B4 // PIN_C1
//Ultrasonido
#define trig PIN_C1 // PIN_C5
#define echo PIN_C0 // PIN_C4
//SALIDAS
#define ELECTROBOMBA PIN_C2 // PIN_A4
#define APAGADO PIN_A5 // PIN_C0
#define SENSORP PIN_A4 // PIN_B0 sensorpuerta
//Variables
///////////////////////////////////////
// Constantes
///////////////////////////////////////
int const lenbuff=200; // Longitud máxima del buffer
char const delimiter = ','; // Delimitador de parametros
int const lenparam = 12; // Máxima longitud por parámetro
///////////////////////////////////////
// RAM
///////////////////////////////////////
int xbuff=0x00; // Índice: siguiente char en cbuff
unsigned char cbuff[lenbuff]; // Buffer de recepción
int flagcommand=0; // Flag para comando disponible
//char banderasensor[2]={'0'}; //por si no hay agua
char tmp[lenparam];
unsigned char manual[lenparam];
unsigned char encenderunidad[lenparam];
unsigned char celular[lenparam];
unsigned char hora[lenparam];
unsigned char fecha[lenparam];
unsigned char latitud[lenparam];
unsigned char longitud[lenparam];
unsigned char signolatitud[lenparam];
unsigned char signolongitud[lenparam];
unsigned char dia[lenparam];
unsigned char mes[lenparam];
unsigned char ano[lenparam];
unsigned char degradianes1[lenparam];
unsigned char minutos1[lenparam];
unsigned char degradianes2[lenparam];
unsigned char minutos2[lenparam];
double horaf;
double fechaf;
double latitudf;
double longitudf;
double degradianesf1;
double minutosf1;
double degradianesf2;
double minutosf2;
int manualsms=0;
int unidadsms=0;
int diaf;
int mesf;
int anof;
int sumadia;
int mestabla;
int multiplo;
int sumaano;
int dianumero;
int unidadgps=0;
int unidad=1;
int16 distancia, tiempo;
int unidadsensor=0;
int estadopuerta=0; //por si habren la puerta
int banderaenvio=0; //bandera para activar envio
unsigned int16 cont=0;
unsigned int16 servicios=0;
///////////////////////////////////////
// Funcione de creditos
///////////////////////////////////////
void creditos(){
if(input(CREDITO1)==1){
cont++;
servicios=servicios+cont;
write_int16_eeprom(0x05, (int16)(servicios));
cont=0;
printf("creditos: %lu\r\n",(unsigned int16)(servicios
)); while(input(CREDITO1)==1)
{;}
}
}
///////////////////////////////////////
// Funciones de Buffer
///////////////////////////////////////
// Cuenta los parametros en el buffer --
int8 count_param_number(void){
int8 ret, i;
unsigned char c;
ret=0;
// ¿Hay comando?
c = cbuff[0];
if(c != 0x00) ret=1;
// Cuenta parámetros
for(i=0;i<lenbuff,c!=0x00;i++){
c = cbuff[i];
if(c==delimiter) ++ret;
}
return ret;
}
// Extrae un Parámetro del buffer ------
int1 get_param_by_order(int8 pos){ //numero de orden del trozo, maxima longitud, array donde extraer
int1 ret=0;
int8 i,j;
int8 nDelimiter;
for(i=0,j=0,nDelimiter=0;i<lenbuff;i++){
tmp[j]=0x00;
if(nDelimiter==pos){
tmp[j++]=cbuff[i];
}
if((cbuff[i]==Delimiter) || (cbuff[i]==0x00)) ++nDelimiter;
if(nDelimiter>pos){
j -= 1;
break;
}
}
tmp[j]='\0';
if(j>lenparam){
ret=1;
}
return ret; //retorna 1 si todo bien
}
// Inicia a \0 cbuff -------------------
void init_cbuff(void){
int x;
for(x=0;x<lenbuff;x++){// Bucle que pone a 0 todos los
cbuff[x]=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente caracter
}
void corrertiempo(void){
init_cbuff(); // Borro buffer.
delay_ms(2000);
flagcommand=0;
delay_ms(2000);
flagcommand=0;
init_cbuff(); // Borro buffer.
}
// Añade a cbuff -----------------------
void add_2_cbuff(char c){
switch(c){
case 'K': // Enter -> Habilita Flag para procesar comando
flagcommand=1;
break;
default: // Añade caracter recibido al Buffer
cbuff[xbuff++]=c;
if(xbuff>199){
flagcommand=2;}
}
}
void recivosms(void){
if(manual[0]=='M') //pregunta si manual o autmatico
manualsms=1;
if(manual[0]=='A')
manualsms=0;
if(encenderunidad[0]=='1') //lee el valor recibido por sms de la solicitud de la unidad
unidadsms=1;
if(encenderunidad[0]=='0')
unidadsms=0;
}
void enviosms(void){
if(manual[0]=='M' || manual[0]=='A' || banderaenvio==1){
banderaenvio=0;
delay_ms(2000);
flagcommand=0;
if(manual[0]=='M' || manual[0]=='A'){
printf("AT+CMGS=+57%s\r\n",celular
); manual[0]=0;}
else{
printf("AT+CMGS=+573118017337\r\n");} delay_ms(2000);
flagcommand=0;
printf("creditos: %lu\r\n",(unsigned int16)(servicios
)); delay_ms(1000);
flagcommand=0;
printf("latitud: %04.5f\r\n",latitudf
); delay_ms(1000);
flagcommand=0;
printf("longitud: %05.5f\r\n",longitudf
); delay_ms(1000);
flagcommand=0;
printf("Estado unidad: %u\r\n",unidad
); delay_ms(1000);
flagcommand=0;
printf("Estado puerta: %u\r\n",estadopuerta
); delay_ms(1000);
flagcommand=0;
printf("maps.google.com/?q=%04.5f,%05.5f\r\n",latitudf
,longitudf
); delay_ms(1000);
flagcommand=0;
init_cbuff(); // Borro buffer.
}
}
void puerta(void){
if(input(SENSORP)==1 && estadopuerta==0){
estadopuerta=1;
banderaenvio=1;
}
if(input(SENSORP)==0 && estadopuerta==1){
estadopuerta=0;
banderaenvio=1;
}
enviosms();
}
void seleccionar(void){
if(manualsms==1){
if(unidadsms==1 && unidadsensor==1){
unidad=1;
output_high(APAGADO); } //envio un 1 para desactivar la salida (APAGADO)
if(unidadsms==0 || unidadsensor==0){
unidad=0;
output_low(APAGADO); } //envio un cero para activar la salida (APAGADO)
}
if(manualsms==0){
if(unidadgps==1 && unidadsensor==1){
unidad=1;
output_high(APAGADO); } //envio un 1 para desactivar la salida (APAGADO)
if(unidadgps==0 || unidadsensor==0){
unidad=0;
output_low(APAGADO); } //envio un cero para activar la salida (APAGADO)
}
}
///////////////////////////////////////
// SENSORES
///////////////////////////////////////
void sensores(void){
//---------------------------------------------------------------------------------
/* output_high (trig);
delay_us (20);
output_low (trig);
WHILE ( ! input (echo)){}
set_timer1 (0);
WHILE (input (echo) ){}
tiempo = get_timer1 (); */
distancia = 200;//(tiempo * 10) / (58.0);
//-----------------------------------------------------------------------------
if(input(TANQUEEXTERIOR)==1 && distancia >= 190)
{
output_low(ELECTROBOMBA);
unidadsensor=0;
/* if(banderasensor[0]=='0'){
banderasensor[0]='1';
banderaenvio=1;
} */
}
else if(input(TANQUE)==1 && distancia >50){ //si el tanque interior no tiene agua
output_high(ELECTROBOMBA);
unidadsensor=1;
}
else if(input(TANQUE)==0 || distancia <= 45){ //si el tanque interior sobre pasa el agua
output_low(ELECTROBOMBA);
unidadsensor=1;
}
else {}
/* if(input(TANQUEEXTERIOR)==0 && banderasensor[0]=='1'){ //desactiva la bandera de nivel
unidadsensor=1;
banderasensor[0]='0';
banderaenvio=1;
} */
seleccionar();
}
///////////////////////////////////////
// Procesador de Comandos
///////////////////////////////////////
void commad_menu(void){
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
init_cbuff(); // Borro buffer.
}
///////////////////////////////////////
// Procesador de Comandos
///////////////////////////////////////
void commad_process(void){
int n,i,x;
degradianesf1=0;
minutosf1=0;
degradianesf2=0;
minutosf2=0;
latitudf=0;
longitudf=0;
// Primera Parte: Cuantos
n = count_param_number(); // Cuento el número de parámetros
// Segunda Parte: Cuales
if(n>0){
for(i=0;i<n;i++){
if(i==2 || i==3 || i==4 || i==15 || i==17 || i==19 || i==23 || i==18 || i==20){
get_param_by_order(i);
// printf("Parámetro %u <%s>\r\n",i,tmp);
for(x=0;x<lenparam;x++){
if(i==2)
manual[x]=tmp[x];
if(i==3)
encenderunidad[x]=tmp[x];
if(i==4)
celular[x]=tmp[x];
if(i==15)
hora[x]=tmp[x];
if(i==17)
latitud[x]=tmp[x];
if(i==19)
longitud[x]=tmp[x];
if(i==23)
fecha[x]=tmp[x];
if(i==18)
signolatitud[x]=tmp[x];
if(i==20)
signolongitud[x]=tmp[x];
}
}
}
}
init_cbuff(); // Borro buffer.
// si recibe un mensaje
recivosms();
//pasando variables de caracter a numero flotante
//conviersion latitud
degradianes1[0]=latitud[0];
degradianes1[1]=latitud[1];
degradianes1[2]='\0';
minutos1[0]=latitud[2];
minutos1[1]=latitud[3];
minutos1[2]=latitud[4];
minutos1[3]=latitud[5];
minutos1[4]=latitud[6];
minutos1[5]=latitud[7];
minutos1[6]=latitud[8];
minutos1[7]=latitud[9];
minutos1[8]=latitud[10];
degradianesf1
=atof(degradianes1
); minutosf1
=atof(minutos1
);
latitudf=degradianesf1+minutosf1/60;
if(signolatitud[0]=='S')
latitudf=latitudf*(-1);
//conviersion longitud
degradianes2[0]=longitud[0];
degradianes2[1]=longitud[1];
degradianes2[2]=longitud[2];
degradianes2[3]='\0';
minutos2[0]=longitud[3];
minutos2[1]=longitud[4];
minutos2[2]=longitud[5];
minutos2[3]=longitud[6];
minutos2[4]=longitud[7];
minutos2[5]=longitud[8];
minutos2[6]=longitud[9];
minutos2[7]=longitud[10];
minutos2[8]=longitud[11];
degradianesf2
=atof(degradianes2
); minutosf2
=atof(minutos2
);
longitudf=degradianesf2+minutosf2/60;
if(signolongitud[0]=='W')
longitudf=longitudf-longitudf*(2);
//------dia de la semana
dia[0]=fecha[0];
dia[1]=fecha[1];
mes[0]=fecha[2];
mes[1]=fecha[3];
ano[0]=fecha[4];
ano[1]=fecha[5];
//tabla de meeses
if(mesf==1 || mesf==10)
mestabla=0;
if(mesf==2 || mesf==3 || mesf==11)
mestabla=3;
if(mesf==4 || mesf==7)
mestabla=6;
if(mesf==5)
mestabla=1;
if(mesf==6)
mestabla=4;
if(mesf==8)
mestabla=2;
if(mesf==9 || mesf==12)
mestabla=5;
sumadia=diaf+mestabla; //sumo dia y el valor del mes(segun la tabla de meses)
if(sumadia>6){ //si es mayor a 6, restarle el mayor multiplo de 7
multiplo=sumadia/7;
sumadia=sumadia-7*multiplo;
}
multiplo=anof/28; //restale al año (a sus ultimos dos digitos) el mayoy multiplo de 28 que en el
sumaano=anof-multiplo*28;
multiplo=sumaano/4; //anof/4;
sumaano=sumaano+multiplo; //la tabla de siglos del año 2000=0 por lo tanto no lo sumo
//--------- si es bisiesto resta uno
if((mesf==1 || mesf==2) && (anof==16 || anof==20 || anof==24 || anof==28 || anof==32 || anof==36 || anof==40 || anof==44 || anof==48 || anof==52 || anof==56 || anof==60 || anof==64 || anof==68 || anof==72 || anof==76 || anof==80 || anof==84 || anof==88 || anof==92 || anof==96))
sumaano=sumaano-1;
dianumero=sumadia+sumaano;
if(dianumero>6){
multiplo=dianumero/7;
dianumero=dianumero-multiplo*7;
}
//--------------------------------------------------------------------------------------
//encendido unidadgps
if(dianumero==2){ //si es lunes
if(horaf>100000) unidadgps=1; //si la hora es mayor de las 10 pm hora internacional
else{unidadgps=0;}
}
if(dianumero==3 || dianumero==4 || dianumero==5|| dianumero==6) { //si es martes, miercoles, jueves o viernes
if(!(horaf>10000 && horaf<100000)) unidadgps=1; //si la hora no esta entre la 1 am y 10 am hora internacional
else{unidadgps=0;}
}
if(dianumero==0){ //si es sabado
if(horaf<10000 || (horaf>100000 && horaf<170000)) unidadgps=1;
else{unidadgps=0;}}
// Manual / Automatica
seleccionar();
//se envia mensaje sms
enviosms();
//------------------------------------------------------------------------------------------
init_cbuff();
flagcommand=0; // Desactivo flag de comando pendiente.
/* lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"%f %s",degradianesf2,degradianes2);
lcd_gotoxy(1,2);
printf(lcd_putc,"lontud %05.5f",longitudf);
delay_ms(2000);
init_cbuff();
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"fecha %f",fechaf);
lcd_gotoxy(1,2);
printf(lcd_putc,"dia %u unidadON %u",dianumero,unidadgps);
delay_ms(2000);
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"udadm%u manual%u",unidadsms,manualsms);
lcd_gotoxy(1,2);
printf(lcd_putc,"udag %u unidad %u",unidadgps,unidad); */
delay_ms(2000);
flagcommand=0; // Desactivo flag de comando pendiente.
init_cbuff();
}
///////////////////////////////////////
// INTERRUPCIONES : RDA Recepción USART
///////////////////////////////////////
#int_rda
void serial_isr() { // Interrupción recepción serie USART
char rcvchar=0x00; // último caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar
=getc(); // lo descargo y ... add_2_cbuff(rcvchar); // lo añado al buffer y ...
}
}
///////////////////////////////////////
// MAIN
///////////////////////////////////////
void main() {
enable_interrupts(int_rda); // Habilita Interrupción RDA <<<<estas dos lines deben ir primero que todo
enable_interrupts(global); // Habilita interrupciones
// write_int16_eeprom(0x05, (int16)(servicios));
servicios = (int16)read_int16_eeprom(0x05);
delay_ms(100);
init_cbuff(); // Borra buffer al inicio
commad_menu();
do {
creditos();
sensores();
puerta();
if(flagcommand==1) commad_process(); // Hay algo pendiente de procesar y lo procesa.
if(flagcommand==2) corrertiempo();
} while (TRUE);
}