# Consulta CCS lectura ADC y envio por puerto serie



## Wever20 (Mar 21, 2014)

Hola a todos. Hace dos días me puse a diseñar un pequeño programa con un PIC16F88 y quisiera corroborar unas cosas.
El programa realiza la siguiente función: Desde otra plataforma enviaré al PIC una señal para que se produzca una interrupción externa (Por el pin RB0 de éste PIC). Una vez se produzca la interrupción mi idea es que dentro de la rutina de servicio a ésta interrupción se comience a leer el canal 0 del ADC. Luego el valor de ésta lectura se convertirá a voltios y se enviará por puerto serie a un Arduino y el PIC volverá a entrar en SLEEP. 
Es uno de mis primeros programas en CCS y quiero verificar cosas para ver si voy por buen camino. Gracias y expongo el código.


```
#include <16F88.h>
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock 8000000)  //8MHZ DEL CLOCK DEL PIC
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2)  //CONFIGURO PUERTO SERIE
#device adc=10  //INDICO EL NÚMERO DE BITS DEL ADC

#int_EXT    // CREO QUE ÉSTO ME PERMITE INDICAR QUE LO SIGUIENTE SERÁ LA RUTINA DE SERVICIO A LA INT. DEL RB0
void intRBO () {
long valor=0;   //DEFINO UNA VARIABLE DE 16BITS PARA GUARDAR EL VALOR DEL ADC
float voltios=0; //DEFINO UN FLOAT PARA EL VALOR DEL VOTAJE DEL ADC 
set_adc_channel(0);  //SELECCIONO CANAL 0 (PIN A0) DEL ADC PARA A LEER.
delay_us(20);
valor=read_adc();
voltios=(5.0*(valor/1024.0));
puts(voltios);
}

void main(void){

enable_interrupts(GLOBAL);  //HABITILRO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_EXT); //HABILITO LA INTERRUPCIÓN DEL PIN RB0
setup_adc_ports(sAN0);    //INDICO EL PIN A0 COMO ENTRADA ANALÓGICA 
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC
SLEEP();

}
```


----------



## Gudino Roberto duberlin (Mar 21, 2014)

Hola, bueno, la variable "valor1" y "voltios" donde se encuentran declaradas?


----------



## Wever20 (Mar 21, 2014)

Gudino Roberto duberlin dijo:


> Hola, bueno, la variable "valor1" y "voltios" donde se encuentran declaradas?



disculpa vi el fallo y lo volví a reescribir. Muchas gracias



La idea es que cuando se envíe el resultado de la conversión ADC, en voltios, lo haga con sus decimales por eso defino un "float voltios". Quiero crear posteriormente un programa para conectarlo en el Arduino y me lea dicho valor. La cuestión es que no estoy seguro que sea tan fácil enviar por puerto serie un valor float.


----------



## ByAxel (Mar 21, 2014)

Hola, no he probado pero se me ocurre:
Como el tipo float es de 32bits se puede separar de 8 en 8 (4 byte) y enviarlos por el puerto... el receptor se encarga de volver a unir todo para tener el valor. Aquí si es de mirocontrolador a microcontrolador es medio sencillo.

Otra es convertir el valor Float en una cadena y enviar como string... el receptor lo recive como string (array) y para trabajar con él a un nivel numérico se tiene que volver a convertir (string a número).

También se puede trabajar todo con enteros que para el caso se obtiene un mismo resultado, solo se multiplica a cada uno x10, x100, x1000 (enteros) de acuerdo a la cantidad de decimales que se quieras y luego hay que jugar con el separador decimal... bueno también se ahorra algo de código ya que operaciones con float suelen consumir memoria en un PIC medio de 8 bits.

Saludos.


----------



## Wever20 (Mar 21, 2014)

Cuando el valor numérico se envíe al Arduino, el Arduino lo único que hará es reenviarlo a otro programa realizado en Labview (esa es mi idea). Creo que transformar el valor float a String es lo más sencillo ya que desde Labview o desde el mismo Arduino podría pasar de nuevo éste string a float.

¿Respecto al código realizado a primera vista parece ser correcto para la función que quiero realizar?


----------



## ByAxel (Mar 21, 2014)

Si, está bien, solo un detalle que no es problema... cuando salga de Sleep, el flujo va a volver a main haciendo que todas las líneas de configuración se vuelvan a repetir... en la práctica puede que no se note pero para asegurar se puede envolver a Sleep dentro de While(True)...

