Potenciometro para atrasar disparo

lo que quiero es utilizar el potenciometro para generar disparos a un triac, se que hay una instruccion que permite leer el valor de resistencia y demas, pero la verdad es que no veo que pueda darle uso a eso..
 
lo que quiero es utilizar el potenciometro para generar disparos a un triac, se que hay una instruccion que permite leer el valor de resistencia y demas, pero la verdad es que no veo que pueda darle uso a eso..

No se comprende de que cosa estás hablando
 
me explico mejor, tengo un pic con el cual voy a generar disparos a un triac, la manera como lo estoy haciendo actualmente es mediante una interrupción presionando un pulsador.. (todo esto con su debido circuito detector de cruce por cero) pero no quiero hacerlo mediante un pulsador quiero saber si se existe la posibilidad de hacerlo con un potenciometro, es decir, el potenciometro tiene un valor decimal dependiendo de en que posicion este correcto ? por tanto si por ejemplo esta al 50 % de la resistencia, entonces eso equivaldria a 50% de recorte de la onda, en otras palabras el disparo deberia de dar cada pi/2 (ciclo +) y pi/2 (ciclo -), pero si muevo ahora el potenciometro a 75% entonces tendria otro recorte de onda y asi sucesivamente... me explique compañero ?
 
creo que no me siguen.. a ver estaba viendo (corrijanme si me equivoco) una manera de hacer lo que dije pero no me da señal al simularlo en el proteus alguien sabra? :

DEFINE ADC_BITS 8
DEFINE ADC_SAMPLEUS 50
A VAR Byte
ADCON1 = %00000000
Inicio:
ADCIN 0, A
PWM PORTB.0,A,100
GoTo Inicio
End
 
Hola @marconikov, vamos por pasos.
1) creo comprender la idea que planteas.
- Variar el "ciclo de útil de trabajo" de cada semi-ciclo de la onda senoidal de la red eléctrica en función del valor resistivo de un potenciómetro, al final de cuentas un "dimer con PIC".
2) Si lo anterior es cierto, puedo comentarte lo siguiente.
Desde mi perspectiva lo que necesita no es un PWM (modulación por ancho de pulso) sino más bien un PPM (modulación por posición de pulso), esto tomando en cuenta que un triac solo necesita un pulso para dispararse.
Utilizando el ADC (conversor analógico a digital del pic) y conectándolo de la siguiente manera (figura) puedes determinar en que "porcentaje de giro" está el potenciómetro, por ejemplo:
En caso de que el potenciómetro este al 100% de su giro se obtendrá 5v y asumiendo que el voltaje de referencia del ADC también es de 5v y que estás trabajando con los 10 bits de resolución del ADC, el ADC leerá 1023, si el potenciómetro está al 50% de su giro el ADC leerá 511 y asi sucesivamente.
Con estos datos 1023,511,... etc., se puede calcular un "retardo" que dure desde el cruce por cero de la onda sinodal hasta el pulso de disparo para el TRIAC.
Con respecto al cruce por cero de la onda sinodal, el PIC tendría que detectarlo o quizá usar un circuito detector de cruce por cero externo que entregue al PIC un cambio de nivel o falco de subida o bajada por cada cruce por cero.

PD. Ni idea del compilador con el que estás trabajando pero dependiendo del compilador esta tarea podría ser más o menos difícil.
 

Adjuntos

  • Dibujo.JPG
    Dibujo.JPG
    32.4 KB · Visitas: 8
Excelente respuesta compañero, eso es básicamente lo que trataba de hacer, de hecho ya lo tengo y lo voy a publicar.

Código:
Define    LCD_DREG    PORTD
Define    LCD_DBIT    0
Define    LCD_RSREG    PORTD
Define    LCD_RSBIT    4
Define    LCD_EREG    PORTD
Define    LCD_EBIT    5
A var byte
i var byte
TRISB = %00000010
TRISD = %00000000
DEFINE ADC_BITS 8 ' Define la conversión A/D a 8 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
lcdout $fe,1
Inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
if portb.1=1 then call triac
goto inicio


