Mostrar voltaje sin usar ADC

#41
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



 int  voltaje=0;


void tension()
{


 
  if (input(PIN_A4)==0)
   {
    while(!input(pin_a4)){
      delay_ms(10);
for(voltaje=0;voltaje <18;voltaje++)
{
delay_ms(60);
           lcd_gotoxy(11,1);
  printf(lcd_putc,"V=%3u",voltaje);
}

    }
   }
  if (input(PIN_A5)==0)
   {
    while(!input(pin_a5)){
            delay_ms(10);
    for(voltaje=18;voltaje >0;voltaje--){
    
    delay_ms(60);
             lcd_gotoxy(11,1);
  printf(lcd_putc,"V=%3u",voltaje);
    }

  
    
   }
  
   }
}
 void main ()
 {
 

  
  
  lcd_init(); 
  
  
   while (true)
   {
  
  
  
   tension();
  
   }
 }
 
 lo hice asi y me cuenta y baja pero estoy mas cerca , como puedo ponerle coma ala muetra no se me ocurre
Lo que estoy viendo con tu código, es que el anti rebote que estas implementado esta mal, por eso no esta sumando de a uno, la forma correcta seria así:
Código:
void tension(){

  if (input(PIN_A4)==0){
    while(!input(pin_a4)){}
      voltaje++;  // Incrementar
         if (voltaje > 18){ voltaje=18;}
   }

  if (input(PIN_A5)==0){
    while(!input(pin_a5)){}
     voltaje --;
       if (voltaje > 18) {voltaje = 0;}
   }
 
  lcd_gotoxy(11,1);
  printf(lcd_putc,"V=%2.1u",voltaje);
}
asi funciona pero cuando mantengo apretado el pulsador tendría que subir rápido y se queda , es difícil hacerlo pero con paciencia saldrá y su aya , gracias
 
Última edición:
#42
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.
 
#45
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));
        }
    }
}
 
#46
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:
#47
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í.
 
#49
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.
 
#50
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 "<".
 
#51
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
 
#52
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.
        }
    }
}
 
#53
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?
 
#54
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.
 
#56
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.
        }
        
        
        
        
    }
 
}


aca esta todo el trabajo pero como me imaginaba no funcia bien , no van de la mano el voltaje que es el contador y el ciclo activo , hay que seguir trabajando
 
#57
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.
 
#58
Si no logro que quede estable probé de todo, promedios, capacitores,que limpie pantalla cada segundo y no me queda bien, las bobinas que conecto tienen mucho ruido eléctrica!
 
#60
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


Arriba