¿Cómo realizar una luz estrobo para el balance de rotores?

El proyecto trata de una luz estrobo para el balance de rotores.
Lo que trato de hacer es que la luz estrobo que tenga un frecuencia igual a las RPM del motor.

Que en todo caso 1 hertz = 1 revolución/segundo = (1 revolución/segundo) (60 segundos/minuto) = 60 rev/minuto.

Entonces lo que yo necesito es hacer que la frecuencia de la lampara sea variable ya que el motor no trabaja a una velocidad constante si no variable y la frecuencia debe variar de 0 a 3500hz

Y según para esto necesito de interrupciones.
Encontré algunos ejemplos que utilizan teclado pero en mi caso quisiera utilizar un potenciómetro como variador de frecuencia.

Otra forma en que lo vi, fue que por medio del teclado se colocara la frecuencia a la que deseo que oscile.
Por ejemplo.

Código:
FLOAT TIEMPO

TIEMPO=(100000/FRECUENCIA)/2

HIGH PORTB.0
PASUSE (TIEMPO)
LOW PORTB.0
PAUSE (TIEMPO)
¿Pero cómo meto por el teclado el valor que deseo y además cómo lo acoplo a la variable tiempo y realmente la respete?
El tiempo lo puse así ya que lo quiero en us y para convertir frecuencia a us la fórmula es la de tiempo.

Esa era la forma en la que yo pensaba que se podía pero la verdad es que no sé si realmente se puede acoplar.

También el problema es que no he llevado mucho pcw y el proyecto lo intenté hacer en microcode y funcionó, pero el problema es que en microcode no se puede sobrepasar el valor de las variables y cuando la división que realizo en la parte de arriba, se hace un valor que ya no es legible para el programa, lo bota y se reinicia desde un valor de cero.

El programa en microcode utilizando el PIC16F873A
Código:
FREC VAR WORD
MICRO VAR word
FREC=1
MICRO=1000

ON INTERRUPT GOTO VERDE
INTCON=%10010000

WHILE(1)
    HIGH PORTC.0
    PAUSE (MICRO/FREC)
    LOW PORTC.0
    PAUSE (MICRO/FREC)
    
WEND
Y este otro lo realicé en PCWHD pero no funcionó.
Código:
#include <16F873a.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock=2000000)
#use fast_io(B)
float frec=0;
float micro=1000000;
float res;

#INT_EXT 
est_isr(){
          
          frec=frec+1;
          res=(micro/frec)/2;
         }
void main(){
while(1){
           set_tris_B(0x01);
           output_high(PIN_B7);
           delay_us (res);
           output_low(PIN_B7);
           delay_us (res);
}
           enable_interrupts(int_ext);
           ext_int_edge(H_TO_L);
           enable_interrupts(GLOBAL);
}
 
Última edición por un moderador:
¿Necesitas sincronía o puede ser frecuencia libre?
Si es por sincronía puedes utilizar la interrupción por RB0
Si es frecuencia libre puedes controlarla con pulsadores y hacer uso de la instrucción FreqOut de PICBasic.
La máxima frecuencia es de 32767Hz. y se recomienda un cristal de 20MHz.

FreqOut Pin,Onms,Frequency1{,Frequency2}
Pin = Pin de salida.
Onms = Periodo en milisegundos.
Frequency1 = Frecuencia deseada.
Frequency2 = Frecuencia opcional deseada.

Ejemplo:
FreqOut PORTB.1,2000,1000
; Genera una frecuencia por el pin RB1 de 1KHz por dos segundos.

Esto viene en el manual de MicroCode Studio.
 
¿Necesitas sincronía o puede ser frecuencia libre?
Si es por sincronía puedes utilizar la interrupción por RB0

La verdad es que la necesito por sincronía pero como comente anteriormente no c como utilizar las interrupcionesen pcw en microcode me va a al 100% pero como las variables son tan pequeñas lo reboto es por eso que lo intenter en pcw ya que maneja c y puedo utilizar float
 
Esos estrobos se gatillan con un sensor de Vibración , puede ser una bobina con un núcleo magnético deslizante + resorte , que se apoya en el cojinete
 
Esos estrobos se gatillan con un sensor de Vibración , puede ser una bobina con un núcleo magnético deslizante + resorte , que se apoya en el cojinete

La verdad es que si e visto como funcionan pero no sabia que era por medio del sensor de vibraciones de hecho lleve unas practicas en una empresa y la maquina que utilizan es Balmac- Vibration Analyzer Model 216-D y bueno como tu dices tenia una entrada para el acelerometro que en esa maquina era el sensor de vibracioines

