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

Temas similares

23/06/2016 #21

Avatar de callecuatro1976

Hasta acá voy muy bien, puedo contar los pulsos, lo que no sé cómo hacer, es medir el duty de la señal y mostrarlo en porcentaje. ¿Cómo lo hago?
No me doy idea de cómo hacer para mostrarlo en el lcd y que cálculo hacer.

Código PHP:
#include <16f883.h>            
#device ADC=10
#use delay (internal = 8MHz)
#FUSES NOWDT                   
#FUSES XT                       
#FUSES PUT                      
#FUSES NOPROTECT               
#FUSES NODEBUG                  
#FUSES NOLVP                    
#FUSES NOCPD                    


      

#include <lcd.C>                

int16 pulso_total;
int16 pulsos;
int8 aux;



#int_TIMER1              
void temp1s(void)       
{  
   
aux++;
   if (
aux == 2)
   {   
      
pulso_total pulsos;
      
pulsos 0;
      
aux 0;
   }      
   
set_timer1 (3036);  
   
}

#int_ccp1
void trata_pulsos(void)
{
   
pulsos++;
}


void main()
{
   
lcd_init();                   
   
   
setup_ccp1(CCP_CAPTURE_RE);   
   
setup_timer_1 (T1_INTERNAL T1_DIV_BY_8);  
      
   
enable_interrupts(INT_CCP1);
   
enable_interrupts(INT_TIMER1);              
   
enable_interrupts(global);                   
   
set_timer1 (3036);                            
   
   while(
TRUE)                                  
   {
   
lcd_gotoxy(7,2);
      
printf(lcd_putc,"speed=%03lu",pulso_total);
      
delay_ms (500);
      
   }

25/06/2016 #22

Avatar de callecuatro1976

Vuelvo con el caballo agotado, no cansado.
Éste código mide perfecto, sólo no logro medir el duty. ¿Me pueden dar una mano?
Código PHP:
#include <16f883.h>
#device ADC=10
#use delay (internal = 8MHz)
#define use_portb_lcd true
 #fuses NOFCMEN, NOIESO,INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,
#include <lcd.c>
 
int16 tic,tic2,tic3,f;
int1 tiempo,tiempo2;
float T,Periodo;
int8 duty;
#int_CCP1
void  CCP1_isr(void
{
   if(!
tiempo)                         
   {
      
tic2 CCP_1;   //alto               
      
tiempo 1;                       
   }
   
   else
   {
      
tic3 CCP_1;        //bajo           
      
tiempo 0;                       
      
      if(!
tiempo2tiempo2 1;               
   }
 }
 
void main()
{
 
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   
setup_ccp1(CCP_CAPTURE_rE);
 
enable_interrupts(INT_CCP1);
 
enable_interrupts(GLOBAL);
  
lcd_init(); 
 while (
true){
 
 if(
tiempo2)                       
      {
        
         
tic = (tic3 tic2); 
         
            
T=4.0*8.0/8000000.0;
 
   
Periodo=T*tic;
   
   
F=1/Periodo;
             
         
tiempo2 0;                   
        
      }
 
 
duty=tic*100 /(tic+tic2);
      
lcd_gotoxy(1,2);
   
printf(lcd_putc,"d=%u",duty);
   
   
     
lcd_gotoxy(9,2);
   
printf(lcd_putc,"F=%03lu",F);
 }
}
 } 
25/06/2016 #23
Moderador

Avatar de D@rkbytes

Para calcular el ciclo activo, debes obtener el tiempo en alto del pulso y el periodo de la frecuencia.
Luego lo obtienes con ésta fórmula:
Donde "t" es la duración del pulso en estado alto y "T" es el periodo.
25/06/2016 #24

Avatar de callecuatro1976

Entonces esta mal lo que hice de duty=tic*100/(tic+tic2) lo voy a ver mejor
También probé esto y nada
Imágenes Adjuntas
Tipo de Archivo: jpg images.jpg (5,4 KB (Kilobytes), 9 visitas)
27/06/2016 #25
Moderador

Avatar de D@rkbytes

Si está bien esa fórmula, pero mejor trata de hacerlo por medio de la interrupción externa por RB0 y mide los periodos con el Timer 1.

Hace algún tiempo hice eso para obtener el ciclo activo de una señal PWM y obtuve buenos resultados.
27/06/2016 #26

Avatar de callecuatro1976

Ok voy a probar rb0 es el pin de la interrupción. Yo tengo el lcd por el puerto B con el Pic 16f883 puedo sacarlo por el puerto c las conexiones para lcd?
27/06/2016 #27
Moderador

Avatar de D@rkbytes

Si usas la librería "lcd.c", puedes direccionar los pines de datos y control al puerto que quieras.
Ve la información en la misma librería.
28/06/2016 #28

Avatar de callecuatro1976

Gracias D@RKBYTE!!!

después de tantas idas y venidas funciono
solo tengo 2 problemas que ya no se como resolverlo
1) cuando enciendo el lcd no me aparece el valor en pantalla, aparece cuando empieza a contar.
2) cuando cuenta y corto el pulso no vuelve a cero y es el if(pulsonuevo) pero no se como solucionarlo, gracias
Código:
 
 #include <16f883.h>