Pregunto: Te surge algún aviso al compilar?, pasa que los Delays no se llevan bien con los bloques de interrupción, puede que ahí necesites hacer un delay manualmente... pero nada crítico.


----------



## Wever20 (Mar 21, 2014)

Muchas gracias por tu rápida respuesta. Pues justo al compilarlo me sale el siguiente mensaje. Estoy utilizando MPLAB IDE 8.87 y el compilador CCS también he instalado los pugins de la página oficial de CCS para poder compilar con MPLAB. Supongo que éste tipo de mensaje es algun problema con el compilador... Pero creo que he realizado correctamente los pasos en project wizard de mplab

Clean: Deleting intermediary and output files.
Clean: Deleted file "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\ProgramaPIC.mcs".
Clean: Done.
Executing: "D:\Archivos de programa\PICC\Ccsc.exe" +FM "..\..\..\..\Archivos de programa\PICC\Examples\ex_RS232_485.c" #__DEBUG=1 +ICD +DF +LN +T +A +M +Z +Y=9 +EA  #__16F88=TRUE
BUILD FAILED: Fri Mar 21 15:43:22 2014


----------



## Gudino Roberto duberlin (Mar 21, 2014)

ByAxel dijo:


> Hola, no he probado pero se me ocurre:
> Como el tipo float es de 32bits se puede separar de 8 en 8 (4 byte) y enviarlos por el puerto... el receptor se encarga de volver a unir todo para tener el valor. Aquí si es de mirocontrolador a microcontrolador es medio sencillo.
> 
> Otra es convertir el valor Float en una cadena y enviar como string... el receptor lo recive como string (array) y para trabajar con él a un nivel numérico se tiene que volver a convertir (string a número).
> ...




Hola, pregunto, pues es una duda que hasta el día de hoy no cierra. En éste caso puntual, del compañero. Se almacena una variable que puede contener 1024 valores posibles (ADC), en un formato de variable tipo float 32bits, pues bien, como pueden obtenerse dichos valores (32 bits), a partir de una variable de 10 bits?.
Pues, en mi experiencia, cuando quiero obtener decimales, a partir de un entero, debo sacrificar varios bits de la parte entera y tratarla como una mantisa, pero la cantidad total de bits, será siempre la misma.


----------



## Wever20 (Mar 21, 2014)

He conseguido que compile. Resulta que luego de configurar correctamente tenia que poner "#device adc=10" después de definir el dispositivo PIC. En el programa no está puesto correctamente ya que de esa manera da problemas. 

correctamente es:

#include <16F88.h>
*#device adc=10 * 
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
*#use delay(clock=8000000)* //Le he puesto un "=" entre el clock y el valor
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //CONFIGURO PUERTO SERI





Gudino Roberto duberlin dijo:


> Hola, pregunto, pues es una duda que hasta el día de hoy no cierra. En éste caso puntual, del compañero. Se almacena una variable que puede contener 1024 valores posibles (ADC), en un formato de variable tipo float 32bits, pues bien, como pueden obtenerse dichos valores (32 bits), a partir de una variable de 10 bits?.
> Pues, en mi experiencia, cuando quiero obtener decimales, a partir de un entero, debo sacrificar varios bits de la parte entera y tratarla como una mantisa, pero la cantidad total de bits, será siempre la misma.



Si mi idea es enviar el resultado de la variable "voltios" (por ejemplo voltios=0,004882) podría funcionar la función "fprint". Con ésta función cambio un resultado en coma flotante a String (creo que es así, quizás me equivoque). 

*fprint("%1.6f\r\n",voltios);* // con %1.6 le indicamos que quiero cojer solo un carácter de la parte entera y 6 caracteres decimales de la variable voltios. Luego finalizaría con retorno de carro y caracter nulo para indicar fin del string. Como el máximo valor del ADC que tendré es 5 o 4,9xxxxx... no sé si ésto podría funcionar


----------



## ByAxel (Mar 21, 2014)

Wever20 dijo:


> Si mi idea es enviar el resultado de la variable "voltios" (por ejemplo voltios=0,004882) ... string (creo que es así, quizás me equivoque)....
> 
> *fprint("%1.6f\r\n",voltios);* // con %1.6 le indicamos que quiero cojer solo un carácter de la parte entera y 6 caracteres decimales de la variable voltios. Luego finalizaría con retorno de carro y caracter nulo para indicar fin del string. Como el máximo valor del ADC que tendré es 5 o 4,9xxxxx... no sé si ésto podría funcionar