Me pordias ecir bien como es que se activa por medio del sensor?

O si tal ves me puedas pasar la forma de realizar la bobina para efectuar los disparos
 
Cualquier bobina te sirve , podría ser una de electroválvula de lavarropas

153_000_0101.jpg


La quitás y dentro le metés un resorte y un tornillo , que la cabeza quede afuera , del otro lado hasta podrias ponerle un imán de disco rígido.

También podrias usar un cerámico cualquiera , buzzer , un soporte en el borde y una pua pegada en el centro que hará de sensor de vibración

buzzer.jpg
 
¿Necesitas sincronía o puede ser frecuencia libre?
FreqOut Pin,Onms,Frequency1{,Frequency2}
Pin = Pin de salida.
Onms = Periodo en milisegundos.
Frequency1 = Frecuencia deseada.
Frequency2 = Frecuencia opcional deseada.

Ejemplo:
FreqOut PORTB.1,2000,1000
; Genera una frecuencia por el pin RB1 de 1KHz por dos segundos.

Esto viene en el manual de MicroCode Studio.

Disculpa el programa lo cheque y funciona de maravilla pero el problema que tengo es que lo queria hacer por interrucciones utilizando ese codigo y ps la verdad es que no me acepta la variable va aumentando por si solo entonces queria ver si me podias echar una mano

lo estoy viendo con el pic16f873a
Código:
cont var word 
cont=0

ON INTERRUPT GOTO VERDE
INTCON=%10001000

WHILE(1)
   if (cont==0)then frec0
   frec0:
   freqout PORTC.0,5000,1
   
   IF (Cont==1)then frec1
   frec1:
   freqout PORTC.0,5000,1
   
   IF (CONT==2)THEN frec2
   frec2:
   freqout PORTC.0,5000,2
   
   if (CONT==3)THEN frec3
   frec3:
   freqout PORTC.0,5000,3
   
   if (CONT==4)THEN frec4
   frec4:
   freqout PORTC.0,5000,4
   
   if (CONT==5)THEN frec5
   frec5:
   freqout PORTC.0,5000,5
   
   if (CONT==6)THEN frec6
   frec6:
   freqout PORTC.0,5000,6
   
   if (CONT==7)THEN frec7
   frec7:
   freqout PORTC.0,5000,7
   
   if (CONT==8)THEN frec8
   frec8:
   freqout PORTC.0,5000,8
   
   if (CONT==9)THEN frec9
   frec9:
   freqout PORTC.0,5000,9
   
   if (CONT==10)THEN frec10
   frec10:
   freqout PORTC.0,5000,10
   
   if (CONT==11)THEN frec11
   frec11:
   freqout PORTC.0,5000,11
   
   if (CONT==12)THEN frec12
   frec12:
   freqout PORTC.0,5000,12
   
   if (CONT==13)THEN frec13
   frec13:
   freqout PORTC.0,5000,13
   
   if (CONT==4)THEN frec14
   frec14:
   freqout PORTC.0,5000,14                 
WEND

DISABLE
VERDE:
IF (PORTB.4==1) THEN SUBIR
    SUBIR:
    CONT=CONT+1
IF (PORTB.5==1) THEN SUB
    SUB:
    CONT=CONT+10

RESUME   
ENABLE

END
 
Última edición por un moderador:
Disculpa, el programa lo chequé y funciona de maravilla pero el problema que tengo es que lo quería hacer por interrupciones utilizando ese código y pues la verdad es que no me acepta, la variable va aumentando por si sola, entonces quería ver si me podías echar una mano

Lo estoy viendo con el PIC16F873A
No sé muy bien que es lo que quieres que realice el programa pero como lo estás haciendo no está bien.
La configuración por interrupción de RB0 está mal.
Debe ser así:
INTCON = %11010000

Para que funcione tu rutina principal, tendría que ser de esta forma por ejemplo:
Código:
    [B]While[/B] (1)
    
    [B]Select Case[/B] cont
    
        [B]Case[/B] 0
        [B]FreqOut[/B] PORTC.0,1000,1000
        [B]Case [/B]1
        [B]FreqOut[/B] PORTC.0,1000,2000
       [B] Case[/B] 2
        [B]FreqOut[/B] PORTC.0,1000,3000
        [B]Case[/B] 3
        [B]FreqOut [/B]PORTC.0,1000,4000
       [B] Case[/B] 4
        [B]FreqOut[/B] PORTC.0,1000,5000
        [B]Case[/B] 5
        [B]FreqOut[/B] PORTC.0,1000,6000
        [B]Case[/B] 6
        [B]FreqOut[/B] PORTC.0,1000,7000

   [COLOR=Green] ; Etcétera [/COLOR]
    [B]End Select[/B]
           
    [B]Wend[/B]