#device ADC=10
#use delay (internal = 8MHz)
#define use_portb_lcd true
 #fuses NOFCMEN, NOIESO,INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,
#include <lcd.c>
int1 nuevopulso=0;
int16 t_bajada_1=0,t_subida_1=0,t_on=0,t_total=0,t_subida_2=0;
float32  t=0,f,duty,periodo;
int flag;
#int_ccp1
void ccp1_int(void)
{
if(flag == 3)
{
flag = 0;
}
if (flag == 0 )
{
t_subida_1=ccp_1;
setup_ccp1(CCP_CAPTURE_FE);
}
if (flag ==1 )
{
t_bajada_1=ccp_1;
setup_ccp1(CCP_CAPTURE_RE);
}
if ( flag==2)
{
t_subida_2=ccp_1;
setup_ccp1(CCP_CAPTURE_RE);
 if (nuevopulso==0)
{
nuevopulso=1;
}
}
flag++;
}
 void main()
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
setup_ccp1(CCP_CAPTURE_RE);
flag=0;
 enable_interrupts(int_ccp1);
enable_interrupts(global);
nuevopulso=0;
lcd_init();
while(true)
{
 if(nuevopulso)
{
t_on=(t_bajada_1-t_subida_1);
 t_total=(t_subida_2-t_subida_1);
 t=4.0*8.0/8000000.0;
   Periodo=T*t_total;
f=1/periodo;
 duty=(float)t_on*100/t_total;
 delay_ms(50);
  lcd_gotoxy(1,2);
printf(lcd_putc,"F=%3.0f",f);
    lcd_gotoxy(9,2);
printf(lcd_putc,"duty=%2.0f%%",duty);    
delay_ms(100);
nuevopulso=0;
 }
 }
  
 
}
28/06/2016 #29

Avatar de ruben90

1) cuando enciendo el lcd no me aparece el valor en pantalla, aparece cuando empieza a contar.
R = porque toda la operación la tienes dentro de la sentencia if(nuevopulso) { }
28/06/2016 #30

Avatar de callecuatro1976

Si saco la operación de la sentencia y cuenta mal
28/06/2016 #31

Avatar de ruben90

No creo (si sigues una lógica no puedes equivocarte). Prueba lo siguiente,
Código:
if(nuevopulso)
{
t_on=(t_bajada_1-t_subida_1);
t_total=(t_subida_2-t_subida_1);
t=4.0*8.0/8000000.0;
Periodo=T*t_total;
f=1/periodo;
duty=(float)t_on*100/t_total;
delay_ms(50);
nuevopulso=0;
}
lcd_gotoxy(1,2);
printf(lcd_putc,"F=%3.0f",f);
lcd_gotoxy(9,2);
printf(lcd_putc,"duty=%2.0f%%",duty);    
delay_ms(100);
Siempre mostrara el valor, porque las variables f y duty las declaraste como globales y el valor queda guardado hasta calcular uno nuevo.
28/06/2016 #32

Avatar de callecuatro1976

Probé así y no me muestra bien los datos en el lcd. igual me falta ver como hago para que cuando cuente y cuando pare de recibir los pulso muestre cero.
30/06/2016 #33
Moderador

Avatar de D@rkbytes

Si quieres mostrar correctamente el porcentaje del ciclo activo, olvídate del CCP y hazlo por interrupción externa usando el Timer 1 para medir los periodos.
01/07/2016 #34

Avatar de callecuatro1976

Hola darkbyte la verdad cambie a basic pro y ya estoy un poco mejor tengo que revisar que funcione todo bien y depurar un poco el código si queres mirarlo y darme una mano bienvenido sea.

Código:
  
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 0
define lcd_lines 2
define intosc 8
DEFINE ADC_BITS 8
DEFINE ADC_CLOCK 3 
DEFINE ADC_SAMPLEUS 50
ANSEL = %11111111 
ANSELH = %00000000 
lectura var word
lectura2 var word
resultado VAR word
resultado2 var word
f var word
bajo VAR WORD 
alto VAR WORD 
total VAR WORD 
duty VAR WORD 


lcdout $fe,1," iniciando "
pause 200 
LCDOUT $FE, 1 
inicio:

ADCIN 0, LECTURA 
RESULTADO = (LECTURA */ 500)
adcin 2,lectura2
resultado2 = (lectura2 */500)

