desktop

Mostrar voltaje sin usar ADC

A ver veamos. Algo así que uso desde tiempo.

if(!input(PIN_A4)) // Comprueba Botón pulsado
{
if(rebote<200)rebote++;
if(rebote==150&&voltaje<18) voltaje++;
}
else rebote=0;

Los valores de rebote, depende de la velocidad del micro, lo que hace ésta variable auxiliar es incrementar el valor de voltaje sólo una vez cuándo es pulsado el botón.
Con un arreglo adicional puede hacerse que incremente uno a uno si se mantiene presionado el botón.
Fíjate que no uso ningún delay, y si el tiempo de incremento es muy rápido, sólo hay que aumentar el o los valores de "rebote" hasta dónde sea necesario.
 
Si me esta volviendo loco, todavía me falta mostrarlo con coma, pensé en ver de mostrar 18, mostrar 180 pero no se bien como meter el punto
 
todavía me falta mostrarlo con coma. Pensé en vez de mostrar 18, mostrar 180 pero no sé bien cómo meter el punto.
De esta forma es sencillo pero se consume algo de ROM:

C:
#include <16f887.h>
#use delay(INTERNAL = 4 MHz)

#include <lcd.c>

#define    pin_decr    PIN_E0
#define    pin_incr    PIN_E1

void mostrar_conteo (float conteo)
{
    if(conteo < 10)
    {    
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Conteo: 0%0.1f ", conteo);    // Si conteo es menor a 10, se muestra un 0 a la izquierda.
    }
    else
    {
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Conteo: %0.1f ", conteo);
    }
}

void main (void)
{
    float conteo = 9.0;
     
    lcd_init();
     
    mostrar_conteo(conteo);
     
    while (TRUE)
    {
        if(!input_state(pin_decr))
        {
            conteo -= 0.1;
            if(conteo <= 0) conteo = 0;
             
            mostrar_conteo(conteo);
             
            while(!input_state(pin_decr));
        }
         
        if(!input_state(pin_incr))
        {
            conteo += 0.1;
            if(conteo > 18) conteo = 18;
             
            mostrar_conteo(conteo);
             
            while(!input_state(pin_incr));
        }
    }
}
 
Una pregunta se puede usar los pulsadores para dos funciones distintas? Con un pulso mover el contador y el mismo pulso incremente otra variable de una función distinta! No se si me explico bien
funciona perfecto muchas gracias , como puedo hacer para que tenga el pulsador apretado suba rápido?
 
Última edición:
Sí se puede, incluso ejecutar otras tareas.
Para que la cuenta se realice más rápido se debe usar un contador que cuando alcance cierto número, disminuya un retardo.
Todo esto mientras se mantenga pulsado por cierto tiempo determinado por la cuenta, si no se cumple la cuenta, entonces hará lento el conteo.
Al salir de la rutina se debe limpiar el contador.

En algún ejemplo de PICBasic hice algo así, pero no recuerdo en qué post lo subí.
 
Con un bucle for no, simplemente empiezas a incrementar un contador mientras se mantenga presionado el pulsador.
Si el contador llega a X número, entonces reduces una variable int16 que establezca el retardo.
 
Si quieres con coma, debes poner "float" en vez de "int", y en vez de "voltaje=0", tienes que poner "voltaje=0.0".
Asi mismo la suma;
voltaje = voltaje + 0.1;
La resta;
voltaje = voltaje - 0.1;
Y los limites;
if(voltaje != 18.0){}
Y
if(voltaje != 0.0){}

Quizas en vez de "!=" Puedas usar ">" y "<".
 
el contador para incremente rápido tendría que ser asi
Código:
#include <16f886.h>
#device ADC=10
#use     delay(internal = 8MHz)                           
#define  LCD_DATA_PORT getenv("SFR:PORTC")
#include <flex_lcd.c>

#define LCD_RW_PIN    PIN_C3


 


void mostrar_conteo (float conteo)
{
    if(conteo < 10)
    {   
        lcd_gotoxy(1,1);
        printf(lcd_putc,"v: %0.1f ", conteo);    // Si conteo es menor a 10, se muestra un 0 a la izquierda.
    }
    else
    {
        lcd_gotoxy(1,1);
        printf(lcd_putc,"v: %0.1f ", conteo);
    }
}

