Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

15/06/2014 #1


Vref de ADC en PIC18F4550
Hola de nuevo !

Esta vez trabajo en un controlador de velocidad para un motor DC por medio de PWM, a su vez controlado por un potenciómetro conectado al PIC.
Tengo la idea de la respuesta que da el ADC, (un número del 0 al 1023 depende del voltaje en la entrada analógica) pero no entiendo como funciona el Vref o como se configura, etc.
¿Si conectó el potenciometro asi sin más, se usa un Vref interno de 5V automáticamente, o de cuanto es ese Vref interno? ¿Tengo que poner algún voltaje en Vref+ o Vref-? si es así, de cuanto?
Agradecería mucho esta explicación.

Trabajo con el 18F4550 en MickroC.

Saludos !
15/06/2014 #2

Avatar de Daniel Meza

El voltaje de referencia (Vref) depende de como haya sido configurado el registro ADCON1. Revisa este registro en la hoja de datos del PIC18F4550 para que te saques de dudas.
Saludos
15/06/2014 #3


Gracias por responder

Oooh, es decir que si configuro los voltajes de referencia como Vss y Vdd, el rango será de 0 a 5V, cierto? y ahí variaran los valores dependiendo del voltaje en la entrada analógica, 0=0V, 1023=5V.
Es eso correcto?
suponiendo que use la conversion a 10 bits
15/06/2014 #4

Avatar de Scooter

Así es. Eso se puede usar por ejemplo a la salida de un circuito que no llega a 5V ni a 0 para tener un rango mas amplio
26/01/2015 #5


Buenas tardes. Soy nuevo en este foro, así que esta es mi primera publicación, y si no es mucha molestia quisiera que me pudieran ayudar con un problema.

Lo que estoy haciendo es usar el adc del pic18f4550, ya que en la entrada del pic tengo un potenciómetro y a la salida un led, y lo que debo de hacer es que si giro el potenciómetro a la derecha, se prenda el led, y si lo giro a la izquierda, se apague.
No importa en que posición esté o cuanto lo gire.

Ya hice el código en ccs compiler, lo simulé en proteus y todo funcionaba bien, pero a la hora de probarlo en la protoboard no funciona.

Aquí les dejo el programa y de ante mano, muchas gracias.

Código:
#include <adc.h>
#use delay(clock=20000000)
#define     BITS     8
//#define     ADC_SAMPLEUS 50

void main() {

         int valor_default;
         int valor_1;
        
         setup_adc_ports(AN0_ANALOG);
         setup_adc(ADC_CLOCK_INTERNAL);                                                                                                                                                                                                                                                                                 
         set_tris_a(0xFF);
         set_tris_b(0x00);
        
         set_adc_channel(0);
         valor_default=read_adc();
        
         while(true){
                    valor_1=read_adc();
                   
                    if(valor_1>valor_default){
                                 
                                  output_high(pin_b0);
                                  valor_default=valor_1;
                                 
                    }
                   
                    if(valor_1<valor_default){
                       
                                  output_low(pin_b0);
                                  valor_default=valor_1;
                   }
         }
}
27/01/2015 #6
Moderador

Avatar de D@rkbytes

Si estás usando el ADC a 8 bits, la mitad sería 127 por fijar un valor medio sobre 255.
Entonces cuando se lea un valor superior a 127 puedes encender el LED y cuando sea menor, apagarlo.

Algo sencillo, sería así:
Código PHP:
#include <18f4550.h>
#fuses   NOWDT,NOFCMEN,CPUDIV1,PLL1,NOUSBDIV,NOVREGEN
#use     delay(internal = 4MHz)


#define  led   pin_b7