Y durante el servicio de interrupción tendría que ser de esta forma:
Código:
VERDE:
    [B]Disable[/B]
    
   [B] If [/B]PORTB.4 = 1 [B]Then[/B]
        cont = cont + 1             [COLOR=Green]; Incrementar cont[/COLOR]
        [B]If [/B]cont > 14 [B]Then [/B]cont = 0   [COLOR=Green]; Si cont es superior a 14 entonces cont = 0[/COLOR]
   [B] EndIf[/B]
    
    [B]If [/B]PORTB.5 = 1 [B]Then[/B]
        cont = cont + 10
        [B]If [/B]cont > 14 [B]Then[/B] cont = 0
    [B]EndIf [/B]

    
    INTCON.1 = 0   [COLOR=Green] ; Limpiar flag INTF[/COLOR]
    
    [B]Resume[/B]
    [B]Enable[/B]
Aquí el problema será que durante el periodo que se genere la frecuencia de salida, se atenderá la interrupción, pero los cambios no se realizaran hasta que termine el periodo.
Y si estás usando 5000ms los cambios se verán hasta que transcurran 5 segundos.

Yo puse 1000ms en el ejemplo, pero tienes que tomar en cuenta que de esta forma no existirá sincronía, así que de la forma que lo estás haciendo, no funcionará.

El detalle es que no sé que deba hacer específicamente el programa para poder ayudarte correctamente.

Suerte.
 
No sé muy bien que es lo que quieres que realice el programa pero como lo estás haciendo no está bien.
La configuración por interrupción de RB0 está mal.
Debe ser así:
INTCON = %11010000
Yo puse 1000ms en el ejemplo, pero tienes que tomar en cuenta que de esta forma no existirá sincronía, así que de la forma que lo estás haciendo, no funcionará.

El detalle es que no sé que deba hacer específicamente el programa para poder ayudarte correctamente.

Suerte.
La verdad es que me va muy bien esta ves hace lo que quiero que realize pero quiero meter mas interrupciones pero como anteriormente me corregiste lo de INTCON=%10010000 no c como meter mas este codio yo lo saque del libro de microcode y ps quiero meter 4 interrupciones y en el libro cheque que viene como interrupcion del puerto B4 A B7
la primera en la que:
If PORTB.4 = 1 Then
cont = cont + 1 ; Incrementar cont +1
If cont > 60 Then cont = 0 ; Si cont es superior a 14 entonces cont = 0
EndIf
If PORTB.5 = 1 Then
cont = cont -1 ;Decremento de cont -1
If PORTB.6 = 1 Then
cont = cont+10 ;Incremento cont+10
If cont > 60 Then cont = 0
If PORTB.6 = 1 Then
cont = cont-10 ;Decremento en cont -10

Para esto en el libro me dice que el codiogo es INTCONT=%10001000 ; HABILITA LA INTERRUPCION DE RB4 A RB7

Y AL FINALIZAR INTCONT=%10001000 ME parece que este codigo es como este que colocaste arriba INTCON.1 = 0
Entonces queria ver si podrias poner el codio para meter esas 4 interrupciones

Y pues muchas gracias por estar ayudando la verdad es que me a servido de mucho
 
Entonces debes habilitar también la interrupción por cambio de estado en el puerto B (RB7:RB4)
El bit que lo hace también está en el registro INTCON (Bit 3 RBIE)
Entonces configuras INTCON de esta forma: INTCON = %11011000