Triac:
call delay
high portb.0
pause 1/100
low portb.0
return

Delay:
for i=0 to A
pause 324/10000
next
return

Funciona tal como necesito, el único problema que vi es que no puedo acoplar al mismo PIC un LCD porque los tiempos que transcurren para operar con el LCD se interponen con los del manejo de ciclo útil.
 
Última edición por un moderador:
Estoy usando el pic16f877a para una pequeña aplicación es la de variar el ciclo útil de trabajo de una onda para así mandar pulsos a un triac, la cuestión es que todo trabajo como debería!
Pero ahora quiero agregar unas líneas de códigos para mostrar cierta información por una pantalla LCD y al agregar esas líneas de códigos veo que el ciclo útil y por consiguiente la onda se distorsiona como si el delay aplicado se modificara :eek::cry:
Acá dejo una imagen con el problema detallado, agradecería su ayuda, como siempre me han sabido dar respuesta a este tipo de situaciones.

Antes:
Código:
A var byte
i var byte
TRISB = %00000010
DEFINE ADC_BITS 8 ' Define la conversión A/D a 8 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
Inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
if portb.1=1 then call triac
goto inicio

Triac:
call delay
high portb.0
pause 1/100
low portb.0
return

Delay:
for i=0 to A
pause 324/10000
next
return


DESPUES:
Define    LCD_DREG    PORTD
Define    LCD_DBIT    0
Define    LCD_RSREG    PORTD
Define    LCD_RSBIT    4
Define    LCD_EREG    PORTD
Define    LCD_EBIT    5
A var byte
i var byte
TRISB = %00000010
TRISD = %00000000
DEFINE ADC_BITS 8 ' Define la conversión A/D a 8 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
lcdout $fe,1
Inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOUT "Grados de desf: " ' Muestra mensaje en la línea 1
LCDOUT $fe,$C0," ",dec A/100," " ' Muestra dato en la línea 2
if portb.1=1 then call triac
goto inicio

Triac:
call delay
high portb.0
pause 1/100
low portb.0
return

Delay:
for i=0 to A
pause 324/10000
next
return
 

Adjuntos

  • foroantes.jpg
    foroantes.jpg
    167.6 KB · Visitas: 7
  • forodespues.jpg
    forodespues.jpg
    162.8 KB · Visitas: 7
Para ese tipo de problemas "biene corriendo en caballo blanco las interrupciones".
Ya que los "tiempos se crusan" para el retardo y los tiempos del LCD, se puede utilizar una de las interrupciones temporizadas para el disparo de TRIAC, y asi la rutina pricipal se ocuparia del LCD.
Puedes crear un tiempo base de 0.1 ms, asi tendias resolucion de 1% para un semiperiodo de 10ms.
 
Las líneas del LCD se ejecutan durante el tiempo, éste tiempo se suma y es muy provable que que el PIC pierda pulsos del cruce por cero. Opciones:

A) Puedes ajustar los delays para que vuelva a trabajar correctamente... pero el problema es que si quitas o agregas más líneas de código, estas van a sumar tiempo dando el mismo inconveniente.
B) Capturar el cruce por cero por interrupción y controlar al triac en la interrupción...
 
Ok, lo haré por la segunda opción, una interrupción por flanco alto.
Te cuento después como me va.

---------- Actualizado después de 1 hora ----------

Lo hice por el método que me dijiste. ¿Se supone que debería ocurrir esto, no?
Pasa por cero la onda y se interrumpe el programa, antes de que continué todo hago un retardo dependiendo de la posición donde este el potenciómetro, después que sale de la interrupción debería mandar el pulso.

Código:
A var byte
i var byte
TRISB = %00000001
DEFINE ADC_BITS 8 ' Define la conversión A/D a 8 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
on interrupt goto Int
INTCON = %10010000
OPTION_REG.6 = 0

Inicio:
call triac
goto inicio

Triac:
call delay
high portb.1
pause 1/100
low portb.1
return

Delay:
for i=0 to A
pause 324/10000
next
return

Int:
disable
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
call delay 
INTCON = %10010000
enable
resume