void main (void)
{

int8 valor_adc;

   
setup_adc_ports(AN0);
   
setup_adc(ADC_CLOCK_INTERNAL);
   
set_adc_channel(0);
   
delay_us(50);
   
   while (
true)
   {
      
valor_adc read_adc();
      
      if(
valor_adc 127)
         
output_high(led);
      else
         
output_low(led);
   }


Mira la palabra de configuración que es para usar el oscilador interno a 4MHz.
Y que no se estableció el ADC a 8 bits, porque si se omite #device adc = bits, el compilador asume 8 bits por defecto.

Tampoco es necesario que uses librerías extras ni nada fuera de lo normal para manejar el ADC.
27/01/2015 #7


Gracias por tu tiempo y por responder, el problema es que si se podria hacer asi pero la manera en la que me lo piden es que por ejemplo, si esta el potenciometro(de 20K) posicionado en 5k o en cualquier valor y lo giro a la derecha 1 ohm se debe prender y si se sigue moviendo 1 ohm o los que sean pero a la derecha se sigue prendiendo (no deja de estar prendido), pero si en cualquier momento ese potenciometro retrocede (a la izquierda) un ohm o los que sean pero a la izquierda el led se apaga y seguira apagado mientras el potenciometro gire a la izquierda. No debe ser por intervalos como me sugerias de mitad a mitad sino que con que cambien un poco el valor del potenciometro (mientras se gire a la derecha)se debe de prender y si retrocede (a la izquierda )un poco asi sean ohms o micro ohms se debe a pagar. Espero haberme dado a explicar bien y lo de #include <adc.h> no es una libreria , es que como use ccs compiler el programa lo guarde como adc y asi lo pone, solo es el nombre del programa.
El caso es que el problema no es como hacerlo ya que en proteus lo simule y funciono perfectamente, lo raro es que cuando lo quiero pasar al pic y lo pruebo en la proto no funciona.
27/01/2015 #8

Avatar de Daniel Meza

¿a qué te refieres con "no funciona"?. En mi opinión hay que modificar un poco el código para que si se hace la comparación y la diferencia entre ambas muestras es < ó > a cierto rango (por ejemplo 5) se proceda, entonces, a ejecutar el encendido o el apagado del LED, con esto se hace un poco más inmune al ADC del ruido que puede introducir el potenciómetro

Salu2
27/01/2015 #9


Pues lo que pasa es que al poner el pic y encenderlo lo unico que hace es que si el potenciometro (20 k)esta en su maxima resistencia el led se apaga pero si es menor a eso desde 19.9(por asi decirlo) hasta 0 el led sigue prendido pero si lo miras de cerca se ve que parpadea muy rapido.
y si estaba pensando ponerle cierto rango para que no haga la comparacion con todos los valores del potenciometro ya que serian demasiadas, nada mas que no se muy bien como ponerle rango. antes habia pensado solo que hiciera la comparacion con ciertos valores.
como:

if(valor_1>valor_defautl && valor_1==50||100||150||200||250){
output_high(pin_b0);
valor_defautl=valor_1;
}
27/01/2015 #10

Avatar de Daniel Meza

Otra cosa, recordemos que el resultado de la conversión es de 10 bits y tu lo quieres meter en un int8, por allí puede andar el problema
27/01/2015 #11


pero desde el principio le puse que fuera de 8 bits y los valores que le pido son de 0 a 255 por lo cual no deberia de haber problema o si?
27/01/2015 #12

Avatar de Daniel Meza

quizá no, haz la prueba definiendo el dato como un "word" a ver que pasa
27/01/2015 #13


Lo siento pero todavia no me familiarizo mucho con la programacion y no se como definir un dato como word
27/01/2015 #14

Avatar de Daniel Meza

prueba con "int16" en lugar de "int8"
27/01/2015 #15

Avatar de 0002

Podrías probar guardar el valor del ADC, en el momento que haces la medición, es decir:

Potenciómetro estático: el ADC, mide y guarda su valor (8 bits por ejemplo) en una variable.

Paso siguiente: mueves el potenciómetro a la derecha: el ADC, vuelve a medir y guarda su valor en otra variable que sirve para hacer una comparación, como será mayor que la variable guardada anteriormente, el LED permanecerá encendido. Ahora la primer variable guarda el valor actual del ADC.

Paso siguiente: mueves el potenciómetro a la izquierda: el ADC, vuelve a medir y guarda su valor en la segunda variable, se vuelve a hacer la comparación, como ahora, dicha variable es menor que la otra, el LED se apaga. También la primer variable guarda el valor actual del ADC.

Creo que eso fue lo que entendí, por favor alguien que me corrija si me equivoco.

Saludos.
27/01/2015 #16


Ya probé con int16 pero sigue haciendo lo mismo.

Código:
#include <adc.h>
#use delay(clock=20000000)
#define  BITS  8

void main() 
{
   
   int16 valor_default;
   int16 valor_1; 
   
   setup_adc_ports(AN0_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);                                                                                                             
   set_tris_a(0b00000001);
   set_tris_b(0x00);
   
   set_adc_channel(0);
   delay_ms(10);
   valor_default=read_adc();
   
 while(true)
  {
        valor_1=read_adc(); 
        
        if(valor_1>valor_default)
          {
             output_high(pin_b0);
           valor_default=valor_1;
          }
        
        if(valor_1<valor_default)
          {
              output_low(pin_b0);
           valor_default=valor_1;
          }
  }
}
Gracias 0002 por responder. Y sí, eso fue lo que yo estoy haciendo pero no sé si me falta algo para que eso lo haga mi programa, ya que no lo hace.
27/01/2015 #17

Avatar de papirrin

el codigo parece bien, y si lo hace bien en proteus y en la realidad no, es muy comun que no esten bien configurados los fuses...

podrias poner como esta el adc.h y poner el diagrama completo, asi hay un panorama mas completo del problema.
27/01/2015 #18


el adc.h no es una libreria solo es el nombre del programa con el que lo guarde y como configuro los fusibles??
27/01/2015 #19

Avatar de papirrin

el adc.h no es una libreria solo es el nombre del programa con el que lo guarde y como configuro los fusibles??
amigo aqui dice:

#include <adc.h>

esa es una libreria abrela y vela ahi estan los fuses. no olvides postear el diagrama.
27/01/2015 #20


cierto lo siento ya la abri y esto fue lo que me apareció:

#include <18F4550.h>

#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES PLL12 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV4 //System Clock by 4
#FUSES USBDIV //USB clock source comes from PLL divide by 2
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES NOPUT //No Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES VREGEN //USB voltage regulator enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES ICPRT //ICPRT enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPB //No Boot Block code protection
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads

#use delay(crystal=20000000, clock=5000000)

el diagrama no lo puedo poner porque no me permite, dice que excede el tamaño para subir la foto
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.