Puede que no sea tan precisa a un nivel numérico, es decir que a la hora de imprimir con 6 decimales, en realidad los 4, 3 o 2 últimos decimales solo sean ceros. aprobar...



Gudino Roberto duberlin dijo:


> Se almacena una variable que puede contener 1024 valores posibles (ADC), en un formato de variable tipo float 32bits, pues bien, como pueden obtenerse dichos valores (32 bits), a partir de una variable de 10 bits?.
> Pues, en mi experiencia, cuando quiero obtener decimales, a partir de un entero, debo sacrificar varios bits de la parte entera y tratarla como una mantisa, pero la cantidad total de bits, será siempre la misma.



Los tipos float estan normados con cierto formato y longitud de bits (pueden ser de 24 o 32), supongo que el CCS utiliza el formato IEEE754 explicado según microchip AN575... leelo, puede que te quede más claro que a mí.

Pasar un valor de 10 bits a 32bits float es como una conversión/adaptación, CCS utiliza internamente funsiones para adaptar los valores... una que encontre en el .lst es ITOF, supongo para adaptar valor entero (16 bits) a float.


----------



## Gudino Roberto duberlin (Mar 21, 2014)

Amigo ByAxel, gracias, pero aún leyendo cualquier documento, por lógica que algo no deduzco es lo sig.
Si por ejem. tienes una variable capaz de almacenar 10 bits, entonces tendrás 1024 valores posibles, bien, entonces si ahora queremos representar esa misma variable pero en un formato float, en el cual queremos visualizar, tomemos como ejem. el del compañero, que desea mostrar esa variable con un entero y seis decimales. 
Entonces resumiendo, tenemos 6 decimales en los cuales puede adoptar de 0 a 999.999, es decir 1.000.000 de valores diferentes y además mostrar una unidad de enteros.
En definitiva, como puede cualquier programa cuantificar un valor entre 2 valores consecutivos?, y obtener posibles valores adicionales entre estos?
Por ejem. el ADC arroja 1ro. un valor digamos 896, en la sig. muestra será 897.
Bueno en el formato float debo averiguar que valor es realmente, siendo que puede estar entre 896 y 896,999999.


----------



## Wever20 (Mar 22, 2014)

En el caso de necesitar que un PIC se "despierte" (una vez utilizada la función SLEEP) por ejemplo cada 10 minutos. ¿Sería posible mediante el timer o watchdog? (Quizás estoy diciendo una burrada).


----------



## oztacen (Ene 10, 2015)

Tengo un problema con este programa. Espero su ayuda.

El código es el siguiente:

```
/*
Autor : Ronald
compañia: G-ELECTRON
descripcion: Controlador de potencia PWM por ADC y USART(software)
*/

// Configuracion del Dispositivo
#include <16F88.h>
#device ADC=8
#fuses HS,NOWDT,NOLVP,NOPROTECT //ordenes para el programado  
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,stream=port,bits=8)
//________________________________________________________________________
// declaracion de variables
int flag_cambio=0,dig=0,cambio=0; // variables temporales 
char dato;                       //  de la comunicacion serial
int temp,valor,RET;           // variables temporales del LDR
int CONT=0,PWM;                // variables temporales del PWM Y inturrp
int set_low,set_high;         // lum_low= indica el nivel mas bajo en  %
int lum_low=20,lum_high=80;  //  lum_low= indica el nivel mas alto en  %                     
                            //   luminosidad minima : 0<set low <8
                           //    luminosidad mmaxima : 1<set low <9 
                          //     OJO: lum_high>lum_low
//________________________________________________________________________ 
// interrupcion para el PWM
#int_timer1
void interrupcion_timer1()
{ set_timer1(65435);
   if (CONT--==0)
   {
   CONT=100;
   output_low(PIN_b7);   
   }
   if (CONT==PWM)
   {
      output_high(pin_b7); 
   }   
}     
// funcion principal
//________________________________________________________________________
void  main()
{
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //prescalador x1
   enable_interrupts(INT_TIMER1); // activa interrupcion Timer1
   enable_interrupts(GLOBAL);   // habilita todas las interrupciones 
   setup_adc (ADC_CLOCK_DIV_32);   
   set_adc_channel(0); // seleccion de canal
// Si el dispositivo viene de fabrica hay que setear los valores 
   lum_low=read_eeprom(50);// si la eeprom esta vacia
   lum_high=read_eeprom(51);// si la eeprom esta vacia
   if(lum_low==0xFF)      // guarde el valor minimo de luminosidad
     {lum_low=40;}      
   if(lum_high==0xFF)      // guarde el valor maximo de luminosidad
     {lum_high=90;}     
     
     PWM=50;  // establece un PWM INTERMEDIO
   while(true)
   {
    set_adc_channel(0); // seleccion de canal
    delay_us(10);      // tiempo para que se estabilice la señal
    temp=read_adc(); // lee el LDR del AN0 
//___________________________________________________________
//  RECEPCION SERIAL Y SETEO DE LUMINOSIDAD
    if(kbhit(port)) // lee si hay algun dato buffer del puerto.
      {dato=getc(port); // LEE EL DATO DEL puerto
         switch(dato)
         {  case 'i':
               flag_cambio=1;cambio=0,dig=0;break; // FLAG CAMBIOS EN LUMINOSIDAD(+ O -)
            case 's':        
               flag_cambio=2;break; //para setear el rango minimo de luminosidad
               
            case '0':               // disminuir la luminosidad
               if(flag_cambio==1)
               { if(PWM<=lum_low)
                 {PWM=lum_low;}
                 else
                 {PWM=PWM-10;} 
                flag_cambio=0; 
                 delay_ms(2); //Retardo de cambio.
               } 
              if(flag_cambio==2)
               {  dig++;
                  if(dig==1)
                  {set_low=dato-48;cambio=0;}
                  if(dig==2)
                  { set_high=dato-48;                                       
                    dig=0;cambio=1;                    
                    flag_cambio=0;}
               }                  
              break;
            case '1': // aumenta luminosidad               
              if(flag_cambio==1)
               { if(PWM>=lum_high)
                  {PWM=lum_high;}
                  else
                  {PWM=PWM+10;}   
                 flag_cambio=0;
                 delay_ms(2); //Retardo de cambio. 
               }
               if(flag_cambio==2)
               {  dig++;
                  if(dig==1)
                  {set_low=dato-48;cambio=0;}
                  if(dig==2)
                  { set_high=dato-48;                                       
                    dig=0;cambio=1;                    
                    flag_cambio=0;}
               }    
                break;
           case 'l':
               fprintf(port,"%i&",PWM);// ENVIA ESTADO DE luminosidad (%)
               flag_cambio=0,cambio=0,dig=0;break;
           default:
            // toma valores desde 2 hasta 9
           if(dato>=50 && dato<=57)
               if(flag_cambio==2)
               {  dig++;
                  if(dig==1)
                  {set_low=dato-48,cambio=0;}
                  if(dig==2)
                  { set_high=dato-48;                                       
                    dig=0;cambio=1;                    
                    flag_cambio=0;}
               }
               break;
         }// switch dato     
      
      } //kbport

 //________________________________________
// Lector de LDR intensidad de luz       
             [COLOR=Red]if(temp>=128) // SI NO HAY LUZ (AUMENTO SU RESISTENCIA)
               {PWM=40;delay_ms(25);}           // el valor MAXIMO
            else
            {PWM=90;delay_ms(25);}     // el valor MINIMO         [/COLOR]
 

//_____________________________________________________
// PULSADORES
if(input(pin_a3)==0) // sube la lumninosidad      
      {
         if(PWM<=lum_low)
           {PWM=lum_low;}
         else
           {PWM=PWM-10;}                  
         delay_ms(25); //Retardo de cambio. 
      }
if(input(pin_a4)==0)  // Baja la Luminosidad
      {  
         if(PWM>=lum_high)
         {PWM=lum_high;}
         else
         {PWM=PWM+10;}                  
         delay_ms(25); //Retardo de cambio. 
      } 
// setea los cambios de la instruccion solo si se han registrado 2 digitos s(xy)
// y solo si el set_high es mayor que el set_low
if(cambio==1)
{if(set_high>set_low)
{lum_low=set_low*10;
 lum_high=set_high*10;write_eeprom(50,lum_low);write_eeprom(51,lum_high);}
// actualiza los datos para el PWM
         if(PWM<=lum_low)    // setea el minimo 
            {PWM=lum_low;}
         if(PWM>=lum_high)  // setea el maximo
            {PWM=lum_high;}
 cambio=0;delay_ms(1);

 } }//while
} // void main
```
El problema es con el código en rojo. (Lo elimino y funciona correctamente y cuando lo adiciono no funciona el RS232.)


