Voltimetro 3 led rgb

Hola, les hago una consulta, estoy haciendo unas prácticas para un voltímetro simple de 3 led, que cuando llegue a los valores encienda un led, llegue a otro valor lo apague y encienda otro, estoy trabado en la parte del apagado, como conviene hacerlo con if o con case?

Lo hice así y funcionó , debe haber una manera mejor,
while (true){

int16 analogico;
set_adc_channel (0);
delay_ms(10);
analogico= read_adc();



if (analogico > 100){
output_high(pin_verde);

}else {

output_low(pin_verde);
}

if (analogico > 350){
output_low(pin_verde);
output_high(pin_azul);
}
else {
output_low(pin_azul);
}
if (analogico > 700){
output_low(pin_verde);
output_low(pin_azul);
output_high(pin_rojo);
}
else {
output_low(pin_rojo);
}


}



}
 

Adjuntos

  • practica voltimetro 3 led.rar
    66.5 KB · Visitas: 11
Te conviene con ifs, ¿vos buscás que se enciendan todos los leds hasta determinado valor (tipo vúmetro) o solo el led de esa escala?

C:
int16 analogico;
set_adc_channel (0);
delay_ms(10);

Esto antes del While.

C:
analogico= read_adc();

Esto si dentro del while, la función read_adc ¿es bloqueante? (es decir, espera hasta que termine la conversión).
 
Quiero que de de 0 a 2 Volt encienda el verde, de 2 a 3,5 el amarillo y de 3,5 a 5 el rojo, pero que encienda uno a_la vez y se apaguen fuera del valor, quiero conectar 3 led de cada color o un rgb , hay que conectarlos con un transistor me imagino para no sobre cargar el pin del pic.
 
... hay que conectarlos con un transistor me imagino para no sobre cargar el pin del pic

Dependiendo de los leds y la corriente del pin que pueda suministrar el Pic, es probable.

Ok, si es de un solo led, te recomiendo empezar de mayor a menor de esta forma:



C:
...
if(analogico>700)
{
    output_low(pin_verde);  //Se apagan los leds que no se usan
    output_low(pin_azul);
    output_high(pin_rojo);    //Se enciende el rojo
}
else if(analogico > 350)
{
    output_low(pin_verde);    //Se apagan los leds que no se usan
    output_low(pin_rojo);   
    output_high(pin_azul);    //Se enciende el azul
}
else if(analogico > 100)
{
    output_low(pin_azul);    //Se apagan los leds que no se usan
    output_low(pin_rojo);   
    output_high(pin_verde);    //Se enciende el verde
}
else
{
    output_low(pin_azul);    //Se apagan todos los leds
    output_low(pin_rojo);   
    output_low(pin_verde);   
}
....
 
Ahora estoy con dudas de la conexión, colocaría 3 led, el pic me da estado alto, tengo que colocar un transistor, ne conviene conectarlo a los 5 volt o a los 12 volt, como colocaría la resistencia ya que con un transistor manejaría 3 led?
 

Adjuntos

  • led-rgb-esquema.jpg
    led-rgb-esquema.jpg
    46.2 KB · Visitas: 4
Cualquiera de los dos voltajes iría bien, descartá posibles excesos en una línea (ya sea por corriente o por potencia), rendimiento y en última instancia si es posible elegí el mejor regulado.

Si por ej. te enganchás de los 5V, pero los leds piden mucha corriente, tal vez el regulador de 5V esté al límite (por corriente o por potencia), tendrías que evaluarlo. Lo mismo se puede pensar en términos de rendimiento, si los 5V son de un regulador lineal y estamos trabajando con una batería, usar los leds en el regulador implican una potencia de disipación en exceso mayor que usar los leds directamente en la línea de 12V.

- Ánodo común: derecho a la fuente y cada cátodo a una resistencia limitadora con su transistor npn de control con emisor a masa.
- Cátodo común: derecho a masa y cada ánodo a una resistencia limitadora con su transistor pnp de control con emisor a fuente.
 
Si pienso poner 3 led juntos y 3 transistores
Mensaje automáticamente combinado:

Creo que esta es la opción mejor para po era 3 led por pin del pic.
 

Adjuntos

  • unnamed.png
    unnamed.png
    10.5 KB · Visitas: 14
  • transistor.jpg
    transistor.jpg
    24.4 KB · Visitas: 15
  • bPggj.jpg
    bPggj.jpg
    77.4 KB · Visitas: 13
Última edición:
Hola, estoy haciendo un voltímetro de colores con un led RGB, cuando entra una tensión en el adc quiero que cambie de la gama de colores en 16 pasos ,hasta ahora no he podido implementar el adc correctamente, si me pueden dar algún consejo como seguir, gracias
 

Adjuntos

  • led rgb.rar
    69.7 KB · Visitas: 7
A ver, no me fijé en la función "pwm_duty", pero ya desde el main tenés esto:

C:
void main(){

setup_adc_ports( AN0_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   set_timer0(0);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   while(true){
      int r, g, b;
      analogico= read_adc();
      delay_ms(15);
   
      for(b=0;b<16;b++){
         pwm_duty(16,0,b);
         delay_ms(50);
     
      }
      for(r=16;r>1;r--){
         pwm_duty(r,0,16);
         delay_ms(50);
      }
      for(g=0;g<16;g++){
         pwm_duty(0,g,16);
         delay_ms(50);
      }
      for(b=16;b>1;b--){
         pwm_duty(0,16,b);
         delay_ms(50);
      }    
      for(r=0;r<16;r++){
         pwm_duty(r,16,0);
         delay_ms(50);
      }
      for(g=16;g>1;g--){
         pwm_duty(16,g,0);
         delay_ms(50);
      }
   }
}

Tenés 6 Fors de 15 repeticiones dentro del While, c/u con un delay de 50mS, haciendo un total de 4,5S de espera por cada vuelta del While que se traduce por c/muestreo en el ADC. Y si a eso le agregamos que a la variable "analogico" no lo usas nunca una vez que tomas la lectura del ADC.

Eso no parece ser muy lógico que digamos.
 
Es un uC con pocas puertos disponibles, solo 6. De los cuales uno vas a usar como entrada para el ADC y tres como salida de PWM. Además el uC cuenta con 3 timers y un módulo para hacer PWM por hard, pero la contra es que solo podrías implementar un PWM, vos necesitás 3.

Entonces, la primera cuestión, ¿Cómo se te ocurre que podrías implementar 3 PWM, usando el hardware disponible e implementando algo de código?

La mejor opción desde mi punto de vista, es usar un timer configurado para que genere una interrupción por ej. c/1mS y luego desde la rutina de interrupción generás las tres señales de PWM según el % necesario mediante variables globales.

Si te parece bien, te propongo que primero hagas funcionar un timer, que genere una interrupción c/1mS, uses una variable que cuente hasta 1000 y cuando llegué a ese valor, cambies el estado de un puerto (conectado por ej. a un led). Si podés hacer funcionar eso, el resto se hace fácil.
 
Si lo hago por código así


Código:
void pwm_duty(int pwm0, int pwm1, int pwm2){
   int cont;
   if(cont>15)
      cont=0;
   else
      cont++;
   if(cont>0&&cont<pwm0)
      output_high(PIN_a1);
   else
      output_low(PIN_a1);
    
   if(cont>0&&cont<pwm1)
      output_high(PIN_a2);
   else
      output_low(PIN_a2);
    
   if(cont>0&&cont<pwm2)
      output_high(PIN_a4);
   else
      output_low(PIN_a4);
    
   set_timer0(0);   
}
 

Adjuntos

  • led rgb.rar
    69.7 KB · Visitas: 3
Voy a cambiar la forma de muestreo con valores fijos y una cadena de if y else, usando los datos del adjunto

De esta manera pensaba hacerlo, pero no me funciona
Código:
#include <12f683.H>
#device ADC=10
#use delay(clock=4mhz)
#fuses intrc_io,nomclr,nowdt, PROTECT
 
int16 analogico;

#int_timer0
void pwm_duty (int pwm0, int pwm1, int pwm2){
   int cont;
   if(cont>99)
      cont=0;
   else
      cont++;
   if(cont>0&&cont<pwm0)
      output_high(PIN_a1);
   else
      output_low(PIN_a1);
      
   if(cont>0&&cont<pwm1)
      output_high(PIN_a2);
   else
      output_low(PIN_a2);
      
   if(cont>0&&cont<pwm2)
      output_high(PIN_a4);
   else
      output_low(PIN_a4);
      
   set_timer0(0);     
}
void main(){

 setup_adc_ports( AN0_ANALOG );
 setup_adc( ADC_CLOCK_INTERNAL );
 set_adc_channel( 0 );

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   set_timer0(0);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   while(true){
      
      analogico= read_adc();
delay_ms(15);
    
       if (analogico > 100){
 pwm_duty (100,0,0);

}else {

 pwm_duty (0,0,0);
}
          
  if (analogico > 200){
 pwm_duty (0,100,0);

}else {

 pwm_duty( 0,0,0);
}   

if (analogico > 300){
 pwm_duty (0,0,100);

}else {

 pwm_duty( 0,0,0);
}   





      }
  
}
 

Adjuntos

  • codigo-de-colores-equivalencia.png
    codigo-de-colores-equivalencia.png
    66.4 KB · Visitas: 11
Haceme caso, primero intentá hacer funcionar bien el timer para que encienda un led cada 1seg.

Editado:

Luego de buscar 2 minutos en google, acá tenés un ejemplo conciso y bien explicado de como funciona el timer usando CCS C (encima en español).

Del ejemplo, solo modificaría el uso de 1mS como base de tiempo y un contador de 1000, esto te va a servir a futuro para el PWM.

 
Última edición:
Atrás
Arriba