Aqui muestro el codigo.
Seguro que hay fallos, de hecho, sé donde hay varios, pero tengo que terminarlo o no acabaré nunca, ya que ya me ha llegado el sensor de humedad y tengo que reestructurar muchas cosas antes de incluirlo. Por favor posteen y a ver si pronto lo publico en un blog o algo asi junto con el software del PC.
Quiero agradecer a todos los miembros de este foro la información aportada, ya que todo lo que he aprendido (hace un par de meses no sabia absolutamente nada) lo he aprendido aqui y en menor medida de otros foros.
Un agradecimiento especial a RedPic y a su web
http://picmania.garcia-cuervo.net/index.php, me ha sido de muchisima ayuda para iniciarme en los microcontroladores PIC, y sobre todo su libreria _ds1307.c (
http://picmania.garcia-cuervo.net/proyectos_aux_rtc.php ).
Con este humilde proyecto, quiero hacer mi pequeña aportación a este inmenso foro, pero sobre todo demostrarme a mi mismo que en estos tiempos dificiles, cuando uno pasa por momentos complicados, sin trabajo y con tiempo libre, merece la pena estudiar un poco y aprender cosas nuevas que nos llenen y aumenten nuestra autoestima, y si es posible aumentar nuestro curriculum.
Yo no soy ingeniero, ni tengo experiencia en la programación, pero queria demostrarme a mi mismo, que cuando uno quiere, puede, aun siendo todo aparentemente "inaccesible", siempre hay alguien que por un interés u otro, aporta sus conocimientos al mundo a traves de diversos medios.
El prototipo tiene un coste para mi casi ridiculo:
PIC 18f2550. cortesia de Microchip
Panatalla LCD 16x2. Reciclaje
Memoria EEPROM. cortesia de Microchip
DS1307. Cortesia de Maxim
Conector USB. Reciclaje
XTAL's. Reciclaje
Añadimos pila cr2032, portapilas, lm35 y algunos componentes, en total no creo que llegue a los 5€.
#define USB_HID_DEVICE FALSE //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 32 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 32 //size to allocate for the rx endpoint 1 buffer
#include <includes\Lectura_de_datos_USB_y_muestra_LCD.h>
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <includes\usb_cdc.h> // Descripción de funciones del USB.
#include <usb.c> //handles usb setup tokens and get descriptor reports
#include <stdlib.h>
#include <math.h>
#include <includes\2432.c>
#include <includes\floatee.c>
#include <includes\_ds1307.c>
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
#define LCD_RS PIN_B3
#define LCD_RW PIN_A1
#define LCD_E PIN_B2
#define PRIMER_BYTE 0x0014
#include <includes\flex_LCD.C>
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#define _version 106 // Version
char version[]="106";
long adc_valor; //varias muestras para luego promediarlas
float conversion;
int i; //Para los bucles
char datosRecibidos;
short modoConfig;
short recibeDateTime;
short recibeDatosCaptura;
short memoriaOk = 0;
byte sec;
byte min;
byte hrs;
byte day;
byte month;
byte yr;
byte dow;
//char sdow[11];
char dia[3];
char mes[3];
char ano[3];
char hora[3];
char minu[3];
char seg[3];
char registros[5]; // numero maximo registros
char direccionMax[7]; // numero maximo de direcciones de memoria
char fechahora[2]; // si vamos a grabar la fecha, la hora o ambos (0->nada , 1->fecha,2->hora,3->ambos)
char cadencia[2]; // indica la cadencia de la captura (1->dia , 2->hora,3->minuto,4->segundo)
char undCadencia[3];// indica el multiplicador de cadencia (unidades)
int16 iregistros;
int16 iSiguienteDireccion = PRIMER_BYTE; // La direccion de memoria donde comenzará el siguiente registro (quedará guardado en 0x000E y 0x000F)
char modoCaptura[2]; // modo de captura ON / OFF
int iUndCadencia;
int iCadencia;
short isModo;
short intExterna = 0; // una bandera, para saber si se pulsó en RB0, se utilizará en el while principal
#int_EXT // RB0
void EXT_isr(void)
{
intExterna = 1; // Una bandera
}
void cambioModo(){
int read = read_ext_eeprom(0x0002);
if (read == 0){
write_ext_eeprom(0x0002, 0x0001); //Ponemos el byte 0x0002 a 1 --->>>>> isModo = 1 ; isCaptura();
}
if (read == 1){
write_ext_eeprom(0x0002, 0x0000);
}
}
void isCaptura(){
/////////////////////////////////////////////
// Vemos si hay que ponerlo en modo captura
/////////////////////////////////////////////
int read = read_ext_eeprom(0x002);
if (read == 1) // El byte 0x002 establece si estamos en modo captura 0/1
{
output_high(PIN_C7);
isModo = 1;
iUndCadencia = read_ext_eeprom(0x009);
iCadencia = read_ext_eeprom(0x0008);
iregistros = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B)); // iregistros toma el numero de registros que quedan disponibles
}
if (read == 0)
{
output_low(PIN_C7);
isModo = 0;
}
}
/////////////////////////////////////////////////////////
// Para cuando queramos poner una memoria como OK
// Las direcciones 0x000C y 0x000D almacenan el numero
// de bytes
/////////////////////////////////////////////////////////
SetMemoria(){
char OK = "O";
if (make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)) == 0) // Vemos cuantos bytes tiene la memoria, si es 0 devolvemos False
{
return 0;
}
else
{
write_ext_eeprom(make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)), OK); // En caso de que no sea 0 grabamos un O en el ultimo byte
return 1;
}
}
comprobarEEPROM(){
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Comprobando");
printf(lcd_putc,"\n");
printf(lcd_putc,"Memoria externa");
delay_ms(1000);
if (make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)) == 0)
{
return 0;
}
if (read_ext_eeprom(make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D))) == 0x4F) //0x4F = "O"
{
return 1;
}
else
{
return 0;
}
}
short SetGrabacion(int hora, int min,int seg){ // Decide si hay que grabar el dato
int pHora; // proxima hora en la que hacemos grabación
int pMin; // proximo minuto en el que hacemos grabación
int pSeg; // proximo segundo en el que hacemos grabación
pHora = read_ext_eeprom(0x0011); // Leemos de la memoria la proxima hora en la que hacemos grabación
pMin = read_ext_eeprom(0x0012); // Leemos de la memoria el proximo minuto en el que hacemos grabación
pSeg = read_ext_eeprom(0x0013); // Leemos de la memoria el proximo segundo en el que hacemos grabación
if (pHora == hora && pMin == min && pSeg == seg){
return 1;
}
else{
return 0;
}
}
void ProxGrabacion(){ // Grabamos en la memoria cuando será la proxima grabacion
int pHora; // proxima hora en la que hacemos grabación
int pMin; // proximo minuto en el que hacemos grabación
int pSeg; // proximo segundo en el que hacemos grabación
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
if (iCadencia == 1){
pHora = hrs + iUndCadencia;
pMin = min;
pSeg = sec;
}
if (iCadencia == 2){
pHora = hrs;
pMin = min + iUndCadencia;
pSeg = sec;
}
if (iCadencia == 3){
pHora = hrs;
pMin = min;
pSeg = sec + iUndCadencia;
}
if (pSeg > 59){
pSeg = pSeg - 60;
pMin ++;
}
if (pMin > 59){
pMin = pMin - 60;
pHora++;
}
if (pHora > 23){
pHora = pHora - 24;
}
write_ext_eeprom(0x0011, pHora);
write_ext_eeprom(0x0012, pMin);
write_ext_eeprom(0x0013, pSeg);
}
void modoConfiguracion(){
int16 iregistrosCapturados;
lcd_putc('\f');
printf(lcd_putc, "Modo configuracion");
modoConfig=true;
delay_ms(1000);
while(modoConfig){
if(usb_cdc_kbhit()) //Devuelve 1 se hay un nuevo dato en buffer de recepcion
{
datosRecibidos = usb_cdc_getc();
if (datosRecibidos=='d'){ //si desconectamos el modo configuracion
modoConfig=false;
}
if (datosRecibidos=='B'){ //Solicitar el borrado de la memoria externa
int16 porcentaje = 0;
int16 i = 0x000;
int factor;
iregistros = make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)); //direccion maxima de memoria
lcd_putc('\f'); //Limpia pantalla
printf(lcd_putc,"Borrando MEMORIA.");
if (iregistros == 0)
{
printf(usb_cdc_putc,"100");
}
factor = (iregistros / 100) + 1; //porque 40.95 redondea a 40, asi que le sumamos 1
for (i=0;i<=iregistros;i++)
{
write_ext_eeprom(i, 0x0000);
delay_ms(5);
if (porcentaje < ((int16) i/factor)){
porcentaje= i /factor;
lcd_gotoxy(1,2);
printf(lcd_putc,"Completado: %Lu%%",porcentaje);
printf(usb_cdc_putc,"%Lu",porcentaje);
}
}
lcd_putc('\f');
printf(lcd_putc,"MEMORIA borrada");
delay_ms(1000);
//reset_cpu();
} // END IF
if (datosRecibidos=='f'){ //Solicita fecha y hora
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf(usb_cdc_putc,"%02d/%02d/%02d %02d:%02d:%02d",day,month,yr,hrs,min,sec);
} // END IF
if (datosRecibidos=='F'){ //Cambiamos fecha
recibeDateTime = true;
lcd_gotoxy(1,2);
printf(lcd_putc,"Esperando fecha");
while(recibeDateTime){
if(usb_cdc_kbhit()){
get_string_usb(dia, 3);
get_string_usb(mes, 3);
get_string_usb(ano, 3);
get_string_usb(hora, 3);
get_string_usb(minu, 3);
get_string_usb(seg, 3);
ds1307_set_date_time(atoi(dia),atoi(mes),atoi(ano),dow,atoi(hora),atoi(minu),atoi(seg));
lcd_putc('\f'); //Limpia pantalla
printf(lcd_putc,"Fecha y hora\n" );
printf(lcd_putc,"establecida..." );
delay_ms(500);
lcd_putc('\f'); //Limpia pantalla
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf(lcd_putc,"\%02d/\%02d/\%02d ",day,month,yr);
printf(lcd_putc,"\%02d:\%02d", hrs,min);
delay_ms(750);
lcd_putc('\f');
printf(lcd_putc, "Modo configuracion");
recibeDateTime = 0;
} // end if
} // end while recibeDateTime
} // end if datosRecibidos == 'F'
if (datosRecibidos=='G'){ //Establecemos configuracion de la captura
recibeDatosCaptura = true;
lcd_gotoxy(1,2);
printf(lcd_putc,"Esperando config.");
while(recibeDatosCaptura){
if(usb_cdc_kbhit()){
get_string_usb(registros, 5); // Recibimos string y lo guardamos en variable
get_string_usb(fechahora, 2);
get_string_usb(cadencia, 2);
get_string_usb(undCadencia,3);
get_string_usb(modoCaptura,2);
get_string_usb(direccionMax,7);
write_ext_eeprom(0x0005, atoi(fechahora)); // Indica que vamos a grabar (nada, fecha, hora o ambas - 0/1/2/3)
iregistros = atol(registros); // Covertimos cadena a numero entero
write_ext_eeprom(0x0006, make8(iregistros,1)); // Numero maximo de registros que tenemos enviados por el PC byte alto
write_ext_eeprom(0x0007, iregistros); // Numero maximo de registros que tenemos enviados por el PC byte bajo
iregistros = atol(registros); // Covertimos cadena a numero entero
write_ext_eeprom(0x000A, make8(iregistros,1)); // Cuantos registros tenemos disponibles en la memoria byte alto
write_ext_eeprom(0x000B, iregistros); // Cuantos registros tenemos disponibles en la memoria byte bajo
write_ext_eeprom(0x0008, atoi(cadencia)); // cada cuantas Horas o minutos o segundos
write_ext_eeprom(0x0009, atoi(undCadencia)); // Unidades de dias horas minutos etc
write_ext_eeprom(0x0002, atoi(modoCaptura)); // modo captura 0/1
iregistros = atol(direccionMax); // Covertimos cadena a numero entero
write_ext_eeprom(0x000C, make8(iregistros,1)); // direccion maxima de memoria byte alto
write_ext_eeprom(0x000D, iregistros); // direccion maxima de memoria byte bajo
write_ext_eeprom(0x000E, 0x0000); // Grabamos la primera direccion de memoria donde comenzara la grabación
write_ext_eeprom(0x000F, PRIMER_BYTE); // Grabamos la primera direccion de memoria donde comenzara la grabación
ProxGrabacion();
recibeDatosCaptura = 0; // para salir del bucle 0 = FALSE
} // end if
} //end while
}
if (datosRecibidos=='L'){ //Solicita configuracion
iregistros = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));//Registros disponibles
if (iregistros == 0){
iregistros = make16(read_ext_eeprom(0x0006),read_ext_eeprom(0x0007)); //Registros totales segun envio de la aplicacion
write_ext_eeprom(0x000A, make8(iregistros,1));
write_ext_eeprom(0x000B, iregistros);
iregistros = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B)); //Registros disponibles para seguir capturando
}
iregistrosCapturados = make16(read_ext_eeprom(0x0006),read_ext_eeprom(0x0007)) - make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));
printf(usb_cdc_putc,"%d %d %d %02d %04lu %04lu", read_ext_eeprom(0x002),read_ext_eeprom(0x005),read_ext_eeprom(0x008),read_ext_eeprom(0x009),iregistros,iregistrosCapturados);
} // END IF "L"
if (datosRecibidos == 'y'){ // solicita el estado del byte de control
if (comprobarEEPROM()){
printf(usb_cdc_putc,"O"); // si el byte de control esta correcto le enviamos una O
}
if (!comprobarEEPROM()){
printf(usb_cdc_putc,"E"); // si el byte de control no esta correcto le enviamos una E
}
} //END IF "y"
if (datosRecibidos=='Y'){ //graba el byte de control
if (SetMemoria()){
printf(usb_cdc_putc,"O"); //si la direccion es mayor que 0 graba el byte y le enviamos una O
}
if (!SetMemoria()){
printf(usb_cdc_putc,"E"); // si la direccion de memoria es 0 no se graba el byte de control y le enviamos una E
}
} // END IF "Y"
if (datosRecibidos=='I'){ //Comienzo de las capturas
write_ext_eeprom(0x0002, 0x0001); //Ponemos el byte 0x0002 a 1 --->>>>> isModo = 1 ; //isCaptura();
isModo = 1;
} // END IF "I"
if (datosRecibidos=='i'){ //Final de las capturas
write_ext_eeprom(0x0002, 0x0000); //Ponemos el byte 0x0002 a 0
isModo = 0;
} // END IF "i"
if (datosRecibidos=='R'){
printf(usb_cdc_putc,"%d", read_ext_eeprom(0x003));
} //END IF R
if (datosRecibidos=='D'){ //Descargar datos
short enviando;
int16 direccion = PRIMER_BYTE;
float temp;
lcd_putc('\f');
printf(lcd_putc, "Descargando...");
enviando = true;
while (enviando){
if(usb_cdc_kbhit()){
datosRecibidos = usb_cdc_getc();
if (datosRecibidos=='c'){ // Terminar (para salir del while
enviando = false;
}
if (datosRecibidos=='s'){ // Solicitamos dato, en este caso no será temperatura
printf(usb_cdc_putc,"%02d" , read_ext_eeprom(direccion));
direccion++;
}
if (datosRecibidos=='t'){ // Solicitamos dato, en este caso será temperatura (2 bytes)
temp = make16(read_ext_eeprom(direccion),read_ext_eeprom(direccion+1)) / 10;
printf(usb_cdc_putc,"%03.1f" , temp );
direccion+=2;
}
}
} // END while
} //END IF D
lcd_putc('\f');
printf(lcd_putc, "Modo configuracion");
} // END IF kbhit
} //END WHILE
lcd_putc('\f');
} //END modoConfiguración
void grabarDato(int16 dato){
output_high(PIN_C6);
int16 registrosdisponibles;
int fechahora;
fechahora = read_ext_eeprom(0x0005);
iSiguienteDireccion = make16(read_ext_eeprom(0x000E),read_ext_eeprom(0x000F)); // Ultima direccion grabada
if ((fechahora == 1) || (fechahora == 3)){
ds1307_get_date(day,month,yr,dow);
write_ext_eeprom(iSiguienteDireccion, day);
iSiguienteDireccion++;
write_ext_eeprom(iSiguienteDireccion, month);
iSiguienteDireccion++;
write_ext_eeprom(iSiguienteDireccion, yr);
iSiguienteDireccion++;
}
if (fechahora == 2 || (fechahora == 3)){
ds1307_get_time(hrs,min,sec);
write_ext_eeprom(iSiguienteDireccion, hrs);
iSiguienteDireccion++;
write_ext_eeprom(iSiguienteDireccion, min);
iSiguienteDireccion++;
write_ext_eeprom(iSiguienteDireccion, sec);
iSiguienteDireccion++;
}
write_ext_eeprom(iSiguienteDireccion, make8(dato,1));
iSiguienteDireccion++;
write_ext_eeprom(iSiguienteDireccion, dato);
ProxGrabacion(); // para grabar cuando será la proxima captura
iSiguienteDireccion++; // aumentamos la siguiente direccion. Obvio, si no, se sobreescribirian los datos
write_ext_eeprom(0x000E, make8(iSiguienteDireccion,1)); // y la grabamos, (byte alto y byte bajo)
write_ext_eeprom(0x000F, iSiguienteDireccion);
///////////////////////////////////////////////////////////////////////////
// Vamos a restar un registro a "registros disponibles"
// Esto es para llevar un control de cuando se nos puede acabar la memoria
////////////////////////////////////////////////////////////////////////////
registrosdisponibles = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));
registrosdisponibles--;
write_ext_eeprom(0x000A, make8(registrosdisponibles,1));
write_ext_eeprom(0x000B, registrosdisponibles);
if (read_ext_eeprom(0x0003) == 0){
write_ext_eeprom(0x0003, 1);
} //si el byte de control de datos grabados esta a 0 lo ponemos a 1
output_low(PIN_C6);
} // END grabarDato()
void main(){
enable_interrupts(GLOBAL); // Se habilita la interrupción global
enable_interrupts(INT_EXT); // Se habilita la interrupción externa
setup_adc_ports(AN0|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_adc_channel(0);
init_ext_eeprom(); //inicializamos memoria EEPROM externa
ds1307_init(DS1307_OUT_ON_DISABLED_HIHG ); // Inicializamos el ds1307
lcd_init(); // empiezo a usar los comandos de la libreria del lcd
set_tris_a(255);
set_tris_b(0b00000001);
set_tris_c(0); // configurando portc como salida
SetMemoria();
////////////////////////////////////////////////////////
// Para cuando queramos poner una version en una EEPROM
//
//
write_ext_eeprom(0x001, _version);
delay_us(10);
//
/////////////////////////////////////////////////////////////////
// Comprobamos que hay una memoria conectada con una "O" al final
memoriaOk = comprobarEEPROM();
if (memoriaOk){
lcd_putc("\f");
printf(lcd_putc,"Memoria OK.");
delay_ms(2000);
}
if (!memoriaOk){
lcd_putc("\f");
printf(lcd_putc,"Memoria");
printf(lcd_putc,"\n");
printf(lcd_putc,"desconocida.");
delay_ms(2000);
}
// Vamos a comprobar la version que tiene la version la EEPROM, si es menor la grabamos, despues mostramos en el LCD.
lcd_putc("\f");
printf(lcd_putc,"Comprobando");
printf(lcd_putc,"\n");
printf(lcd_putc,"Version...");
delay_ms(300);
if (read_ext_eeprom(0x001) < _version)
{
write_ext_eeprom(0x001, _version);
lcd_putc("\f");
printf(lcd_putc,"Guardando ver.");
delay_ms(1000);
}
//convertimos la version xxx en una cadena
itoa(read_ext_eeprom(0x001),10,version);
printf(lcd_putc,"\n");
printf(lcd_putc,"Version: ");
printf(lcd_putc, "v.%C.%C.%C" , version[0], version[1] , version[2]);
delay_ms(1000);
usb_cdc_init();
usb_init(); //inicializa el USB
usb_task();
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Esperando");
printf(lcd_putc,"\n");
printf(lcd_putc,"conexion USB....");
lcd_gotoxy(1,1);
printf(lcd_putc,"Termometro");
lcd_gotoxy(1,2);
printf(lcd_putc,"Digital by Ale");
delay_ms(1000);
lcd_putc('\f');
isCaptura(); // vamos a ver si tenemos que poner el dispositivo en modo captura
while(true) // bucle infinito
{
lcd_gotoxy(1,1);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf(lcd_putc,"\%02d/\%02d/\%02d ",day,month,yr);
printf(lcd_putc,"\%02d:\%02d", hrs,min);
if (intExterna){
intExterna = 0;
cambioModo();
isCaptura();
ProxGrabacion();
}
for(i=0; i<200;i++) //Tomas 200 muestras y las sumas en grados_temperatura
{
adc_valor+= read_adc();
delay_us(11); //Demos tiempo al ADC para terminar la conversión anterior (TAD)
}
adc_valor /= 200; //aqui calculas el promedio de 200 muestras
conversion=(float) adc_valor;
//setup_adc (adc_off);
conversion=conversion*0.48875; //Pasa binario a °C
//
//el "0.48875" sale de dividir 5/1023 (10bits) y el resultado de eso multiplicarlo
//por 100 el 5 sale de los 5 voltios aplicado al voltaje de referencia, los 1023
//salen de los 10 bit de resolución del conversor analógico digital.
//Si utilizáramos la resolucion de 8 bist del conversor analógico digital, la
//formula sería (5/255)*100 ya que con 8 bits el numero máximo posible es de 0-255
lcd_gotoxy(1,2);
printf(lcd_putc,"T: %03.1f \xdfC",conversion);
if ((isModo) && (iregistros > 1)){
if (SetGrabacion(hrs,min,sec)) {
grabarDato(conversion*10); // Lo multiplicamos por 10 para quitarle el decimal y asi ocupar solo 2 bytes de memoria
}
}
if(usb_cdc_kbhit()) //Devuelve 1 se hay un nuevo dato en buffer de recepcion
{
datosRecibidos = usb_cdc_getc();
if (datosRecibidos=='c'){ //Vamos a Configuracion
modoConfiguracion();
}
if (datosRecibidos=='t'){ //Solicitamos la temperatura
printf(usb_cdc_putc,"%03.1f",conversion);
}
if (datosRecibidos=='v'){ //Solicitamos la version del Hardware
itoa(read_ext_eeprom(0x001),10,version);
printf(usb_cdc_putc, "v.%C.%C.%C" , version[0], version[1] , version[2]);
}
if (datosRecibidos=='f'){
printf(usb_cdc_putc,"%02d/%02d/%02d %02d:%02d:%02d",day,month,yr,hrs,min,sec);
}
}
} //fin de while
} //fin de main