----------



## D@rkbytes (Ene 10, 2015)

A ese programa le hace falta establecer el canal del ADC: *setup_adc_ports(sAN0);

*Tiene otros detalles, pero empieza por agregar eso.


----------



## oztacen (Ene 11, 2015)

Si me di cuenta!. Que raro que lo haya quitado, mi programa inicial si lo tenía y no tuve problema con ello.
Lo restauré y haré un programa más corto, pero mi idea es enviar un dato al puerto serie.
Este pic lee el adc, lo convierte a la variable PWM y lo envia  por el puerto serie.



Por cierto, le puse el setup_adc (ADC_CLOCK_DIV_32); cambie por (ADC_CLOCK_DIV_64) , (ADC_CLOCK_INTERNAL) , por el tiempo de adquisición de ADC Tad=2Fosc >1.6ms y aparece un error en el PROTEUS, el cual indica que es erroneo el Tad.



Este código está más detallado.
Lo que pasa es que no funciona el serial con el ADC al mismo tiempo, pero si quito el programa del ADC funciona perfectamente el serial.


```
#include <16F88.h>  
#device ADC=8
#fuses HS,NOWDT,NOLVP,NOPROTECT //ordenes para el programado  
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,st  ream=port,bits=8)
 
//__________________________________________________  ______________________
// declaracion de variables
int flag_cambio=0,dig=0,cambio=0; // variables temporales 
char dato;                       //  de la comunicacion serial
int temp,RET;           // variables temporales del LDR
int CONT=0,PWM;                // variables temporales del PWM Y inturrp
int set_low,set_high;         // lum_low= indica el nivel mas bajo en  %
int lum_low=20,lum_high=80;  //  lum_low= indica el nivel mas alto en  %                     
int valor;                   //   luminosidad minima : 0<set low <8
                           //    luminosidad mmaxima : 1<set low <9 
                          //     OJO: lum_high>lum_low
//__________________________________________________  ______________________
//__________________________________________________  ______________________ 
// interrupcion para el PWM
#int_timer1
void interrupcion_timer1()
{ set_timer1(65435);
   if (CONT--==0)
   {CONT=100;output_low(PIN_b7);}
   if (CONT==PWM)
   {output_high(pin_b7);}   
}       
 
void  main()
{
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //prescalador x1
   enable_interrupts(INT_TIMER1); // activa interrupcion Timer1
   enable_interrupts(GLOBAL);   // habilita todas las interrupciones 
   setup_adc(ADC_CLOCK_INTERNAL); //configura el conversor
   setup_adc_ports(sAN0); //entrada 0 como analogica
   set_adc_channel(0);
   delay_us(30);
 
// Si el dispositivo viene de fabrica hay que setear los valores 
   lum_low=read_eeprom(50);// si la eeprom esta vacia
   lum_high=read_eeprom(51);// si la eeprom esta vacia
   if(lum_low==0xFF)      // guarde el valor minimo de luminosidad
     {lum_low=40;}      
   if(lum_high==0xFF)      // guarde el valor maximo de luminosidad
     {lum_high=90;}     
  PWM=50;   
   while(true)
   {
 //________________________________________
// Lector de LDR intensidad de luz
//_________________________________________
    set_adc_channel(0);
    delay_us(100);
    temp=read_adc(); // lee el LDR         
 
//__________________________________________________  _________
//  RECEPCION SERIAL Y SETEO DE LUMINOSIDAD
    if(kbhit(port)) // lee si hay algun dato buffer del puerto.
      {dato=getc(port); // LEE EL DATO DEL puerto
         switch(dato)
         {  case 'i':
               flag_cambio=1;cambio=0,dig=0;break; // FLAG CAMBIOS EN LUMINOSIDAD(+ O -)
            case 's':        
               flag_cambio=2;break; //para setear el rango minimo de luminosidad
 
            case '0':               // disminuir la luminosidad
               if(flag_cambio==1)
               { if(PWM<=lum_low)
                 {PWM=lum_low;}
                 else
                 {PWM=PWM-10;} 
                flag_cambio=0;                  
               } 
              if(flag_cambio==2)
               {  dig++;
                  if(dig==1)
                  {set_low=dato-48;cambio=0;}
                  if(dig==2)
                  { set_high=dato-48;                                       
                    dig=0;cambio=1;                    
                    flag_cambio=0;}
               }                  
              break;
            case '1': // aumenta luminosidad               
              if(flag_cambio==1)
               { if(PWM>=lum_high)
                  {PWM=lum_high;}
                  else
                  {PWM=PWM+10;}   
                 flag_cambio=0;               
               }
               if(flag_cambio==2)
               {  dig++;
                  if(dig==1)
                  {set_low=dato-48;cambio=0;}
                  if(dig==2)
                  { set_high=dato-48;                                       
                    dig=0;cambio=1;                    
                    flag_cambio=0;}
               }    
                break;
           case 'l':
               fprintf(port,"%i&",PWM);// ENVIA ESTADO DE luminosidad (%)
               flag_cambio=0,cambio=0,dig=0;break;
           default:
            // toma valores desde 2 hasta 9
           if(dato>=50 && dato<=57)
               if(flag_cambio==2)
               {  dig++;
                  if(dig==1)
                  {set_low=dato-48,cambio=0;}
                  if(dig==2)
                  { set_high=dato-48;                                       
                    dig=0;cambio=1;                    
                    flag_cambio=0;}
               }
               break;
         }// switch dato     
 
      } //kbport
 
//__________________________________________________  ______________________
 
    RET=(TEMP/10); //   RET=(Temp*100)/250
    RET=(RET*10)/25;
    RET*=10; // escalamiento de 0 a 100
 
if(RET!=valor) //ANALIZA EL LDR SI HUBO CAMBIO EN SU RESISTENCIA
         {             
         if(RET>=valor+9)
         {valor=temp; // RETIENE EL ULTIMO CAMBIO para ver si hubo variacion 
//__________________________________________________  ___
         if((RET>lum_low) && (RET<lum_high)) // verifica si esta en rango de valores
         {PWM=RET;}    // actualizar PWM            
         else
         {if(RET<=lum_low)   // setea el minimo
          {PWM=lum_low;}
         if(RET>=lum_high)   // setea el maximo
          {PWM=lum_high;}
         }}
          if(RET<=valor+9)
         {valor=temp; // RETIENE EL ULTIMO CAMBIO para ver si hubo variacion   
//__________________________________________________  ___
         if((RET>lum_low) && (RET<lum_high)) // verifica si esta en rango de valores
         {PWM=RET;}    // actualizar PWM            
         else
         {if(RET<=lum_low)   // setea el minimo
          {PWM=lum_low;}
         if(RET>=lum_high)   // setea el maximo
          {PWM=lum_high;}
         }}
         }
 
 
 
 
 
 
// setea los cambios de la instruccion solo si se han registrado 2 digitos s(xy)
// y solo si el set_high es mayor que el set_low
if(cambio==1)
{if(set_high>set_low)
{lum_low=set_low*10;
 lum_high=set_high*10;write_eeprom(50,lum_low);writ  e_eeprom(51,lum_high);}
// actualiza los datos para el PWM
         if(PWM<=lum_low)    // setea el minimo 
            {PWM=lum_low;}
         if(PWM>=lum_high)  // setea el maximo
            {PWM=lum_high;}
 cambio=0;delay_ms(1);
}
   }//while
} // void main
```


----------



## D@rkbytes (Ene 12, 2015)

oztacen dijo:


> Lo que pasa es que no funciona el serial con el ADC al mismo tiempo, pero si quito el programa del ADC, funciona perfectamente el serial.


Pues no veo que falle. Al enviar el comando '*l*' retorna el valor de la variable PWM.
El conversor sigue haciendo su tarea e igualmente la recepción y transmisión serial.

Puedes hacer unas cuantas mejoras:


Utilizar el módulo AUSART de ese PIC, pues lo estás haciendo por software.
Utilizar la interrupción RDA para la recepción de datos.
Utilizar el módulo CCP para la generación de PWM.


----------



## oztacen (Ene 29, 2015)

gracias, funciono. hice el uart1 del pic por hardware y funciona perfecto.


----------

