Conversor analógico digital

La conversión analógica digital, es la que nos permite transformar una señal analógica (un voltaje), en una representación digital (números binarios) del valor correspondiente a la tensión en el pin de entrada para poder trabajar con ella. Se utiliza en infinidad de aplicaciones, lo más común es usarla para leer señales provenientes de algún sensor (temperatura, humedad, acelerómetros, etc.).

El PIC que se ha utilizado en este tutorial, es el PIC 16f877A, pero si se utiliza cualquier otro, el funcionamiento es prácticamente el mismo.


En esta primera parte del tutorial, se hace una pequeña introducción con el datasheet del PIC 16f877A, para darnos a conocer un poco su funcionamiento y de este modo también tener en cuenta que parámetros debemos fijarnos a la hora de configurar el conversor con cualquier otro PIC. También se habla un poco de las funciones a utilizar en el código y lo que realiza cada una.

En el segundo vídeo, se expone un código de ejemplo, en el cual se lee una tensión de en la entrada analógica AN0 que está conectada a un potenciómetro (la cual podría ser la señal analógica proveniente de cualquier sensor u otro dispositivo), y dependiendo de cuál sea su nivel de tensión, se enciende un determinado número de leds que es equivalente a la tensión leída. También se explica una configuración previa, de la cual nos provee el propio compilador al usar el Wizard aunque no es necesario puesto que lo podemos hacer directamente nosotros mismos si conecemos las funciones necesarias para llevar a cabo la configuración

Como venimos haciendo en los últimos tutoriales, el último vídeo o en la parte final del vídeo, les mostramos el ejemplo realizado en el código funcionando en una protoboard. Así ustedes pueden hacer la prueba también que siempre es recomendable para afianzar los conocimientos.

Si tienen alguna duda no duden en comentarla en el foro del blog.

Descarga: Código y Esquemático

