TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: omibaya en 09 de Diciembre de 2005, 20:40:00
-
Amigos, tengo una pregunta, estoy usando un 16f877, con un lcd controlado por i2c, pero quiero controlar la intensidad de un foco, el problema es que el cruce por cero lo estoy poniendo por RB0 como una interrupcion, por lo tanto esta llega cada 8.33ms(medio ciclo de 60 hz) y me parece que el tiempo es corto, y a veces me corta los datos que aparecen en mi lcd, como puedo hacer para que no afecte, tal vez hacer esto con un pic16f84 que sea el que reciba la interrupcion? creen que hay otra manera?
-
Hola, si quieres regular la intensidad de un foco/bombilla prueba con una señal PWM, de esta manera podras controlar la cantidad de energia que le llega en cada momento a el foco.
No se como tienes el programa configurado de todas las maneras, pero si tu escribes en I2c y te viene una interrupcion por RB0 no deberias tener problema en el retorno de la interrupcion (creo yo, si no que me corrija algun otro compañero), y seguiria el micro por donde lo habia dejado.
Un saludo.
-
Creo que lo del PWM no le servirá porque el foco trabaja en alterna.
Ciertamente necesitarás detectar el cruce por 0 para activar el foco en la parte de la onda que te convenga.
Respecto a que la interrupción te corte la transmisión I2C, me resulta extraño que te afecte, pero dependerá de la velocidad a la que tengas trabajando el micro, de la velocidad que necesite el I2C y del tiempo que dure la interrupción del foco.
Sólo se me ocurre que habría que analizar eso para ver si tu micro puede atender la interrupción externa y continuar el I2C por donde fuera sin problemas.
Todo eso salvo que algún forista aporte una solución mejor.
-
Podría valer que lo único que hicieses en la interrupción pfuese poner un flag definido por tí mismo a 1 y vayas comprobando su valor para actuar en consecuencia ya fuera de la rutina de interrupción y en los puntos del programa en los que no sea crítico para la comunicación i2c,así no gastas demasiado tiempo dentro de la interrupción y el i2c puede mantener su temporización
-
Brillante
-
Manolo supongo que Xerex se refiere a un pwm por software con algún TMR, no con el módulo hardware, con el cual no se consigue llegar al Dutymax de los 10ms (50Hz en España).
Yo támpoco creo la interrupcion afecte a la escritura en la LCD.
Un saludo
-
hola, cuando hablaba de PWM siempre habia supuesto que estabamos hablando de alterna con lo del foco, la idea no es de utilizar una resolucion "infinita" como puede ser la temporizacion del pwm del micro, sino, al atacar a un triac, poder hacer que se dispare ciertos semiciclos de la señal de la red electrica, asi con un triac podriamos hacer que se encendiera desde un semiciclo a los 100 semiciclos para una señal de 50 Hz, controlando estos mediante el disparo del triac. las condiciones del pwm seria la de frecuencia de 50 Hz (idem red electrica) y el pwm minimo de 10 ms y el maximo 1 segundo con resolucion de 10 ms como dide pocher.
Aunque se puede hacer de mas formas para variar la intensidad del foco, utilizando la interrupcion externa activada por un detector por paso por cero de la red electrica y contando, podemos hacer que el foco, este funcionando unos determinados ciclos de señal alterna y otros no, asi no necesitar temporizar nada y harias un pseudoPWM jeje. Cuestion de gustos. Un saludo.
-
Ah, ahora sí te he entendido.
¿Y has probado eso, Xerex?. Es que sospecho que se notaría algún parpadeo, esa frecuencia es muy lenta.
De todas formas, la idea es buena, así que lo probaré cuando pueda.
-
Vaya una forma nueva que desconocía. Yo me refería a con un temporizador controlar el tiempo que la señal deseamos que esté a 1 dentro de los 10ms (semiperiodo), de esa forma se obtiene un control muy fino sobre la potencia de salida.
Probaré que tal resulta el método que propone Xerex de ir cargandose entre 1 y 100 semiciclos para controlar la luminosidad.
-
hombre! probarlo no lo he probado, hice algo similar en alguna practica en el instituto, pero en ese caso el disparo de un triac lo controlaba una red RC con un diac...
, deberia funcionar, tambien podemos intentar hacer que envez de que sea tan largo el tiempo hacerlo mas pequeño, recordamos que el filamento de un foco/bombilla tarda un poco en volver a la temperatura ambiente, podemos utilizar este efecto para controlar la intensidad luminosa del foco.
Osea podemos controlar envez de 1 segundo en menos tiempo, esto tambien seria valido, por ejemplo en 0.5 segundos o en 100 ms pero cuanto menos tiempo tengamos menos "resolucion de la intensidad luminosa" tendremos, para averiguarlo, lo mejor el experimento. Tambien os recuerdo que el ojo humano puede distinguir hasta 16 fotogramas por segundo por tanto a frecuencias menores a 16 Hz podria llegar a distinguir el ojo humano, pero como he dicho antes, la atenuacion de la bombilla cuando se desactiva el paso de corriente por ella es "lento" y nos puede valer ese fenomeno para controlar su intensidad. OJO, SIEMPRE ESTOY HABLANDO DE FOCOS/BOMBILLAS DE INCANDESCENCIA!!!!
Un saludo.
-
Si no se controla la potencia en un semiciclo, y se eliminan varios semiciclos se nota el parpadeo.
-
amigos, a lo que me refiero, es que pasa si justo en plena transmision de i2c llega la interrupcion externa o cualquier interrupcion?, lo que me ha sucedido es que la transmision se corta para dar paso a la interrupcion, lo del cruce por cero lo solucioné con un pic16f84, a este le mandaba el cruce por cero, pero no me acrode que tengo otra interrupcion int_rda porque pido los datos por la computadora, esto lo hago mas o menos cada segundo, yo supongo (porque no lo he probado aun) que tal vez no me genere mucho problema, pero si me da problemas como hagooooooooooooo
-
Bueno ya que tienes que hacer varias cosas, porque no optas por montar un sistema operativo para el pic???? supongo que vendran con multitarea y no te interferira entra todas las cosas que tienes que hacer y probablemente te funcione correctamente ... es una posible solucion, en cuanto a lo de los sistemas operativos no puedo ayudarte porque nunca he trabajado con ellos.
Si al final desechas la idea anterior, prueba ha hacer una red de micros con uno como master y los demas como slave, y a cada uno le haces que haga una tarea.
Saludos.
-
Hola como estan decenadoles a todos un feliz año por favor me pueden ayudar con eso de la interrupcion apra el detector de cruce por cero por que en verdad no le entiendo muy bien como utilizar las interrupciones, lo que necesito es hecer un detector de cruce por cero con el pic 16f877 o el 16f872 tengo el siguiente codigo pero se me dispara en todo el semiciclo negativo y la verdad no se que esta mal les publico el codigo por favor ayudenme que no se que esta mal..........
#INCLUDE <16F876A.H>
#FUSES XT, NOWDT, PROTECT, NOPUT, NOBROWNOUT, NOLVP
#USE DELAY (CLOCK = 4000000)
int j=1;
void main()
{
signed int t;
set_tris_b(0x01);
while(1)
{
t=input(PIN_B0);
if(t==0)
{
{
if (j==0)
{
//output_high(PIN_B1);
j=1;
ext_int_edge(H_TO_L); // Cambio la detección del flanco, para que la
} // proxima sea de bajada
else if(j==1)
{
//output_low(PIN_B1);
j=0;
ext_int_edge(L_TO_H); // La próxima interrupción será de subida
}
}
output_high(PIN_B1);
delay_us(10);
output_low(PIN_B1);
delay_us(10);
t=0;
}
}
}
cualquier ayuda por favor que la verdad no le entiendo bien
-
Vamos a ver, en tú código no hay ninguna interrupción, cosas raras que veo:
1. Pones un corchete extra en la siguiente instrucción, uno de ellos sobraría.
Para la interrupción externa, te recomiendo que veas el post de Ejemplitos en C para 16F648A (http://www.todopic.com.ar/foros/index.php?topic=4530.0), concretamente el número 40.
Suerte!!! ;)
-
gracias ya hice ese cambio pero tampoco... funciona en el flanco de bajada pero se repete todo el fanco en que el voltaje es negativo el pulso se da 8 veces en el semiciclo
-
Me da la impresión que parte de ese código está extraído de mi proyecto "Dimmer con mando".
Si te fijas, la función original que yo utilicé, y que pego a continuación, está precedida por el literal #INT_EXT. Esto significa que la función se ejecutará cada vez que salte la interrupción externa, o lo que es igual, cada vez que el PIC detecte en ese pin un flanco de bajada (si está en H_TO_L) o un flanco de subida (si está en L_TO_H).
/****************************************************************************/
/* El ciclo del TRIAC comienza de nuevo con cada cruce por 0 */
/* por ello en la interrupción externa se pone a 0 la cuenta de PasosDimmer */
/* y se cambia la detección de flanco de la entrada */
/****************************************************************************/
#INT_EXT
void CrucePor0()
{
PasosDimmer=0;
if (j==0){
j=1;
LED_VERDE=1;
LED_ROJO=1;
ext_int_edge(H_TO_L); // Cambio la detección del flanco, para que la proxima sea de bajada
}
else {
j=0;
LED_VERDE=0;
LED_ROJO=0;
ext_int_edge(L_TO_H); // La próxima interrupción será de subida
}
}
Esta función es francamente optimizable y en ella se pueden observar defectos que cometí debido a mi bisoñez con los PIC, como el uso de la variable j, pero te puedo garantizar que funcionaba perfectamente.
-
que tal nocturno pedes por favor explicarme que significa el
PasosDimmer=0;
LED_VERDE=1;
LED_ROJO=1;
por que la verdad no se a que pines o varibles estan asignadas
-
Son variables / pines indiferentes para la detección del cruce por cero, por lo que puedes eliminarlas.
-
gracias men se te agradece un monton ya funciono el detector de cruce por cero otra cosita me puedes po favor enviar el codigo del dimer por que lo e pasado buscando y en todos lados y no lo e encontrado te lo agracedería un monton si puedes publicalo en este gran foro o si no ponlo en algun lado para descargarlo xp en la pagina del rebijito no vale descargarlo te agradecería un monton
-
Está publicado en la zona de Descargas de El Rebujito (http://www.elrebujito.es/modules.php?name=Downloads), sección Proyectos, Dimmer con Mando:
http://www.elrebujito.es/modules.php?name=Downloads&d_op=viewdownload&cid=18
Me alegro que lo hayas resuelto.
-
muchas gracias estaremos en contacto y feliz año nuevo se les agradece un monton :-/ :-/ :-/ :-/
-
hola alguien me puede decir como varian las varibles int , char, float, double y long en piccsc y cuales son los rangos maximos para las variables
-
hola, el detector de cruce por cero es un buen método para variar la potencia de salida disparando a un triac en cada semiperiodo de la señal alterna, yo también lo he probado y me ha funcionado.
Hay que tener cuidado cuando se dispara al triac en la zona cercana a 180 grados, por ejemplo si se le dispara justo en los 180 grados y la frecuencia de la alterna es 60.1Hz, entonces se estaría disparando en la parte negativa y con la máxima potencia, lo que hize en ese caso fue dispararlo hasta los 179 grados como máximo.
Otra forma para controlar la potencia de una carga es mediante el PWM, convirtiendo primero la señal alterna 220v en continua 220*1.41 aprox. (un poco menos), y luego utilizando un transistor de potencia hacerlo commutar con la señal de PWM del PIC.
El periodo será fijado al inicio del programa y el ancho de pulso determinará la potencia que se le entrega a la carga, de esta forma las interrupciones de cruce por cero no afectarán él trabajo del módulo I2C.
-
Para ver el rango de las variables, pasate por la página web de la empresa CCS (http://www.ccsinfo.com/) y descargate el manual]http://www.ccsinfo.com/downloads/ccs_c_manual.pdf]descargate el manual (http://www.ccsinfo.com/downloads/ccs_c_manual.pdf) y en DATA DEFINITIONS está lo que buscas.
Suerte!!! ;)
-
hola a todos miren quiero crear una señal de 120Khz por el pin B1 con el pic y tengo el siguiente codigo pero no funciona alguien me puede ayudar por que la verdad no se que esta mal...........
#INCLUDE <16F876A.H>
#FUSES XT, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP
#USE DELAY (CLOCK = 4000000)
int j=1;
#INT_EXT
void IntRB0()
{
delay_ms(2);
output_high(PIN_B4);
delay_ms(1);
output_low(PIN_B4);
if (j==0)
{
j=1;
ext_int_edge(H_TO_L);
}
else if(j==1)
{
j=0;
ext_int_edge(L_TO_H);
}
x++;
}
#INT_RB
void RB4()
{
output_high(PIN_B1);
delay_us(4);
output_low(PIN_B1);
delay_us(4);
}
void main()
{
enable_interrupts(INT_EXT);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
set_tris_b(0x01);
while(1)
{
}
}
-
El código que has pegado se parece bastante a un código de lectura de la señal, no al de generación de la misma.
Te aconsejo que eches un vistazo al módulo CCP del PIC que permite generar PWM de distintas frecuencias y seguramente servirá para lo que quieres.
-
pero el pwm trabaja en todo el timepo o existe alguna manera de controlar cuando se activa por que lo que yo necesito es que solo en un milisegundo se ejecute la frecuencia de 120Khz por otro pin de salida
-
Tú puedes activar y desactivar cuando quieras.