PULSIN PORTc.2 , 0 , bajo : PULSIN PORTc.2 , 1 , alto
COUNT PORTc.2, 1000, f
cutdown2:
total = bajo + alto
if total > 655 then 
bajo = bajo / 2 : alto = alto / 2 : goto cutdown2
endif
duty = ( alto* 100 ) / total
LCDOut $fe , 1
lcdout $fe ,$80 ," DUTY:" , DEC2 duty +1 ,"%"
LCDOUT $fe , $C0 ,"CPS:" , DEC3 f 
LCDOUT $fe, $8a, "V=", DEC (RESULTADO/10),".",dec1 resultado
lcdout $fe,$c9, " A=", dec (resultado2/10),".",dec1 resultado2
pause 200

GOTO inicio 
end
01/07/2016 #35
Moderador

Avatar de D@rkbytes

Mide el pulso con la interrupción de RB0 con PulsIn.
Eso le dará mayor precisión a las lecturas.
01/07/2016 #36

Avatar de callecuatro1976

Y como mido con count esta bien usar así los dos comandos? Y porque el duty no va subiendo? Voy a cambiar midiendo por rb0 y veo como va gracias.
01/07/2016 #37
Moderador

Avatar de D@rkbytes

El problema con la instrucción "Count", es que detiene la ejecución del programa por el tiempo establecido, en tu caso, 1000 ms.
Todavía aparte de ese retardo, estás poniendo otro de 200 ms.
De esa forma nunca vas a medir los pulsos correctamente.

Pues que mal que hayas cambiado de lenguaje, porque en C lo pudiste haber hecho más fácil.


En PICBasic también lo puedes lograr, pero debes hacer uso de interrupciones y timers.
Imágenes Adjuntas
Tipo de Archivo: jpg Duty Percent.jpg (164,2 KB (Kilobytes), 50 visitas)
02/07/2016 #38

Avatar de callecuatro1976

Si, tenéis razón. Lo que pasa es que se me hizo una ensalada y como no me quedaba como quería en c, probé en basic.
En basic me funcionó pero el código no es estable, lo colocas en un lcd y corre por momentos o no corre y en c funcionaba mejor.

Entonces vos que sabes, me recomendáis hacerlo en c con el timer1.
Bien, como arranco con el timer1 ya quedó, sé como seguir. Gracias por tu tiempo.

--- Actualizado ---

Esto es lo que hice hasta ahora y no me funciona. ¡Ayuda!
Código:
#include <16f883.h>
#device ADC=10
#use delay (internal = 8MHz)
#define use_portb_lcd true
 #fuses NOFCMEN, NOIESO,INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,
#include <lcd.c>
 int16 bajo,alto, tiempo;
int1 pulso;
float t,periodo,f;
int bandera;
#int_timer1
void timer1_int(void)
{
 if(bandera==0){
 bajo=get_timer1();
 EXT_INT_EDGE(0,L_TO_H);
 
}
if ( bandera==1)
{
alto=get_timer1();
EXT_INT_EDGE(0,H_TO_L);
 if (pulso ==0)
{
pulso=1;
}
}
bandera++;
 }
void main(){
 set_timer1(0); 
SETUP_TIMER_1(T1_INTERNAL  |T1_DIV_BY_8);
EXT_INT_EDGE(0,L_TO_H);
enable_interrupts(int_ext);
enable_interrupts(GLOBAL);
lcd_init();
bandera=0;
while (true){
  lcd_gotoxy(1,1);
   T=4.0*8.0/8000000.0;
   Periodo=T*tiempo;
   F=1/Periodo;
   printf(lcd_putc,"tiempo= %Lu",tiempo);
   printf(lcd_putc,"\nF= %FHz",F);
 }
 
}
02/07/2016 #39
Moderador

Avatar de D@rkbytes

Mira el ejemplo adjunto, en simulación mide el ciclo activo desde el 12% hasta el 89%
La frecuencia de entrada es de 1 KHz y seguramente necesitarás adaptarlo a la frecuencia del equipo.
Archivos Adjuntos
Tipo de Archivo: rar 16F883 Obtener porcentaje del ciclo activo.rar (91,8 KB (Kilobytes), 15 visitas)
02/07/2016 #40

Avatar de callecuatro1976

MUCHAS GRACIAS! me sirvió mucho y entendí un poco mas como hacerlo, ahora antes de seguir cambiando te consulto cuando deja de recibir pulsos tendría que ponerse en cero la frecuencia y el duty, no se como hacerlo! cuando recibe un pulso largo o tendría que quedar en 99% hasta que el pulso se termine y eso no se como hacerlo, te tengo que pagar un asado por lo que me ayudaste muchas gracias ya que hiciste que entienda mejor lo que estaba haciendo.
¿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.