end
Lo que está ocurriendo es que veo solo pulsos que no cambian con el tiempo indiferentemente de la posición del potenciómetro, no se ve ninguna onda de salida.
 
Me referia a poner la rutina que controla al triac cuando sucede la interrupción, es decir que, se supone que el cruce por cero es el que manda, por lo tanto el PIC deberia de responder inmediatamente cuando hay flanco activo.

Algo asi:

Código:
Inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
' Otro delay...
' Más cosas
goto inicio

Delay:
for i=0 to A
pause 324/10000
next
return

Int:
disable

call delay
high portb.1
pause 1/100
low portb.1

INTCON = %10010000
enable
resume

end

Con eso la variable A se mantiene actualizada siempre (o también se puede actualizar en la interrupción), luego es usado en la interrupción cuando hay flanco.

Saludos
 
Estoy tratando de hacerlo por ese medio y de hecho estoy verificando la secuencia de las instrucciones con unos leds que conecté, pero al momento que ocurre el flanco alto en rb0 que pasa a la subrutina de interrupción el proteus se vuelve loco y no sale de la subrutina, sino que manda un montón de mensajes de "Stack overflow executing call instruction".

Logré solventar el problema quitando la instrucción call y colocando directamente la rutina.
¿Realmente no sé por qué ocurre eso? Otra cuestión, volví a colocar el código con mis líneas para el LCD y pasa lo mismo que te había comentado.
Anexo la imagen y el código:

Código:
Define    LCD_DREG    PORTD
Define    LCD_DBIT    0
Define    LCD_RSREG    PORTD
Define    LCD_RSBIT    4
Define    LCD_EREG    PORTD
Define    LCD_EBIT    5

A var byte
i var byte
TRISB = %00000001
DEFINE ADC_BITS 8 ' Define la conversión A/D a 8 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
on interrupt goto Int
INTCON = %10010000
OPTION_REG.6 = 0

Inicio:
ADCIN 0, A 
LCDOut $fe, 2 
LCDOUT "Grados de desf: " 
LCDOUT $fe,$C0," ",dec A/100," "
goto inicio

Triac:
call delay
high portb.1
pause 1/100
low portb.1
return

Delay:
for i=0 to A
pause 324/10000
next
return

Int:
disable
for i=0 to A
pause 324/10000
next
high portb.1
pause 1/100
low portb.1
INTCON = %10010000
enable
resume

end
 

Adjuntos

  • problema LCD.jpg
    problema LCD.jpg
    160.5 KB · Visitas: 2
mmm aquí me quedo, no estoy seguro pero por el comportamiento que describes es posible que las instrucciones para el LCD desactiven temporalmente las interrupciones... porque? puede que tenga como preferencia el envio de datos al LCD... veré si hay info al respecto o como configurar o si se me ocurre otra forma de tratar la lógica... pero parece que PicBasic se queda corto para lo que pretendes...

Sobre call, puede que pierda la dirección de retorno de la pila, por eso hay esos avisos... esto ya es cosa del compilador... pero intenta con GoSub...

Saludos.
 
ah, ya en otro tema estaba hablando con un compañero y me habia recomendado algo referente a interrupciones pero de manera diferente a como la estoy trabajando, quizas sabes a lo que me refiero, es de hacer uso de la interrupcion para que en ese tiempo trabaje con los triacs y mientras que no haya interrupcion trabaje con el LCD, pero no entendi muy bien..
 
Se deben priorizar procesos, en tu caso la prioridad es el manejo del triac y despues el LCD, usa las INTs para la deteccion del cruce por cero y disparo del triac.
 
asi es como esta configurado compañero, la interrupcion se genera cuando pasa por cero, se hace un delay para luego disparar el TRIAC y sale de la interrupcion para volver al main; según el resultado que obtengo esa no es la manera compañero.. :confused:
 
Estas seguro que entre 2 pulso de cruce por cero podes hacer el manejo del LCD?? por ahi podes tener tu problema, debes segmentar el manejo del LCD, que muestras en el LCD??
 
Atrás
Arriba