Luego durante el servicio de interrupción tienes que determinar cual fue la interrupción que se ejecutó.
Por ejemplo:
Código:
Interrupciones_ISR:
    [B]Disable[/B]
    [B]If [/B]INTCON.1 = 1 [B]Then[/B] [COLOR=Green]; Fue interrupción por RB0[/COLOR]
  [COLOR=Green]  ; Código[/COLOR]
     INTCON.1 = 0 [COLOR=Green]; Limpiar flag INTF[/COLOR]
   [B] EndIf[/B]

   [B] If [/B]INTCON.0 = 1 [B]Then [/B][COLOR=Green]; Fue interrupción por RB4:RB7[/COLOR]
  [B]  If[/B] PORTB.4 = 1 [B]Then[/B] [COLOR=Green]; Cambio de estado en RB4[/COLOR]
   [COLOR=Green] ; Código[/COLOR]
    [B]EndIf[/B]
  [B]  If [/B]PORTB.5 = 1 [B]Then[/B] [COLOR=Green]; Cambio de estado en RB5[/COLOR]
 [COLOR=Green]   ; Código[/COLOR]
    [B]EndIf[/B]
 [COLOR=Green]   ; Etcétera[/COLOR]
    INTCON.0 = 0 [COLOR=Green]; Limpiar flag RBIF[/COLOR]
    [B]EndIf[/B]
    [B]Resume[/B]
    [B]Enable[/B]
Algunas veces para que funcione la interrupción por RB4:RB7 se tiene que poner PORTB = PORTB
No siempre pero me ha tocado tener que hacer eso para que funcione correctamente.

Saludos.
 
Última edición:
Entonces debes habilitar también la interrupción por cambio de estado en el puerto B (RB7:RB4)
El bit que lo hace también está en el registro INTCON (Bit 3 RBIE)
Entonces configuras INTCON de esta forma: INTCON = %11011000
Algunas veces para que funcione la interrupción por RB4:RB7 se tiene que poner PORTB = PORTB
No siempre pero me ha tocado tener que hacer eso para que funcione correctamente.

Saludos.
Buenas. Gracias por la ayuda.
Tenías razón sobre lo de que algunas veces no funciona.
Lo del código PORTB = PORTB ¿Dónde lo tengo que colocar?
En este momento está de esta forma.
Código:
cont var word 
cont=0
PORTB = PORTB

ON INTERRUPT GOTO VERDE
INTCON=%11011000
 While (1)
 Select Case cont
    
        Case 0
        FreqOut PORTC.0,1000,1
        Case 1
        FreqOut PORTC.0,1000,1
        Case 2
        FreqOut PORTC.0,1000,2
        Case 3
        FreqOut PORTC.0,1000,3
        Case 4
        FreqOut PORTC.0,1000,4
        Case 5
        FreqOut PORTC.0,1000,5
        Case 6
        FreqOut PORTC.0,1000,6
        CASE 7
        FREQOUT PORTC.0,1000,7
        CASE 8 
        FREQOUT PORTC.0,1000,8
        CASE 9
        FREQOUT PORTC.0,1000,9
        CASE 10
        FREQOUT PORTC.0,1000,10
        CASE 11
        FREQOUT PORTC.0,1000,11
        CASE 12
        FREQOUT PORTC.0,1000,12
        CASE 13
        FREQOUT PORTC.0,1000,13
        CASE 14
        FREQOUT PORTC.0,1000,14
        CASE 15
        FREQOUT PORTC.0,1000,15
        CASE 16
        FREQOUT PORTC.0,1000,16                
        CASE 17
        FREQOUT PORTC.0,1000,17
        CASE 18
        FREQOUT PORTC.0,1000,18
        CASE 19
        FREQOUT PORTC.0,1000,19
        CASE 20
        FREQOUT PORTC.0,1000,20
        CASE 21
        FREQOUT PORTC.0,1000,21
        CASE 22
        FREQOUT PORTC.0,1000,22
        CASE 23
        FREQOUT PORTC.0,1000,23
        CASE 24
        FREQOUT PORTC.0,1000,24
        CASE 25
        FREQOUT PORTC.0,1000,25
        CASE 26
        FREQOUT PORTC.0,1000,26
        CASE 27
        FREQOUT PORTC.0,1000,27
        CASE 28
        FREQOUT PORTC.0,1000,28 
        CASE 29
        FREQOUT PORTC.0,1000,29
        CASE 30
        FREQOUT PORTC.0,1000,30 
        CASE 31
        FREQOUT PORTC.0,1000,31
        CASE 32
        FREQOUT PORTC.0,1000,32   
        CASE 33
        FREQOUT PORTC.0,1000,33 
        CASE 34
        FREQOUT PORTC.0,1000,34
        CASE 35
        FREQOUT PORTC.0,1000,35
        CASE 36
        FREQOUT PORTC.0,1000,36
        CASE 37
        FREQOUT PORTC.0,1000,37
        CASE 38
        FREQOUT PORTC.0,1000,38
        CASE 39
        FREQOUT PORTC.0,1000,39
        CASE 40
        FREQOUT PORTC.0,1000,40
        CASE 41
        FREQOUT PORTC.0,1000,41
        CASE 42
        FREQOUT PORTC.0,1000,42
        CASE 43
        FREQOUT PORTC.0,1000,43
        CASE 44
        FREQOUT PORTC.0,1000,44
        CASE 45
        FREQOUT PORTC.0,1000,45
        CASE 46
        FREQOUT PORTC.0,1000,46
        CASE 47
        FREQOUT PORTC.0,1000,47
        CASE 48
        FREQOUT PORTC.0,1000,48
        CASE 49
        FREQOUT PORTC.0,1000,49 
        CASE 50
        FREQOUT PORTC.0,1000,50 
        CASE 51
        FREQOUT PORTC.0,1000,51
        CASE 52
        FREQOUT PORTC.0,1000,52
                            
    End Select
           
    Wend
    Verde:
    Disable
    
    If PORTA.4 = 1 Then ; Cambio de estado en RB4
    cont = cont + 1
    If cont > 60 Then cont = 0 
    EndIf
    If PORTA.5 = 1 Then ; Cambio de estado en RB5
    cont = cont - 1
    If cont > 60 Then cont = 0 
    EndIf
    If PORTA.6 = 1 Then ; Cambio de estado en RB6
    cont = cont + 10
    If cont > 60 Then cont = 0 
    EndIf
    if PORTA.7 = 1 Then ; Cambio de estado en RB7
    cont = cont - 10
    If cont > 60 Then cont = 0 
    EndIf
    
    INTCON.0 = 0 ; Limpiar flag RBIF
    Resume
    Enable
 