71 Comentarios

  1. HECTOR GONZALEZ

    OYE COMPAÑERO YO TRATE DE MONTAR EL MAIN TUYO Y EL CIRCUITO EN PROTEUS Y NO FUNCIONA NO SE QUE TENGO MAL PERO SIEMPRE SALTA AL CASE 6 SI ME PODRIAS COLABORAR ENVIANDOME EL LENGUAJE ES QUE LO NESECITO URGENTISIMO PARA MI PROYECTO O SI TIENES COMO UNIR UN LCD Y UN ADC TE LO AGRADECERIA COMPAÑERO ESPERO TU RESPUES Y DE ANTEMANO GRACIAS

  2. Twistx77

    Buenas,

    Postea tu código en el foro para ver si te podemos ayudar puesto a que sin ver el código es muy dificil.

    En cualquier caso voy a subir el programa que mi compañero no lo ha hecho.

    Saludos!

  3. Dantechs

    muy interezantes todos los video tutoriales me parecen que estan muy bien estructurados y van a lo que todos nos intereza “al grano”
    ¡¡felicitaciones!

  4. Twistx77

    Muchas gracias!

    Me alegro que te gusten.

    Saludos!

  5. ulysseszxy

    Eh estado viendo los tutoriales y verdad son muy interesantes,…
    y me estan ayudando mucho para relizar mis proyectos
    talvez podrias hacer un tutorial de como realizar el control
    de ADC a un PWM. en este caso un potenciometro como ADC, y controlar un servomotor.bueno gracias y FELICITACIONES…!

  6. Josean

    Felicidades Twistx77,

    respecto al ADC, me gustaría saber si sería posible centrar la conversión en un rango determinado. Por ejemplo, si quiero medir la tensión de una batería que oscila muy poco, siempre va a estar entre 20 y 24 voltios, ¿como hago para que el 0 sea 20 voltios y el 24 el 1024?

    Gracias

  7. Twistx77

    Buenas,

    gracias por el comentario. Por ahora ya he mostrado como usar el ADC, el próximo vídeo hablaré del PWM y más adelante pondré todo junto en una sola aplicación.

    Saludos!

  8. Twistx77

    Muchas gracias,

    lo más fácil que se me ocurre es hacer un divisor resistivo de modo que para cuando tengas 24V en la resistencia del divisor tengas 5V máximo. De esa manera tendrás que 24V son 1024 o casi. Luego aunque 20V no sean 0 en el divisor lo que puedes hacer es usar una tensión de referencia para la Vref- como puede ser por ejemplo 2V lo que haría que tengas la lectura entre 5V y 2V para lo cual tendrías una resolución de unos 3 mV para extrapolarlo luego a la tensión de la batería. No se si me explicado bien. Te recomiendo que si lo haces pongas un zener de 5.1V en inversa en la entrada del conversor para evitar que se queme el conversor si la batería sobre pasa los 24V, otra solución podría ser bajar a 4V los 24V en el divisor resistivo. Ten en cuenta que no debes usar resistencias de valor pequeño puesto que eso hará que circule mucha corriente de la batería por tu divisor.

    Cualquier duda por favor exponla en el foro que nos permite subir imágenes para explicar mejor. Saludos!

  9. Josean

    Gracias Twistx77,

    al final he cambiado la batería de 24 a 12v, y he añadido un divisor de tensión para, como dices, hacer que al conversor le lleguen 5v cuando hay unos 14v y 0v cuando hay 0v. En el cálculo que he hecho me sale una de 12k con otra de 6k8. Como estoy usando la arduino UNO, no sé si poniendo una tensión de 7v en la Vref me haría que 7v fuera el 0 lógico y el 14 los 1023. Para obtener los 7v en el Vref supongo que tendría que hacer otro divisor de tensión para obtener en vez de 5v 7v (con dos de 12k), ¿no? Supongo que usando resistencias de este valor no hará falta meter un diodo, ¿no?

    Gracias.

  10. Twistx77

    Hola amigo,

    Siento decirte que no podrás conectar los 7V al VRef del ADC puesto a que según el datasheet del ATMega328 (El micro de Arduino) la tensión máxima en VRef es la que tengas en AVcc y esta como máximo puede valer Vcc+0.3V por lo que si está alimentado a 5V la máxima tensión que podrás poner es de 5.3V . Lo puedes comprobar en el datasheet en la página 328, aquí te dejo un link http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf .

    Saludos!

  11. Josean

    Gracias por el apunte,

    en mi caso alimento el arduino UNO con la propia batería (12v), a través de un circuito regulador de tensión LM317 (lo tendría que ajustar a 6.7<V<7.3) conectado al "jack" del arduino. De todos modos luego me he dado cuenta que necesito sensar una tensión más, en este caso de 5V, por lo que entiendo que en el caso de la arduino la referencia es común para todas las entradas analógicas, ¿no? , por lo que mi gozo en un pozo.

    Gracias Twistx77

  12. Enrique88

    Hola,
    Estoy realizando un proyecto en el que si que necesito que el ADC vaya lo más rápido posible. Lo hago con el PIC 18F4550. Tengo unas dudas que a ver si me puedes ayudar a resolver. Como bien dices, para conseguir la máxima rapidez hay que bajar la frecuencia de trabajo, poniendo un cristal menos rápido. El problema que tengo es que necesito un cristal trabajando rápido debido a que hago el envío por USB 2.0. Me gustaría saber que posibles soluciones tengo, como se podrían configurar los fuses, alguna manera de solucionarlo, ya que he visto por datasheet que puede ser que el cristal tenga una configuración para el USB y a su vez otro para el resto.

    Gracias y espero haberme explicado.

    Saludos,

    Enrique

  13. Twistx77

    Buenas,

    no se si te has confundido al escribirlo pero para conseguir la máxima rapidez tienes que subir la frecuencia de trabajo no bajarla, poniendo un cristal más rápido. Ahora la velocidad del ADC vendrá determinado por el reloj que elijas en la configuración pero tienes que tener en cuenta que tienes que configurarlo para que el tiempo de adquisición de cada bit sea el suficiente. Si mal no recuerdo para la mayoría de los PIC de la serie 16 era 1.6uS. Además tienes que tener en cuenta que tiene que pasar un tiempo mínimo entre conversiones que también lo tendrás especificado en el datasheet. Por lo tanto no esperes frecuencias de muestreo de 500k/s sino inferiores.

    Por lo tanto pon un cristal que te sirva para el USB puesto a que seguro que es más que suficiente para conseguir la máxima velocidad del ADC.

    Saludos!

  14. vicente

    podrias poner mas tutoriales sobre codigos en pic c y simularlo en proteus!!!
    saludos!!

  15. Twistx77

    He puesto tutoriales en C de PIC, cuando tenga tiempo subiré el próximo.

    No los simulo en Proteus, los monto en una protoboard y de muestro como funcionan.

    Saludos!

  16. Lennon

    Buenas tardes, Twistx77.

    En primera instancia quiero felicitarte por el trabajo realizado, me parece que estas aportando mucho al conocimiento con este blog. Escribo porque me encuentro desarrollando un proyecto donde necesito medir corriente y visualizarla en un LCD. Como solución plantie realizar una medida indirecta de la coriente mediente el voltaje y la resistencia (Ley de ohm), pero tuve un problema ya que los rangos de corriente a medir estaban en micro amperios y por tanto el voltaje en la entrada del A/D era muy pequeño, para solucionarlo utilize un amplificador de instrumentación y estableci una relación. Bueno en fin tengo el pseudo código para la solución del problema.. en especial queria ver si me podrias ayudar con la visualización en el LCD de los valores obtenidos.

  17. Twistx77

    Buenas,

    gracias por tu comentario.

    Necesito saber cual es el problema que tienes para poder ayudarte :)

    Exactamente que te pasa?

    que micro y que lenguaje estás usando.

    que LCD?

    Saludos!

  18. Lennon

    Hola Twistx77,

    Estoy usando el PIC 16F877A, inicialmente estaba desarrollando el proyecto en Assemble pero me parecio muy tedioso y el proyecto como tal no requiere un estricto control de maquina. Por eso busque alternativas y vi que programas en C con CCS es bastante sencillo. Necesito un ejemplo donde se haga uso del conversor AD y se muestre en un LCD algun valor relacionado con la lectura del A/D. Solo quiero tomarlo como ejemplo para sentarme a desarrollar mi proyecto.

    Saludos, Gracias

  19. jonathan

    hola. me gustan mucho estos videos son muy claros en su mayoria.
    mira lo q pasa es q pues no entiendo muy bn la tabla de frecuancia de operacion y tda y pues no se diigamos como obtener este 1,6 us, tengo q hacer un conversor el cual debe ser lo mas rapido posible y lo quiero hacer con un 16, cual es el minimo tiempo q puedo obtener ?

  20. Eduardo

    Quiciera saber si me puedes orientar, como hago para manejar el convertidor analogo digital del pic 16f873 conectado a 5 cny

  21. Twistx77

    Buenas,

    no entiendo cual es tu problema. Solo necesitas saber la frecuencia a la que está trabajando tu micro para calcular el tiempo. De todas maneras, si vas al datasheet y buscas Selecting the A/D Conversion Clock, tendrás en ese apartado, una tabla en la que dice la configuración correspondiente dependiendo del oscilador que estés usando.

    Con un 16 te refieres a un pic de la serie 16 no? Si es así creo que todos los de la serie 16 tienen un tiempo mínimo por bit de 1,6uS. Quizás haya alguno especial pero en general la serie 16 usa conversores de esa velocidad.

    Saludos!

  22. Andrea

    ¡Muchas gracias por tu aporte!

  23. foraneo77

    amigo he estado usando el arduino he investigado un poco ,he visto tus tutoriales dicho de paso son muy buenos ; hay algo que no me queda claro aun es respecto a la comunicacion serial,quisiera por favor que expliques este tema tanto en arduino como en pic ( veo que se usa bastante en varias funciones del arduino )

  24. neo3shion

    buen dia

    he montado las lineas tal cual las pones en el video:
    #include “I:\U\Electronica 3\proyecto\programa adc.h”

    #byte PORTB = 0x06
    void main()
    {
    ////Config///
    setup_adc_ports(AN0);
    setup_adc(ADC_CLOCK_INTERNAL);
    //setup_pp(PMP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);

    unsigned int16 tension=0;

    set_tris_b(0x00);

    set_adc_channel (0);
    delay_us(10);

    while(1){

    tension=read_adc();
    delay_ms(1);
    valor=tension/127;

    switch(valor){
    case 0: PORTB=0b00000000;
    break;
    case 1: PORTB=0b00000001;
    break;
    case 2: PORTB=0b00000011;
    break;
    case 3: PORTB=0b00000111;
    break;
    case 4: PORTB=0b00001111;
    break;
    case 5: PORTB=0b00011111;
    break;
    case 6: PORTB=0b00111111;
    break;
    case 7: PORTB=0b01111111;
    break;
    case 8: PORTB=0b11111111;
    break;

    default: break;
    }

    }
    // TODO: USER CODE!!

    }
    ————————————————————————————————————–
    y al momento de compilar el archivo se producen 14 errores:

    ***Error51″programa adc.c”Line 16(1,9): A numeric expression must appear here
    ***Error12″programa adc.c”Line 25(4,11): Undefined identifier tension
    ***Error12″programa adc.c”Line 27(4,9): Undefined identifier valor
    ***Error12″programa adc.c”Line 29(11,16): Undefined identifier valor
    ***Error51″programa adc.c”Line 30(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 32(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 34(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 36(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 38(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 40(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 42(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 44(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 46(7,11): A numeric expression must appear here
    ***Error51″programa adc.c”Line 49(7,14): A numeric expression must appear here
    —————————————————————————————————————-
    espero me puedas ayudar pronto, en verdad lo necesito.
    mil gracias

  25. Luicho666

    El primer error puede ser que no hayas definido la variable “valor”.
    Saludos.

  26. Twistx77

    Buenas, has comprobado que el .h ¿está bien? Me puedes decir cual ahí es la linea 16?

  27. starter

    Hola neo3shion, a mí me pasa exactamente lo mismo. A que se debe?
    saludos,

  28. Twistx77

    No hay de que. Saludos!

  29. Twistx77

    He hecho vídeos sobre ambos. Que es lo que no entiendes exactamente?

  30. Twistx77

    Prueba a poner debajo de esta línea: unsigned int16 tension=0;

    unsigned int8 valor = 0;

    Saludos!

  31. starter

    Hola,
    me da igual 15 errores,
    y lo raro es que he descargado el código escrito por ti y lo he compilado y me da también 15 errores.
    Que estaré haciendo mal.?
    saludos

  32. starter

    unsigned int16 tension=0; //Variable para almacenar el valor de tensión leido por el ADC
    unsigned int8 valor=0; //Variable temporal.

    set_tris_b(0x00); //0b0000000// Configuramos el puerto B como salida.

    set_adc_channel(0); //elegimos el canal que vamos a leer.
    delay_us(10); // esperamos 10uS necesarios para el ADC

    while(1){

    tension=read_adc(); //Leemos la tensión en el canal que elegimos.
    delay_ms(1); //Esperamos un poco.
    valor=tension/127; //Calculamos a cuantos LEDs encendidos corresponde la tensión leida.

    switch(valor){ //Encendemos los leds que hagan falta.
    case 0: PORTB=0b00000000;
    break;
    case 1: PORTB=0b00000001;
    break;
    case 2: PORTB=0b00000011;
    break;
    case 3: PORTB=0b00000111;
    break;
    case 4: PORTB=0b00001111;
    break;
    case 5: PORTB=0b00011111;
    break;
    case 6: PORTB=0b00111111;
    break;
    case 7: PORTB=0b01111111;
    break;
    case 8: PORTB=0b11111111;
    break;

    default: break;
    }

    }

    }

    **ERROR 51 “adc.c” Line 18(4,12): A numeric expression must appear here
    **ERROR 51 “adc.c” Line 19(4,12): A numeric expression must appear here
    **ERROR 12 “adc.c” Line 29(7,14): Undefined identifier tension
    **ERROR 12 “adc.c” Line 31(7,12): Undefined identifier valor
    **ERROR 12 “adc.c” Line 23(14,19): Undefined identifier valor
    **Error 51 “adc.c” line 34(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 36(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 38(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 40(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 42(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 44(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 46(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 48(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 50(10,14): A numeric expression must appear here
    **Error 51 “adc.c” line 53(10,17): A numeric expression must appear here

    15 Errors, O Warning

  33. CoolDann

    Se ve interesante la informacion, lo malo de esos videos, el sonido esta horrible, y si a eso le agregamos la manera de que hablas el video sale echado a perder todo. como sea te agradezco tu colaboracion

  34. AVEAE

    Hola me aparecen los mismos errores al compilarlo como lo dicen los comentarios, se puede tratar del compilador? ya que el código está bien, yo lo realicé para el pic 16f873a con un criztal de 4mhz

  35. AVEAE

    Hola a todos de nuevo ya reparé el error que han mencionado anteriormente, lo que deben hacer es declarar las dos variables: unsigned int16 = tension =0; y unsigned int8 = valor; al principio del programa despues del void main() {
    no se si digo lo correcto pero de esta forma se toman como un tipo de variables globales. En ciertos compiladores ocurre lo mismo, tuve un problema parecido con un programa que realicé en java. Bueno eso es todo a mi me funcionó intentenlo¡¡¡

  36. AVEAE

    nota:
    unsigned int16 tension =0;
    unsigned int8 valor;
    no llevan el igual como lo puse arriba (unsigned int16 = tension =0; y unsigned int8 = valor;)
    por si las dudas

  37. Bravo

    Felicitaciones !!! muy interesante los tutoriales de tu web…. sobre todo para los que nos iniciamos o los que tenemos nociones de programacion, excelente sitio y gracias por compartir tus conocimientos a todos los interesados.

    hasta pronto..

  38. Roberto (Publicaciones Autor)

    Gracias,

    Me alegro de que te guste.

    Un saludo.

  39. Bravo

    Saludos
    me custaria saber como hago para tomar valores con punto decimales en los case : del switch, puesto que en ves del potenciometro uso resistencias y 100 hom en serie.

    Ejemplo:

    case 0.20:
    portb=0b00000001;
    break;

    case 0.50:
    portb=0b00000010;
    break;

    En este caso toma los valores de case: como repetidos.

  40. israel

    hola estoy empezando a programar en pic c tengo un sensor ultrasonico de distancia Lv-maxsonar-ez1 quiero medir distancia en cm en su modo analogico el sensor tiene un rango de medida de 0 a 254 pulgadas este sensor varia 9.8mv por pulgada
    no se si me puedar una idea para la programacion y la conversion en pic c

  41. Twistx77

    Sabes usar el ADC de PIC?

  42. israel

    mas o menos a tu pregunta, con el apoyo de los video tutiales y ejemplos de la red con el pic que voy a utilzar,pude realizar un programa que lee la tension de 5 voltios solo me falta integrar el sensor Lv-maxsonar-ez1 pero tengo dudas para de la conversion alquien que me explique y me despeje dudas. el programa lo simule en proteus y funciona…

    gracias…!

    #include
    #device adc=10

    #FUSES HS,NOWDT,NOPROTECT, PUT

    #use delay(clock=8000000)
    #include
    #use fast_io(d) //Directiva Entrada/Salida del Puerto D

    void main()
    {
    int16 q;
    float p;

    setup_adc_ports(AN0); //Canal 0 analógico
    setup_adc(ADC_CLOCK_INTERNAL); //Fuente de reloj RC interno
    delay_ms(100);
    lcd_init();

    for (;;)
    {
    set_adc_channel(0); //Habilitación canal0
    delay_us(20);
    q = read_adc(); //Lectura canal0
    p = q*5.0/1024 ; //Conversión a tensión

    printf(lcd_putc, “\fADC = %4ld”, q);
    printf(lcd_putc, “\nVoltage = %01.2fV”, p);

    delay_ms(1000);
    }
    }

  43. carblack

    Muchas gracias por compartir tus experiencias —Twistx77– y tambien quisiera dar mi aporte dando solucion a los problemas que se presentaron con unos errores de compilacion .
    esta este es el programa fuente que funciona probado tanto en proteus como en protoboard:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////leds con control analogico (potenciometro////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////
    #include
    #device adc=10

    #FUSES NOWDT //No Watch Dog Timer
    #FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
    #FUSES PUT //Power Up Timer
    #FUSES NOPROTECT //Code not protected from reading
    #FUSES NODEBUG //No Debug mode for ICD
    #FUSES NOBROWNOUT //No brownout reset
    #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
    #FUSES NOCPD //No EE protection
    #FUSES NOWRT //Program memory not write protected

    #use delay(clock=8000000)

    /////////////////////////////////////////////////////
    //#include

    #byte PORTB = 0x06 //Definimos PORTB con la dirección del registro PORTB.

    void main()
    {

    int tension=0;

    int valor;

    ////Configuración///
    setup_adc_ports(AN0_AN1_AN3);
    setup_adc(ADC_CLOCK_INTERNAL);
    //setup_pp(PMP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);

    // unsigned int16 tension=0;
    //Variable para almacenar el valor de tensión leido por el ADC
    //unsigned int8 valor; //Variable temporal.

    set_tris_b(0x00); //0b0000000// Configuramos el puerto B como salida.

    set_adc_channel(0); //elegimos el canal que vamos a leer.
    delay_us(10); // esperamos 10uS necesarios para el ADC

    while(1){

    tension=read_adc(); //Leemos la tensión en el canal que elegimos.
    delay_ms(1); //Esperamos un poco.
    //valor=tension/127;
    //Calculamos a cuantos LEDs encendidos corresponde la tensión leida.

    valor=tension/25; // puedes variar para ver el cambio de respuesta
    //Calculamos a cuantos LEDs encendidos corresponde la tensión leida.

    switch(valor){ //Encendemos los leds que hagan falta.
    case 0: PORTB=0b00000000;
    break;
    case 1: PORTB=0b00000001;
    break;
    case 2: PORTB=0b00000011;
    break;
    case 3: PORTB=0b00000111;
    break;
    case 4: PORTB=0b00001111;
    break;
    case 5: PORTB=0b00011111;
    break;
    case 6: PORTB=0b00111111;
    break;
    case 7: PORTB=0b01111111;
    break;
    case 8: PORTB=0b11111111;
    break;

    default: break;
    }

    }

    }

    Atte
    Carblack

  44. jorge luis

    ola antes que nada kiero fecilitar los buenos videos tutoriales que dan a conocer estan bastante buenos, tengo poco tiempo de estar metido en esto de programacion de microcontroladores y aora tengo una duda, estuve buscando en la web algo q me aiudara pero no pude solucionar aun
    el programa que kiero hacer funcionar es el siguiente:
    al encender debo mostrar una frase en el lcd ” pulse tecla 0 o 1″, el cual con alguno de estos valores debo seleccionar el canal 0 o canal 1 para hacer la conversion AD y mostrar el valor del voltaje en el lcd del canal selecccionado y si no es ninguna de estas teclas que me muestre “tecla incorrecta” por 1segundo y luego que me muestre otra vez la frase “pulse tecla 0 o 1″.
    mi problema es q al parecer no iega la señal del teclado y por ello no ejecuta ninguna de las conversiones. noce donde esta el error x fa aver si pueden aiudar

    aqui muestro el codigo que realice aver si aiudan a encontrar el error xfavor

    #include “16f877a.h”
    #device ADC=10
    #fuses NOWDT,HS,NOLVP
    #use delay(clock=10M)

    #include “lcd.c”
    #include “kbd.c”

    void main()
    {
    char c;
    int16 q,m;
    int8 x;
    float p,n;

    lcd_init();
    port_b_pullups(TRUE);
    kbd_init();
    set_tris_a(0xFF);
    set_tris_b(0xFF);
    setup_adc(ADC_CLOCK_DIV_32);//32/10M=3.2us
    setup_adc_ports(AN0_AN1_AN3);
    printf(lcd_putc,”\fpulse tecla 0-1″);

    BUCLE:
    do
    {
    c=kbd_getc();
    }while(c==0||c==1);
    x=c-48; //lo convierto de ASCII a decimal
    if(x==0)
    {
    delay_ms(100);
    set_adc_channel(0); //selecciono canal 0
    delay_us(20);
    q=read_adc();
    p=q*(5.0/1023.0);
    printf(lcd_putc,”\fCANAL0=%f v”,p);
    }
    if(x==1)
    {
    delay_ms(100);
    set_adc_channel(1); //selecciono canal 1
    delay_us(20);
    m=read_adc();
    n=m*(5.0/1023.0);
    printf(lcd_putc,”\nCANAL1=%f v”,n);
    }
    else
    {
    printf(lcd_putc,”\ftecla incorrecta”);
    delay_ms(1000);
    printf(lcd_putc,”\fpulse tecla 0-1″);
    }
    goto BUCLE;
    }

  45. keydarkman

    He visto que el Mikroc es mucho mas facil que el css y ademas mas intuitivo en unas cuantas lineas de codigo se obtiene el valor digital de la conversion analogica deberian de probarlo yo un tiempo tambien comense con el css pero no me gusto ya que para cada cosa tiene una funcion y uno tiene que memorizarse muchas funciones en este IDE para hacer algo muy simple como convertir un valor analogico en digital.

  46. leonardo

    #include
    #device adc = 10
    #use delay (clock=4m)
    #byte puerto_a = 0x05
    unsigned int16 tension = 0;
    unsigned int valor;

    void main(){

    setup_adc_ports(AN0_analog);
    setup_adc(adc_clock_internal);

    set_tris_a(0x00);

    set_adc_channel(0);
    delay_us(10);

    while(1){

    tension=read_adc();
    delay_ms(1);
    valor=tension/255;

    switch(valor){

    case 0: puerto_a= 0b00000000;
    break;

    case 1: puerto_a= 0b00000001;
    break;

    case 2: puerto_a= 0b00000011;
    break;

    case 3: puerto_a= 0b00000111;
    break;
    default: break;

    }

    }

    }

  47. leonardo

    perdon tengo algunas dudas ya que cambie el codigo.
    1) porque no me deja poner las variables en el main..
    2)como declaro el tris en este pic12f683
    3)que puerto pongo en este pic y como encuentro la direccion..
    4) funciona en el proteus si lo quiero depurar ahi..
    gracias por todo y sigue con tus videos saludos

  48. leonardo

    si copias y pega no funciona, tiene que realizar tu el codigo, saludos

  49. leonardo

    ya me di cuenta lo de las variables hay que declararlas entes de los setup, lo del puerto todabia no lo entiendo como lo declaro y el tris menos

  50. leonardo

    hola funciona en el proteus ????? ya que ahi no me anda voy a probar en la realidad , saludos

  51. ALFONSO

    hola, muy chevere tus videos, sabes deberias hacer uno con un modulo LCD. y explicar el codigo seria de gran utilidad. gracias y muchos exitos.

  52. yeison

    muy bueno pero como utilizo los voltajes de referencia
    -vref y +verf tengo una señal que oscila entre 4.5 y 5 voltios como le hago agradezco cualquier ayuda de antemano que dios los bendiga

  53. Gonzalo

    hola soy de peru ta bien xevere los tutos, quisiera que me ayudaras a adecuar la señal del sensor lm35 para leer todo su rango con el pic 16f877, agradesco tu pronta respuesta

  54. Twistx77

    Buenas,

    no necesitas hacer nada, la señal del LM35 es lo suficientemente “alta” para leer todo el rango con el ADC del pic directamente.

    Saludos!

  55. Daniela

    Hola, de cuanto son las resistencias que pones en el circuito?
    Muchas gracias por el tutorial!!!

  56. Twistx77

    El Potenciometro de 10K la resistencia en MCLR también. Las de los leds. Dependerá de los leds que uses pero 330ohms estará bien casi seguro.

  57. daniel hernandez

    Hola buenas nachos buenisimo la aplicación y explicación de este tutorial, pero trate de simularlo con proteus ya que no tengo los componentes pero que va no e podido simularlo. si puedes ayudarme con eso seria buenisimo gracias amigo.

  58. erick santiago

    perdona es el pic16f690

  59. erick santiago

    hola quierod decirte que me gusto mucho tu tutorial y me ha servido de ejemplo, sin embargo avia comentado ya parece q se borro, bueno dejo mi cuestión.
    Quiero saber si podrias darme la mano para habilitar 11 o 12 adc con el pic16f690
    segui tu ejemplo pero no paso de 8, de antemano gracias

  60. david

    hola, bueno no se si sea el lugar correcto para preguntarte, pero dice que es para los que apenas se adientran a los micros, asi que preguntare.
    Bueno estoy empezando con el 18f4550 de microchip, y quisiera poder poner un panel solar en mi casa, y poder monitorear la carga de la bateria de ciclo profundo para que no llegue a descargarse completamente, y tambien monitorear el panel solar para verificar la carga que nos esta ofreciendo, con uno de tus tutoriales aprendi a manejar los puertos adc del pic, bueno el panel me ofrece en condiciones optimas 140Wp, 8.4A y 18Vcd, es capas el pic de medir 18Vcd?, se descompondra si recibe 8.4A, que me recomiendas para poder monitorear esto??,, Bueno muchas gracias por tu tiempo

  61. emerson

    HOLA DAVID—- CON RESPECTO A TU PREGUNTA DE K DICES DE DESCOMPONERSE NO AL ADC DEL PIC NORMALMENTE SE LE PUEDE APLICAR 110 V OJO Y NO PASA NADA SABES POR K¿? ES K FIJATE EN CADA ADC YA SEA (AN0, AN1….), HAY DOS DIODOS ESOS SIRVEN COMO LIMITADORES¡¡¡¡¡ POR LO TAMTO TE LO LIMTARA EN EL VSS Y VDD O EN VOLTAJE K ESTAS ALIMENTANDO AL PIC ….. PERO CUANDO HABLAS SOBRE LA CORRIENTE E SO SI CUIDATE MUCHO… POR K ES PERMITIDO CREO EN PIC SOLO 25mA CREO PERO USAS ALGUNOS DIVISORES Y ASI TRABAJAS… BUENO ESTE APAORTE K TE DOY ESTA EN FOROS DE ELECTRONICA

  62. Richard

    Saludos a todos esta bueno el tutorial, por favor podrian poner el diagrama detallado en pdf y como seria la conexion del conector RS232 conectado a la pc. Seria de mucha ayuda gracias a todos.
    Podrian mandarmelo algun diseño para hacerlo y probarlo mi email es : raguilar111@hotmail.com

  63. polux

    hola como estas dime amigo como puedo convertir esa salida paralela a una salida en serie cual seria el diagrama de conexion

  64. JOSS44

    hola esta muy bueno este tuto les felicito y espero que sigan adelante en sus planes de orientar en este mundo dela electrónica yo estoy dando mis primeros pasos en este mundo de los pic pero ustedes ayudan a que sea mas facir esto
    muchas gracias por su aporte y le seguiré todo lo que pueda mi interes es con en el pwm y adc

  65. JOSS44

    ademas puse en practica su codigo con los leds y me funciona de maravilla por aora solo lo simulo en proteus pero estoy preparando mi programador y manos ala obra para aserlo en realidad

  66. Ruben

    Hola he intentado hacerlo con un 16F876 y me enciende permanentemente los led 0 1 2 y 7.
    simulado en proteus, y no localizo el error. ¿alguien me puede ayudar?
    gracias adelantadas

    #include
    #device adc=10
    #FUSES NOWDT //No Watch Dog Timer
    #FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
    #FUSES NOPUT //No Power Up Timer
    #FUSES NOPROTECT //Code not protected from reading
    #FUSES NOBROWNOUT //No brownout reset
    #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
    #FUSES NOCPD //No EE protection
    #FUSES NOWRT //Program memory not write protected
    #FUSES NODEBUG //No Debug mode for ICD
    #FUSES RESERVED //Used to set the reserved FUSE bits
    #USE FAST_IO(B)

    #use delay(clock=4000000)
    #byte portb=0x06
    #byte trisb=0x86

    void main()
    {

    setup_adc_ports(AN0);

    setup_adc(ADC_CLOCK_INTERNAL);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);

    set_tris_b(0);

    set_adc_channel(0);
    delay_us(10);

    unsigned int16 tension=0;
    unsigned int8 valor;

    while(1);
    {
    tension=read_adc();
    delay_ms(1);
    valor=(tension/127);

    switch(valor)
    {

    case 0: portb=0b00000000;
    break;

    case 1: portb=0b00000001;
    break;

    case 2: portb=0b00000011;
    break;

    case 3: portb=0b00000111;
    break;

    case 4: portb=0b00001111;
    break;

    case 5: portb=0b00011111;
    break;

    case 6: portb=0b00111111;
    break;

    case 7: portb=0b01111111;
    break;

    case 8: portb=0b11111111;
    break;

    default: break;
    }

    }
    }

  67. Ruben

    ya encontré el error, el ; del while. Pero no entiendo por que con él se me encienden los terminales que os comentaba.

  68. jjponce

    amigo buen tutorial del conversor pero me podrias ayudar a como programar y conectar el voltaje de refrencia para q no sea 5 volts sino 12 he hecho algunos intentos pero no funciona con mas de 5 volts

  69. Hardpic

    Hola twist, el programa me funciona muy bien en proteus, pero fisicamente no funciona no prende ni un led, que puede estar mal….tal vez esta mal grabado, como debe estar el MCLR al momento de grabar? o que puede ser …gracias por tu respuesta..

  70. sbedoya

    Saludos, Deseo realizar la lectura del voltaje de un panel solar, por medio de un micro controlador, posee las siguientes caracteristicas: 60W-18V-3.33A, como puedo tomar esta lectura del panel?… Mi duda es la corriente de este quemaria los pines de I/O del PIC o solo bastaria con realizar un divisor?… Gracias

  71. lucas

    hola alguien tendria un ejemplo de conversion analogo – digital pero con la captacion de audio en ves de un potenciometro? Que a la salida de X puerto que solo use 3 de sus salidas muestre en forma de distintas secuencias RGB. Espero que alguien me pueda ayudar… Gracias…

Dejar un comentario