void main (void)
{
    float conteo = 1.0;
    
    lcd_init();
    
    mostrar_conteo(conteo);
    
    while (TRUE)
    {
        if(!input_state(pin_a4))
        {
        
            conteo -= 0.1;
            if(conteo <= 0) conteo = 0;
            
            mostrar_conteo(conteo);
              while(!input_state(pin_a4) );
              
              
                 if(input(pin_a4)==0){
          while(!input(pin_a4)){
          conteo--;}
      
        
        
        if(!input_state(pin_a5))
        {
            conteo += 0.1;
            if(conteo > 18) conteo = 18;
            
            mostrar_conteo(conteo);
           while(!input_state(pin_a5));
          
        }
    }
    }
}

Código:
#include <16f886.h>
#device ADC=10
#use     delay(internal = 8MHz)                           
#define  LCD_DATA_PORT getenv("SFR:PORTC")
#include <flex_lcd.c>

#define LCD_RW_PIN    PIN_C3


 



#define    pin_decr    PIN_a4
#define    pin_incr    PIN_a5

void mostrar_conteo (float conteo)
{
    if(conteo < 10)
    {   
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Conteo: %0.1f ", conteo);   
    }
    else
    {
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Conteo: %0.1f ", conteo);
    }
}

void main (void)
{
    float conteo = 0.0;
     int16 cont;
    
    lcd_init();
    
    mostrar_conteo(conteo);
    
    while (TRUE)
    {
        if(!input_state(pin_decr))
        {
    
            conteo -= 0.1;
            if(conteo <= 0) conteo = 0;
            
            mostrar_conteo(conteo);
         }
          
        
        
        if(!input_state(pin_incr))
        {
    

             if(cont<200)cont++;

    
            conteo += 0.1;
            if(conteo > 18) conteo = 18;
            
            mostrar_conteo(conteo);
             while(!input_state(pin_incr));
              
        
            
          
        
        }
    }
}

no pudo hacer que cuente rápido o cuanta rápido o de uno en uno no entendí del tiempo del rebote
 
Esa función la he implementado de otras maneras, (más optimizada) pero esta es una forma de hacerlo:
C:
#include <16f887.h>
#use delay(INTERNAL = 4 MHz)

#include <lcd.c>

#define    pin_decr    PIN_E0
#define    pin_incr    PIN_E1

void mostrar_conteo (float conteo)
{
    if(conteo < 10)
    {   
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Conteo: 0%0.1f ", conteo);
    }
    else
    {
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Conteo: %0.1f ", conteo);
    }
}

void main (void)
{
    float conteo = 9.0;
    int16 cont_r = 0, retardo;
    
    lcd_init();
    
    mostrar_conteo(conteo);
    
    while (TRUE)
    {
        retardo = 200;
        
        if(!input_state(pin_decr))
        {
            while(!input_state(pin_decr))
            {
                cont_r ++;
                
                if(cont_r > 9)        // Si "cont_r" llega a 10, se reduce el retardo.
                    retardo = 50;
                else
                    retardo = 250;
                    
                conteo -= 0.1;
            
                if(conteo <= 0)
                {
                    conteo = 0;
                    cont_r = 0;        // Para evitar el desborde por mantener el pulsador presionado.
                }
            
                mostrar_conteo(conteo);
                
                delay_ms(retardo);
            }
            cont_r = 0;                // Limpiar "cont_r" si no se entra al bucle.
        }
        
        if(!input_state(pin_incr))
        {
            while(!input_state(pin_incr))
            {
                cont_r ++;
                
                if(cont_r > 9)        // Si "cont_r" llega a 10, se reduce el retardo.
                    retardo = 50;
                else
                    retardo = 250;
                    
                conteo += 0.1;
            
                if(conteo > 18)
                {
                    conteo = 18;
                    cont_r = 0;        // Para evitar el desborde por mantener el pulsador presionado.
                }
            
                mostrar_conteo(conteo);
                
                delay_ms(retardo);
            }
            cont_r = 0;                // Limpiar "cont_r" si no se entra al bucle.
        }
    }
}
 
Necesito si tenes tiempo que me expliques las líneas del temporizado, quiero lograr en algún momento poder hacer aunque sea algo más sencillo, gracias por el tiempo invertido
Otra consulta todo ese programa se podía hacer en una función así la agrego en un programa? El While true puede estar dentro de una función?
 
Con lo que comenté se me hizo más que suficiente para comprender lo que se está haciendo.
Son instrucciones muy básicas que se comprenden al ir leyendo.
Y si comprendes el uso específico que se le está dando al código, verás que no se puede implementar como función.
 
Si veo que no se puede hacer una función voy a probar de adaptarlo y subo lo que hice, gracias

Código:
#include <16f886.h>
#device ADC=10
#use     delay(internal = 8MHz)                          
#define  LCD_DATA_PORT getenv("SFR:PORTC")
#include <flex_lcd.c>

#define LCD_RW_PIN    PIN_C3
//#include <internal_eeprom.c>


int1 flagHayDatos=0;
float const ticks_us = 4.0;          // microsegundos por Tick del Timer 1 @ 8 MHz. (Osc. Interno)
//float const ticks_us = 8.0;          // microsegundos por Tick del Timer 1 @ 8 MHz. (Osc. Cristal)
long int  var2=0;
int8 flancos;
int8 flag_flanco;
int16 periodo1,periodo2,periodo3;
int16 tiempo_alto,tiempo_bajo,tiempo_total;
float us_alto,us_bajo,us_total,valor2,amper, duty;
   int porcentaje;
   int frecuencia;
 

int8   ciclo_activo=1;

  int16 cont3;  
 



  #define    pin_decr    PIN_a5
#define    pin_incr   PIN_a4
  int16 cont4;
   float conteo = 0;



void energia2()  
{
// set_adc_channel(11);
//  delay_us(50);
//  ene = read_adc();
// if(ene<200)
if(input(pin_B4)==0){
cont4++;
delay_ms(1);
if (cont4 >10) {
write_eeprom(04,conteo);
delay_ms(50);
cont4 = 0;            
               }
                  }
}


#INT_EXT
void sdi_externa_RB0 (void)
{
   flancos++;                          // Incrementar la variable "flancos"
 
   if(!flag_flanco)                    // Si el flanco del pulso es bajo...
   {
      if(flancos == 1)                 // Si el conteo de flancos es 1...
      {
         set_timer1(0);                // Limpiar el Timer 1
         periodo1 = get_timer1();      // "periodo1" tendrá el tiempo del pulso en alto.
      }
      if(flancos == 3)                 // Si el conteo de flancos es 3...
         periodo3 = get_timer1();      // "periodo3" tendrá el tiempo del pulso en alto.
       
         EXT_INT_EDGE(H_TO_L);         // Establecer la interrupción por flanco de bajada.
         flag_flanco = 1;              // Indicar que el próximo flanco será de bajada.
   }
   else                                // Caso contrario. (Pulso en estado alto)...
   {
      periodo2 = get_timer1();         // "periodo2" tendrá el valor del pulso en bajo.
      EXT_INT_EDGE(L_TO_H);            // Establecer la interrupción por flanco de subida.
      flag_flanco = 0;                 // Indicar que el próximo flanco será de subida.
       if(flagHayDatos==0){       // Si los datos anteriores han sido procesados ...
      flagHayDatos=1;          // Indico que ya hay nuevos datos de flancos para calcular
    }
   }

   if(flancos > 2)flancos = 0;         // Si la variable "flancos" llega a 3, ponerla a 0.
}



void establecer_ciclo (int8 ciclo)
{
   
    set_pwm1_duty(ciclo);   // Establecer el ciclo activo




 

   
}



 
void pulsadores()
{  
   if (input(PIN_A4)==0)
   {
    while(!input(pin_a4)){
      ciclo_activo ++;  // Incrementar el ciclo activo.
      if (ciclo_activo > 249) ciclo_activo = 249;   // No permitir que el ciclo activo suba de 249
      delay_ms(10);
      establecer_ciclo(ciclo_activo);
     
   }
   }
   if (input(PIN_A5)==0)
   {
    while(!input(pin_a5)){
      ciclo_activo --;  // Disminuir el ciclo activo.
       if (ciclo_activo <= 1) ciclo_activo = 2;  // No permitir que el ciclo activo baje de 1
          delay_ms(10);
      establecer_ciclo(ciclo_activo);
     
   }
 
}
}



void energia()  
{
// set_adc_channel(11);
//  delay_us(50);
//  ene = read_adc();
// if(ene<200)
if(input(pin_B4)==0){
cont3++;
delay_ms(1);
if (cont3 >10) {
write_eeprom(03,ciclo_activo );
delay_ms(50);
cont3 = 0;            
               }
                  }
}
void mostrar_conteo (float conteo)
{
    if(conteo < 10)
    {  
        lcd_gotoxy(11,1);
        printf(lcd_putc,"V: %0.1f ", conteo);
    }
    else
    {
        lcd_gotoxy(11,1);
        printf(lcd_putc,"V: %0.1f ", conteo);
    }
}
void main()
{
 
ciclo_activo =read_eeprom(03);                  
    establecer_ciclo(ciclo_activo);  
   
setup_ccp1(CCP_PWM);
   setup_timer_2(T2_DIV_BY_4,249,1);   // 1000 Hz. @ 4 MHz.
   set_pwm1_duty(1);                   // Ciclo activo al mínimo
 
   setup_adc_ports(sAN1|san3|san11);
   setup_adc(ADC_CLOCK_INTERNAL);
 
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   enable_interrupts(int_ext);
   ext_int_edge(0,L_TO_H);
   enable_interrupts(global);

   #ZERO_RAM   // Limpiar RAM. (Variables en 0)
   lcd_init();
    establecer_ciclo(ciclo_activo);
        float conteo = 0;
    int16 cont_r = 0, retardo;
   
   while (true)
   {

    if(flagHayDatos==1){
 
      if((periodo3 > periodo2) && (periodo2 > periodo1))
      {
         tiempo_alto = periodo2 - periodo1;                 // Obtener el periodo del pulso en estado alto.
         tiempo_bajo = periodo3 - periodo2;                 // Obtener el periodo del pulso en estado bajo.
         tiempo_total = tiempo_alto + tiempo_bajo;          // Obtener el periodo de la frecuencia.
         us_alto = ticks_us * tiempo_alto;                  // Obtener el periodo en microsegundos del pulso en alto.
         us_bajo = ticks_us * tiempo_bajo;                  // Obtener el periodo en microsegundos del pulso en bajo.
         us_total = ticks_us * tiempo_total;                // Obtener los microsegundos en total de la frecuencia.
         frecuencia = 1 / (us_total / 1000000);             // Obtener la frecuencia.
         duty = ((float) tiempo_bajo / (float)(tiempo_bajo + tiempo_alto));
          porcentaje = (duty * 100) + 10; // Físicamente el + 0.5 puede no ser necesario. (Ajusta desviación pero consume ROM)      
      }
       flagHayDatos=0;
    }
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Hz:%03u ",frecuencia);
       if(porcentaje < 3)porcentaje = 0;
      if(porcentaje > 95)porcentaje = 99;
   
      lcd_gotoxy(1,2);
      printf(lcd_putc,"Duty:%02u%% ",porcentaje );
   
     
       flagHayDatos=0;
     
      delay_ms(100); // Retardo para disminuir parpadeos en la pantalla. (No afecta interrupción externa.)
      if(flagHayDatos==0){
      frecuencia = 0;
      porcentaje=0;
 
   
      }
 
    pulsadores();


energia();
energia2();

  set_adc_channel(1);
    delay_us(30);
   amper=0;
  for(var2=0;var2<50;var2++)
  {
    amper=amper+ read_adc();
    delay_us(62);
  }

  valor2 = amper / 50;
  valor2 = valor2 * 20 / 1023;

  lcd_gotoxy(11,2);
  printf(lcd_putc,"A=%4.2f",valor2);
  delay_ms(60);




   
   
        retardo = 200;
       
        if(!input_state(pin_decr))
        {
            while(!input_state(pin_decr))
            {
                cont_r ++;
               
                if(cont_r > 9)        // Si "cont_r" llega a 10, se reduce el retardo.
                    retardo = 50;
                else
                    retardo = 250;
                   
                conteo -= 0.1;
           
                if(conteo <= 0)
                {
                    conteo = 0;
                    cont_r = 0;        // Para evitar el desborde por mantener el pulsador presionado.
                }
           
                mostrar_conteo(conteo);
               
                delay_ms(retardo);
            }
            cont_r = 0;                // Limpiar "cont_r" si no se entra al bucle.
        }
       
        if(!input_state(pin_incr))
        {
            while(!input_state(pin_incr))
            {
                cont_r ++;
               
                if(cont_r > 9)        // Si "cont_r" llega a 10, se reduce el retardo.
                    retardo = 50;
                else
                    retardo = 250;
                   
                conteo += 0.1;
           
                if(conteo > 18)
                {
                    conteo = 18;
                    cont_r = 0;        // Para evitar el desborde por mantener el pulsador presionado.
                }
           
                mostrar_conteo(conteo);
               
                delay_ms(retardo);
            }
            cont_r = 0;                // Limpiar "cont_r" si no se entra al bucle.
        }
       
       
       
       
    }

}



Acá está todo el trabajo pero cómo me imaginaba no funciona bien , no van de la mano el voltaje que es el contador y el ciclo activo , hay que seguir trabajando.
 
Si tienes ADC, lo mejor sería leer el voltaje y mostrarlo, no hacerlo por partes separadas.
Y si lo que te preocupa es que el voltaje no se muestre estable en la pantalla, hay varias formas de solucionarlo.
 
hola estuve haciendo pruebas y con la ayuda de ustedes pude avanzar en la idea , tengo algunos problemas como de costumbre subo el archivo y la simulación , consulta porque se me da vuelta la variable y como calculo para que cuando el pwm este en 5 volt la muestra este en 18.0 , graciaS
 

Adjuntos

  • Nueva carpeta (5).rar
    70.9 KB · Visitas: 11
Ya resolví lo que se me daba vuelta la variable, ahora estoy trabajando en que sea igual la muestra de la pantalla y el pwm!

No puedo guardar el dato de la muestra del lcd del voltaje en la memoria eeprom , subo el programa para que puedan ver , gracias
 

Adjuntos

  • Nueva carpeta (5).rar
    100.5 KB · Visitas: 14
Sí se guardan, pero únicamente cuando RB4 se encuentra en estado bajo como lo declaraste en el programa.
Sin embargo, en el esquema el pin RB4 siempre está en estado alto por R3.
 
Atrás
Arriba