Última edición por un moderador:
El PORTB = PORTB se pone dentro del servicio de interrupción, enseguida de Disable
Ésto es por si utilizas la interrupción por cambio de estado en RB4:RB7

Pero en tu código no estás verificando que interrupción se está ejecutando y tienes activas INTE y RBIE
O sea por RB0 y por RB4:RB7
Por lo tanto la ejecución de instrucciones que están dentro del servicio de interrupción, actuarán cuando cualquiera de estas dos interrupciones que tienes establecidas se ejecuten.

Por eso te puse en el ejemplo anterior como determinar cual fue la interrupción que se está ejecutando y a continuación escribes el código que requieras cuando ésta se ejecute.

Corrige ese detalle para que no tengas problemas cuando se ejecuten o selecciona que tipo de interrupción necesitas y conforme a lo que decidas configuras el registro INTCON.
 
El PORTB = PORTB se pone dentro del servicio de interrupción, enseguida de Disable
Ésto es por si utilizas la interrupción por cambio de estado en RB4:RB7

Muchas gracias, finalmente quedó.

El problema que tengo ahora es que lo quiero mostrar en una lcd y pues para eso quería hacerlo contando los pulsos pero no resulta, salen valores muy altos.
Este quería probarlo con el 555 pero no sale.
Código:
DEFINE LCD_DREG PORTA 'Puerto LCD Datos
DEFINE LCD_DBIT 0 'bit de inicio
DEFINE LCD_RSREG PORTB 'Registro puerto LCD
DEFINE LCD_RSBIT 5 'bit RS
DEFINE LCD_EREG PORTB 'Registro enable
DEFINE LCD_EBIT 6 'bit Enable
DEFINE LCD_BITS 4 'bus LCD
DEFINE LCD_LINES 2 'número de líneas
CMCON=7
revo VAR WORD   
PROG:
    PAUSE 200
    count portb.0,1000,revo
    revo=revo * 60 
    LCDOUT $FE,1
    LCDOUT $FE,$82," Velocidad:"
    lcdout $fe,$C5,DEC revo,"RPM" 
     pause 200
GOTO PROG    
END
 
Última edición por un moderador:
Quita los retardos de 200Ms. pues la función Count está realizando uno de 1000Ms.
¿Cuantos dígitos tiene la variable revo?
Si utilizas una variable tipo Word para revo, entonces tiene 5 digitos. (Word = 65535 Max.)
Para que no se sobrepongan números en la pantalla, en vez de Dec escribe Dec5 (Muestra 5 dígitos)

Recuerda que Count paraliza el programa durante el tiempo que establezcas como periodo.
Así que, en tu caso el programa no responderá durante un segundo.
Y la máxima frecuencia que podrás contar con Count a 20MHz es de 125KHz. (125000 Hz.)
 
Atrás
Arriba