Formulas DMX de multiplicacion y division en AVRstudio lenguaje C

Bueno .,he estado buscando info en internet hace tiempo​
pero muchos datos no he encontrado ., el caso es que vi ejemplos en bascon y asm​
pero nada para C .,tampoco ejemplos validos de guiá para DMX​
Lo que si encontré son las formulas que usan en C pero en los pic (supongo que son iguales o que se pueden aplicar)​
EJEMPLO master RGB:[/LEFT] ch = ch *dim / 255 seria asi (creo)if ((DmxRxField [0] * DmxRxField [3]) / 255> PWM_timer)//rojo y el strobo [/LEFT] ch = timer *ch*4 seria asi (creo) if(strobo_timer>(255-DmxRxField[4]) *4)
yo hice un burdo intento de compilar ., tengo demasiados errores​
esta es mi configuración de timer​
PHP:
  // ***** inicializacion del timer****//
void init_timer(){
		TCCR0|= (1<<CS02) ;	// Precontador 256
		TIMSK|= (1<<TOIE0);	// desbordamientos de la interrupción
		TCNT0= OV_SIZE;		
}
// Restablecer el temporizador
void reset_timer(){
		TCNT0= OV_SIZE;	// Worth ?? comenzando Contador inicial
		timer_counter=0;
esto es lo que arme (no me funciona)​
PHP:
                                                                                                                               enum strobo{ON=1,OFF=0};   //Strobe permite o no permite 
	strobo=ON;                 // La conexión ?? iluminación stroboscopica habilitada
	int strobo_timer=0;    // Contador Strobe
	while(1)		// bucle central principal	
	{
	 get_dips();    // Comprobar dip-switch y descargar la dirección DMX
		for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // bucle PWM a aplicar a través de una serie de relleno
		{												
				
			if (DmxRxField[0]>PWM_timer)		//ROJO	
			{
				PORTB &= ~(1<<PB0);				//LED OFF (APAGADO)
			}else{
				PORTB |= (1<<PB0);				//LED ON  (ENCENDIDO)		
			}
 
			if (DmxRxField[1]>PWM_timer)		//VERDE
			{
				PORTB &= ~(1<<PB1);				//LED OFF (APAGADO)				
			}else{
				PORTB |= (1<<PB1);				//LED ON  (ENCENDIDO)
			}
    
			if (DmxRxField[2]>PWM_timer)		//AZUL    
			{
   			    PORTB &= ~(1<<PB2);				//LED OFF (APAGADO)					
			}else{
				PORTB |= (1<<PB2);				//LED ON  (ENCENDIDO)
			}																																									
		 // ------------- Apoyo estroboscópica 
		if(DmxRxField[4]>0){	// si el canal Strobe = 0  siempre ., led encendido normales ., lo contrario  luz estroboscópica
		if(strobo_timer_count>(255-DmxRxField[4]) *4) // La multiplicación por 4 retarda el tiempo estroboscópica 1 - tiempo máximo , 255 - min Tiempo
				strobo_timer_count=0;               // Cambiar el estroboscopico temporizador ?
                strobo=0 ;    strobo=ON;  // Cambiar ., habilitacion strobo
    
			}else{
            strobo_timer++;
              }
		    }else{
			strobo=1;	// Strobe apagado	
		     }
 
		// -------------------- PWM LED
		//for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop explican que muestra un ciclo de llenado
		{
			if (( (DmxRxField[0]*DmxRxField[3])/255>PWM_timer) & strobo)	//red 																						
			{
				PORTB &= ~(1<<PB0);				//LED OFF
			}else{
				PORTB |= (1<<PB0);				//LED ON		
			}
 
			if ( ((DmxRxField[1]*DmxRxField[3])/255>PWM_timer) & strobo)  //green														
			{
				PORTB &= ~(1<<PB1);				//LED OFF				
			}else{
				PORTB |= (1<<PB1);				//LED ON
			}
 
			if ( ((DmxRxField[2]*DmxRxField[3])/255>PWM_timer) & strobo)	//blue																																														
			{
				PORTB &= ~(1<<PB2);				//LED OFF					
			}else{
				PORTB |= (1<<PB2);				//LED ON
			}
me gustaria ir desglosando poco a poco las funciones ., asi aprendo​
aca tengo un ejemplo de lo que funciona ., pero tiene los timer distintos .,y ami no me funciona .,​
PHP:
// Temporizador 0 Contador de tiempo de interrupción DMX y PWM
	TCCR1A |= (1<<WGM01);
	TCCR1B |= (1<<CS00);
	TIMSK |= (1<<OCIE1A);
	OCR1A = F_OSC/1024/100 - 1; // Marque 1 ms
aca los enuciados de dicha cabecera​
PHP:
	unsigned long strobe_counter = 0;
	unsigned char tmp1,tmp2,tmp3;
aca el ejemplo de C​
PHP:
if(dmx_lost==DMX_LOST_TIMEOUT)
		{
			dmx_buffer[1] = 0;
			dmx_buffer[2] = 0;
			dmx_buffer[3] = 0;
			dmx_buffer[4] = 0;
		}
		
		tmp1 = dmx_buffer[1]*dmx_buffer[4]/255;
		tmp2 = dmx_buffer[2]*dmx_buffer[4]/255;
		tmp3 = dmx_buffer[3]*dmx_buffer[4]/255;
		
		
		if(dmx_buffer[5]<10)
		{
			led_kanal[0] = tmp1;
			led_kanal[1] = tmp2;
			led_kanal[2] = tmp3;
		}
		else
		{
			strobe_counter++;
			if(strobe_counter > (256 - dmx_buffer[5]))
			{
				led_kanal[0] = tmp1;
				led_kanal[1] = tmp2;
				led_kanal[2] = tmp3;
			}
			else
			{
				led_kanal[0] = 0;
				led_kanal[1] = 0;
				led_kanal[2] = 0;
			}
			
			if(strobe_counter > (2 * (256 - dmx_buffer[5])))
			{
				strobe_counter = 0;
				led_kanal[0] = 0;
				led_kanal[1] = 0;
				led_kanal[2] = 0;
			}
		}
	}
}
 
Última edición:
Loco, es más sencillo que hagas preguntas puntuales, sobre los errores de compilación que te fue dando.

Por ej. de esto:

Código:
strobo=ON;                 // La conexión ?? iluminación stroboscopica habilitada
    int strobo_timer=0;    // Contador Strobe
    while(1)        // bucle central principal    
    {
     get_dips();    // Comprobar dip-switch y descargar la dirección DMX
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // bucle PWM a aplicar a través de una serie de relleno
        {                                                
                
            if (DmxRxField[0]>PWM_timer)        //ROJO    
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)        
            }
 
            if (DmxRxField[1]>PWM_timer)        //VERDE
            {
                PORTB &= ~(1<<PB1);                //LED OFF (APAGADO)                
            }else{
                PORTB |= (1<<PB1);                //LED ON  (ENCENDIDO)
            }
    
            if (DmxRxField[2]>PWM_timer)        //AZUL    
            {
                   PORTB &= ~(1<<PB2);                //LED OFF (APAGADO)                    
            }else{
                PORTB |= (1<<PB2);                //LED ON  (ENCENDIDO)
            }                                                                                                                                                                    
         // ------------- Apoyo estroboscópica 
        if(DmxRxField[4]>0){    // si el canal Strobe = 0  siempre ., led encendido normales ., lo contrario  luz estroboscópica
        if(strobo_timer_count>(255-DmxRxField[4]) *4) // La multiplicación por 4 retarda el tiempo estroboscópica 1 - tiempo máximo , 255 - min Tiempo
                strobo_timer_count=0;               // Cambiar el estroboscopico temporizador ?
                strobo=0 ;    strobo=ON;  // Cambiar ., habilitacion strobo
    
            }else{
            strobo_timer++;
              }
            }else{
            strobo=1;    // Strobe apagado    
             }
 
        // -------------------- PWM LED
        //for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop explican que muestra un ciclo de llenado
        {
            if (( (DmxRxField[0]*DmxRxField[3])/255>PWM_timer) & strobo)    //red                                                                                         
            {
                PORTB &= ~(1<<PB0);                //LED OFF
            }else{
                PORTB |= (1<<PB0);                //LED ON        
            }
 
            if ( ((DmxRxField[1]*DmxRxField[3])/255>PWM_timer) & strobo)  //green                                                        
            {
                PORTB &= ~(1<<PB1);                //LED OFF                
            }else{
                PORTB |= (1<<PB1);                //LED ON
            }
 
            if ( ((DmxRxField[2]*DmxRxField[3])/255>PWM_timer) & strobo)    //blue                                                                                                                                                                                        
            {
                PORTB &= ~(1<<PB2);                //LED OFF                    
            }else{
                PORTB |= (1<<PB2);                //LED ON
            }

Es díficil saber error sin saber lo que te tira el compilador, ya que es muy probable que tengas variables que nunca declaraste o incluso estados como el "ON" que nunca definiste, o por lo menos en ese tramo de código se vé eso.

Deberías reducir el código de a pedazos e ir compilando de a poco, es decir:

Código:
strobo=ON;                 // La conexión ?? iluminación stroboscopica habilitada
    int strobo_timer=0;    // Contador Strobe
    while(1)        // bucle central principal    
    {
     get_dips();    // Comprobar dip-switch y descargar la dirección DMX
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // bucle PWM a aplicar a través de una serie de relleno
        {                                                
                
            if (DmxRxField[0]>PWM_timer)        //ROJO    
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)        
            }
 
           ......//quitar todo ese código e ir probando
       }
   }

Lo que te recomiendo es que si querés programar, empezá con algún libro o algo que te sirva de base y con cosas básicas, yo entiendo que estás tratando de "recauchutar" el código que encontraste, pero para hacerlo hay veces que se necesita saber donde metés mano. Además no solo está el tema de saber programar, sino saber como usar el hard de la familia de uC que usas. Por eso, en ese caso si querés resultados rápidos, lo ideal es conseguir algo ya hecho para la familia de uC que estás usando.

De todo ese código que pasaste, hay muchas cosas que quedan en el aire y cuesta mucho responderlas.
 
Hola y gracias por responder​
si querido amigo ., estoy aprendiendo ., y a medida que voy comprendiendo las cosas y su funcionamiento​
me doy cuenta que en DMX hay muy poco material para aprender​
He buscado y traducido varios tutoriales de ASM y C (alemanes y ingles) están por aca https://www.forosdeelectronica.com/posts/1004709/​
no los publico en los post para no infringir los derechos de autor​
y con respecto a eso te doy el ejemplo claro ., la USART ¿¿¿¿ te acordás del problema de la habilitación de recepción ?????​
bueno ., todos los tutos y ejemplos de uso son para 9600Baud y aca se usa 250kBaud y dos bit de parada​
y si te acordás de la famosa habilitación de señal ., (que muy pocos usan) y es tan importante., ese error yo no sabia como explicártelo​
De eso no hay tutos o libros., tampoco es valido los ejemplos ., el tratamiento de la señal es distinta​
yo lo que hago es reformar y adaptar los ejemplos que encuentro .,y en algunos casos agregarle funciones (esto es algo de eso)​
los dos ejemplos que te indique los hice yo solo ., la de los led ., no funcionaba​
después de arreglarla ., le agregue dos motores pap ., con micro pasos​
luego le adapte dos motores de DC y lo ultimo que logre son dos motores DC y un pap ( todos con los led obviamente)​
Acá desde el vamos tengo que cambiar lo el timer del PWM si quiero que me trabaje el STROBO.,​
(con que sea simple me conformo) como no es un flash ., no hay problema​
bueno aca te muestro los errores del compilador​
capture_04262015_150116.jpg
LAS indicaciones que me dieron con respecto a eso son estas (traducidas del polaco al castellano)​
Código:
 El archivo de cabecera es la definición:
PHP:
volatile uint8_t	 DmxRxField[8];  //array of DMX vals (raw)
Código:
 y en la biblioteca de recepcion siempre se comprueba el tamaño:
PHP:
 if (DmxCount >= sizeof(DmxRxField)) //all ch received?
Código:
Eso es muy fácil cambiar el tamaño del canal de lectura. En este caso, la lectura de 8 canales. Incluso demasiado, sólo 5

Dimmer master va a ser fácil de hacer. Supongamos que se CH3 (contando desde 0).
DmxRxField [3] = canal masterl dimmer. En el bucle principal, tiene que cambiar 3 condiciones:
PHP:
 if (DmxRxField[0]>PWM_timer)//red
Código:
para que el valor se redujo por un factor de DmxRxField [3]
PHP:
if ((DmxRxField[0]*DmxRxField[3])/255>PWM_timer) //red
Código:
Strobe es un poco más complicado. Usted tendrá que ganar algo de tiempo extra ., otra condición - tiempo. Esto se puede hacer en el temporizador, o en un bucle. Sería mejor en el temporizador, ya que no se sienta el tiempo de estroboscópica, y esto se puede programar (PWM) sin usar el PWM del hardware.

Aproximadamente seria como a continuación. No estoy seguro de si algo esta mal .,porque escribí solo de memoria , pero no tengo el equipo para comprobar.

Ch0 - Rojo
CH1 - Verde
CH2 - Azul
CH3 - master dimmer
Ch4 - Strobe, 0 = apagado, 1 el tiempo más largo, 255 el menor tiempo                             


El cuidado de otras soluciones parecen razonables para aumentar el alcance de la exención estroboscópica 0 a 10 con el fin de evitar el parpadeo accidental cuando los potencimetros virtuales , donde un pequeño movimiento cambia el valor del control deslizante. Con los controladores del ordenador no debe ser un problema.
Condición :
PHP:
(255-DmxRxField[4]) *4)
Código:
tiene como objetivo extender el tiempo mínimo que el estroboscopio.   Este parámetro debe ser elegido por la prueba. Esto dependerá de la frecuencia del oscilador.  Estoy en el reloj de 8 MHz de reparación de la izquierda, pero sería aumentar el reloj a 16MHz. Esto aumentará la velocidad PWM - será menor a parpadear en pequeños valores de DMX especialmente después de lista de control prolongado del bucle principal.
Bueno con eso mas o menos explico la única respuesta atendible que encontré ., he buscado bastante ., te lo aseguro ., ni siquiera en AVRfreak me contestaron (solo tonterías sin valor ., de aprendizaje) http://www.avrfreaks.net/forum/add-channel-master-and-strobe-compile-atmega-8515
lo que no logro descifrar es el timer para el strobo ., y lo otro es el valor "virtual" de DmxRxField [3]​
porque sin el valor de DmxRxField [3] no tengo atenucion porque falta un valor para la división​
el efecto es que los led siguen prendidos ., aunque se atenuan individualmente​
el motivo del master dimmer es la atenuacion de un color concreto .,o mezcla de los tres ejemplo violeta (rojo+azul)​
 
Última edición:
Para empezar, el error que te tira es que la variable strobo no está declarada en ningún lado, tenés que indicar que tipo de variable es y si es necesario inicializarla con un valor de arranque.

Luego el otro error se debe a que tenés un "else" en el aire, el "else" va acompañado siempre del "if", ejemplo:

Código:
if(....condicion...)
{
  .... se cumple la condición, ejecuta lo que está dentro de las llaves...
}
else
{
  .... no se cumple la condición, ejecuta esto otro que está dentro de la llaves..
}

En tu caso se vé, que en alguna parte del código te quedó:

Código:
...
else
{
  .... no se cumple la condición, ejecuta esto otro que está dentro de la llaves..
}

Lo cual es obvio que está mal.

Editado:

Para salvar lo de la variable, reemplazá esto:

Código:
...
enum strobo{ON=1, OFF=0};
...

Por esto:

Código:
...
typedef enum {ON=1, OFF=0} variable_tipo_strobo;

variable_tipo_strobo strobo=ON;
...

Por cierto, nunca usé el enum en C, fijate si funciona.
 
Última edición:
A mi me da resultado (a veces) interpretar el significado en castellano de la instrucción.

Por ejemplo "Else" se traduce como: "De otro modo" en sentido condicional.

Es decir una condición que hace "Algo" mientras es válida (Se cumplre la condición) y "Hace otra cosa" en caso de no cumplirse la condición (IF)
 
gracias amigo
Para empezar, el error que te tira es que la variable strobo no está declarada en ningún lado, tenés que indicar que tipo de variable es y si es necesario inicializarla con un valor de arranque.

Luego el otro error se debe a que tenés un "else" en el aire, el "else" va acompañado siempre del "if", ejemplo:

Código:
if(....condicion...)
{
  .... se cumple la condición, ejecuta lo que está dentro de las llaves...
}
else
{
  .... no se cumple la condición, ejecuta esto otro que está dentro de la llaves..
}

En tu caso se vé, que en alguna parte del código te quedó:

Código:
...
else
{
  .... no se cumple la condición, ejecuta esto otro que está dentro de la llaves..
}

Lo cual es obvio que está mal.
por supuesto esta dejado porque pensé en agregar ., los valores de accionamiento del strobo
es lo arme de acuerdo al ejemplo de arriba., pero si no configuro el timer del estrobo no tengo valor que poner en las condiciones​
si te fijas en el ejemplo que puse​
PHP:
if(dmx_buffer[5]<10)
        {
            led_kanal[0] = tmp1;
            led_kanal[1] = tmp2;
            led_kanal[2] = tmp3;
        }
        else
        {
            strobe_counter++;
            if(strobe_counter > (256 - dmx_buffer[5]))
            {
                led_kanal[0] = tmp1;
                led_kanal[1] = tmp2;
                led_kanal[2] = tmp3;
            }
            else
            {
                led_kanal[0] = 0;
                led_kanal[1] = 0;
                led_kanal[2] = 0;
            }
            
            if(strobe_counter > (2 * (256 - dmx_buffer[5])))
            {
                strobe_counter = 0;
                led_kanal[0] = 0;
                led_kanal[1] = 0;
                led_kanal[2] = 0;
            }
        }
    }
}
es este segmento de código if(dmx_buffer[5]<10)
(dmx_buffer) seria igual a DmxRxField misma funcion USART dise que es menor que <10​
eso es el valor tomado del timer_strobo desde aca unsigned long strobe_counter = 0;
donde yo supongo que es el valor arojado de TCCR1A |= (1<<WGM01);
o sea tengo que definir primero el timer del estrobo ., luego definir los parametros de trabajo que seria algo como esto o parecido if(dmx_buffer[5]<10) minimo y if(strobe_counter > (2 * (256 - dmx_buffer[5]))) maximo​
las funciones Temp1 .,Temp2 y Temp3 ., son para alojar los valores temporales que genera el Dimmer master (unsigned char tmp1,tmp2,tmp3) y que esta ejecutado aca tmp1 = dmx_buffer[1]*dmx_buffer[4]/255;
tmp2 = dmx_buffer[2]*dmx_buffer[4]/255;
tmp3 = dmx_buffer[3]*dmx_buffer[4]/255;
ese ejemplo del timer ami no me funciona ., es timer1 y yo uso timer0​
los ejemplos que encontré en la red son ASM (alli estoy muerto)​
pero pude comprobar que funcionan en lo físico., alli te lo paso ., proyecto completo y funciona perfectamente en el atmega8515​
 

Adjuntos

  • RGB-Fader-3 .0 español .rar
    56.4 KB · Visitas: 3
Última edición:
Bueno gente ., acá muestro mis primeras pruebas​
PHP:
	for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
		   
           
         {																	
				if (DmxRxField[0]>PWM_timer)		//ROJO	
			{
				PORTB &= ~(1<<PB0);	//LED OFF (APAGADO)
			}else{
				PORTB |= (1<<PB0);	//LED ON  (ENCENDIDO)		
			}
 
			if (DmxRxField[1]>PWM_timer)	 //VERDE
			{
				PORTB &= ~(1<<PB1);	//LED OFF (APAGADO)				
			}else{
				PORTB |= (1<<PB1); //LED ON  (ENCENDIDO)
			}
 
			if (DmxRxField[2]>PWM_timer)		//AZUL    
			{
				PORTB &= ~(1<<PB2); //LED OFF (APAGADO)					
			}else{
				PORTB |= (1<<PB2);//LED ON  (ENCENDIDO)
			}		
					
			
        for (master_timer=0;master_timer<255;master_timer++)
			if (DmxRxField[3]>master_timer)
																					
			{
            DmxRxField[0] = 0;
            DmxRxField[1] = 0;
            DmxRxField[2] = 0;
            DmxRxField[3] = 0;
                       }
        
        tmp1 = DmxRxField[0]*DmxRxField[3]/255;
        tmp2 = DmxRxField[1]*DmxRxField[3]/255;
        tmp3 = DmxRxField[2]*DmxRxField[3]/255;
Agregue estas sentencias en la cabecera (.C)​
PHP:
 volatile uint8_t master_timer = 0;
    unsigned char tmp1,tmp2,tmp3;
También le di inicio en el MAIN​
PHP:
int PWM_timer ; int master_timer;
Los problemas que tengo : no refleja., el valor del "potenciometro virtual"​
Ni tampoco atenuá el valor de los canales ., aunque los tres canales dimmerizan correctamente​
La señal DMX al uC ., llega correctamente y la refleja (indicador de señal de entrada) .,​
El comando (al parecer) funciona mal ., porque algo marca en los led (los tres) .,​
También ., no se si desarrollo ., el comando correctamente​
Acepto sugerencias ., o ideas como realizarlo​
 
A ver, nuevamente está todo muy en el aire, por lo tanto lo que te pueda responder tal vez sea cualquier cosa.

De lo que entendí de ese código es:

DmxRxField[0] => nivel del duty del color rojo (en este caso "podemos" decir duty = intensidad)
DmxRxField[1] => nivel del duty del color verde (en este caso "podemos" decir duty = intensidad)
DmxRxField[2] => nivel del duty del color azul (en este caso "podemos" decir duty = intensidad)

Hasta ahí vamos.

En el código pasas por un for que no se sabe bien como llegaste, ni que parte de la rutina principal representa, pero que dá a entender que en base a ese valor de "intensidad" activa o no lo leds, lo cual es lógico.

Dentro de ese for, hacés otro for (no entiendo el porque, tal vez se te escapó una llave que limita la acción del 1er for). En ese segundo for, obtenés tres valores temporales tmp1, tmp2 y tmp3 que no se sabe que uso le dás. Esos tres valores, dependen pura y exclusivamente del valor que hay en "DmxRxField[3]" (que no se sabe exactamente que es).

Pensá que lo que ví de DMX cuando te ayudé me lo re olvidé, este tipo de cosas deberían quedar claros en el mensaje si realmente querés que te puedan dar una mano.

Volviendo al problema:

locodelafonola dijo:
Los problemas que tengo : no refleja., el valor del "potenciometro virtual"
Ni tampoco atenuá el valor de los canales ., aunque los tres canales dimmerizan correctamente

Al parece los leds te funcionan bien, pero ¿en dónde es lo que no se refleja bien el valor de los canales y del potenciómetro virtual?

Nuevamente, pensá que estás dando información muy limitada donde no todos sabemos exáctamente lo que hacés, tratá de resumirlo lo más brévemente posible.
 
Bueno ante todo muchas gracias amigo ., y después mil disculpas
Me confié que te acordarías .,ese es mi error ., vamos a empezar de cero ., y viendo los problemas de a uno
El problema lo tengo en el canal 3 ., DmxRxField[3] y de ahora en mas ., sera la función MASTER DIMMER
La señal al uC llega perfectamente ., y al parecer tengo un valor "virtual"
Porque te digo esto ???? ., porque el led azul de la señal DMX correcta ., "parpadea" a la velocidad y movimiento ., del potenciometro virtual
Esto me indica que DmxRxField[3]., si tiene un valor dentro del uC
Si tomamos las formulas ., ejemplo ., la división en este caso ((DmxRxField[0]*DmxRxField[3])/255)., al parecer ., para que se cumpla me falta un valor
Si me falta un valor dentro de esa división ., obviamente la división no se cumple ., eso es desarrollado permanentemente ., dentro del bucle"while(1)"
Lo que hice arriba fue tratar de igualar o hermanar ., el valor virtual con uno definido dentro de la compilación
Si te fijas ., el canal 3 no tiene ., ningún valor comparativo o definido
Con respecto a ese valor ., tengo dudas ., no se si tiene que ser un valor de conteo (COUNT) o un valor del PWM
En si no tiene una salida definida ( led)., pero en realidad si la tiene (los tres led del conjunto)
Porque en realidad lo que tiene que hacer ., es dimerizar el conjunto ., ejemplo el color rosa : rojo 255 , verde 0 ,azul 128
DmxRxField[3] lleva esos valores a cero (atenuación de brillo/intensidad)

Y logicamente aumentarlo hasta su máximo brillo/intensidad ., sin cambiar el valor del color elegido
Aca te muestro lo que hice ., desde cero ., compila bien ., pero DmxRxField[3] no funciona o no hace nada dentro de la formula de división

PHP:
    while(1)                                    //
        {
        get_dips();        //

    
        //-------------------- PWM LED
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
           
           
         {                                                                                                                        
                if (DmxRxField[0]>PWM_timer)        //ROJO    
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)        
            }

            if (DmxRxField[1]>PWM_timer)        //VERDE
            {
                PORTB &= ~(1<<PB1);                //LED OFF (APAGADO)                
            }else{
                PORTB |= (1<<PB1);                //LED ON  (ENCENDIDO)
            }

            if (DmxRxField[2]>PWM_timer)        //AZUL    
            {
                PORTB &= ~(1<<PB2);                //LED OFF (APAGADO)                    
            }else{
                PORTB |= (1<<PB2);                //LED ON  (ENCENDIDO)
            }        
            if (DmxRxField[3]>master_count)        
            
         
            if ((DmxRxField[0]*DmxRxField[3])/255) //red
            {
                PORTB &= ~(1<<PB0);                //LED OFF
                }else{
                PORTB |= (1<<PB0);                //LED ON
            }

            if ((DmxRxField[1]*DmxRxField[3])/255) //green
            {
                PORTB &= ~(1<<PB1);                //LED OFF
                }else{
                PORTB |= (1<<PB1);                //LED ON
            }

            if ((DmxRxField[2]*DmxRxField[3])/255) //blue
            {
                PORTB &= ~(1<<PB2);                //LED OFF
                }else{
                PORTB |= (1<<PB2);                //LED ON
            }
 
No queda del todo claro la función de ese 3er canal. Al parecer funcionaría como un factor lineal que fuerza los otros canales.

Del código en si, te puedo tirar un par de pistas:

1- Cuando realizás la operación del mensaje anterior, ejemplo:

Código:
tmp1 = DmxRxField[0]*DmxRxField[3]/255; ...

No tenés en cuenta si hay overflow o no, ya que muy probablemente el vector DmxRxField sea del tipo "unsigned char".

Para solucionarlo podés emplear variables del tipo "unsigned short" o incluso "unsigned int". Con short debería alcanzarte, pero para asegurarte usá int:

Código:
unsigned int var_aux;
....
var_aux=DmxRxField[0];
var_aux=var_aux*DmxRxField[3];
tmp1 = var_aux/255;

var_aux=DmxRxField[1];
var_aux=var_aux*DmxRxField[3];
tmp2 = var_aux/255;

var_aux=DmxRxField[2];
var_aux=var_aux*DmxRxField[3];
tmp3 = var_aux/255;
...


2- Como te mencioné antes, una cosa es un if y otra una asignación. Realmente no se entiende que se pretende hacer. Por otro lado:

Código:
if ((DmxRxField[1]*DmxRxField[3])/255)

Estás preguntando sí "(DmxRxField[1]*DmxRxField[3])/255" es distinto de cero, de ser así, entra en el if; ¿eso es lo que estás buscando?
 
hola cosme ., bueno en realidad ., las temp 1 ,2 y 3 eran valores volátiles que quería guardar para usar en el strobo
Pero olvidate de eso ., el strobo funciona ., pero mal ., tal vez porque falta el valor de DmxRXField 3
Tranquilo amigo ., vamos por partes ., y de acuerdo a como se desenvuelve el bucle
No queda del todo claro la función de ese 3er canal. Al parecer funcionaría como un factor lineal que fuerza los otros canales.

Del código en si, te puedo tirar un par de pistas:

1- Cuando realizás la operación del mensaje anterior, ejemplo:

Código:
tmp1 = DmxRxField[0]*DmxRxField[3]/255; ...

No tenés en cuenta si hay overflow o no, ya que muy probablemente el vector DmxRxField sea del tipo "unsigned char".

Para solucionarlo podés emplear variables del tipo "unsigned short" o incluso "unsigned int". Con short debería alcanzarte, pero para asegurarte usá int:

Código:
unsigned int var_aux;
....
var_aux=DmxRxField[0];
var_aux=var_aux*DmxRxField[3];
tmp1 = var_aux/255;

var_aux=DmxRxField[1];
var_aux=var_aux*DmxRxField[3];
tmp2 = var_aux/255;

var_aux=DmxRxField[2];
var_aux=var_aux*DmxRxField[3];
tmp3 = var_aux/255;
...


2- Como te mencioné antes, una cosa es un if y otra una asignación. Realmente no se entiende que se pretende hacer. Por otro lado:

Código:
if ((DmxRxField[1]*DmxRxField[3])/255)

Estás preguntando sí "(DmxRxField[1]*DmxRxField[3])/255" es distinto de cero, de ser así, entra en el if; ¿eso es lo que estás buscando?
bueno voy a recordarte como era esto ., en la librería de recepción (DMX_RX) hay una función que es esta
PHP:
uint8_t i;
    for (i=0; i<sizeof(DmxRxField); i++)
        {
        DmxRxField[i]= 0;
        }
bueno a travez del desarrollo de la librería de recepción eso se convierte en esto
PHP:
else if (DmxState == STARTB)
    {
    if (--DmxCount == 0)                        //start address reached?
        {
        DmxCount= 1;                            //set up counter for required channels
        DmxRxField[0]= DmxByte;                    //get 1st DMX channel of device
        gDmxState= STARTADR;
        }
    }

else if (DmxState == STARTADR)
    {
    DmxRxField[DmxCount++]= DmxByte;            //get channel
    if (DmxCount >= sizeof(DmxRxField))         //all ch received?
        {
        gDmxState= IDLE;
y que tiene un valor declarado al comienzo de la librería
PHP:
static  uint16_t DmxCount;
        uint8_t  USARTstate= UCSRA;                //get state before data!
        uint8_t  DmxByte   = UDR;                //get data
        uint8_t  DmxState  = gDmxState;            //just load once from SRAM to increase speed
Bueno ., ese valor DmxCount ., es el valor del potenciometro virtual ., que va desde 0 a 255
aclaremos que ese valor ya lo tengo dentro del uC (comando)
la cosa es ., como bien me preguntas al final
2- Como te mencioné antes, una cosa es un if y otra una asignación. Realmente no se entiende que se pretende hacer. Por otro lado:

Código:
if ((DmxRxField[1]*DmxRxField[3])/255)

Estás preguntando sí "(DmxRxField[1]*DmxRxField[3])/255" es distinto de cero, de ser así, entra en el if; ¿eso es lo que estás buscando?
Y te lo ejemplifico de esta manera (como yo lo entiendo ., puedo estar equivocado al entenderlo)
aca tenemos el PWM de los led
PHP:
for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
Donde yo le estoy dando un valor de comparacion ., PWM_timer=0 donde cero es el comienzo del PWM (cero en el potenciometro virtual y cero en la salida del led) ., PWM_timer<255 ., máximo de 255 en el potenciometro virtual y máximo de 255 en la salida del led
PWM_timer++ ., vendria siendo el valor variable o mometanio reflejado
en el caso de la salida de los led tengo definido de esta manera
PHP:
if (DmxRxField[0]>PWM_timer)        //ROJO   
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)       
            }
Donde el valor individual esta definido por >PWM_timer ., al final de la IF ., y así tengo tres valores individuales de PWM ., que uno., es independiente de otro
Viendo que esto es así .,( supongo) que a DmxRxField 3 le tenemos que dar un valor
Que seria del cero a < 255 y por supuesto con un "++" para que sea variable y acompañe la señal del potenciometro virtual
a todo esto ., la conclucion que saco ., es que por mas que lo tenga declarado ., también definido ., pero sin ningún valor numérico
DmxRxField 3 no hace nada .,tampoco interfiere en en las demás funciones .,porque no tiene ni siquiera el valor de CERO .,
Por lo tanto la división en DMX no se cumple (igual que en cualquier función matemática)
en cuanto a definirla no hay problema podría ser uint8_t DmxBuf_DmxRxField[3]

Donde DmxBuf ., ya lo tenemos manejado en la librería de recepción
tambien pence que si hay que darle un valor de PWM podria ser
PHP:
if (DmxRxField[3]>>PWM_timer)
pero alli esta mi gran duda ., y es a lo que me referia anteriormente
Porque supuestamente la resultante de las divisiones y multiplicaciones es un valor del PWM ., que se aplica a los led
de ali la duda de ser un count o PWM_timer
bueno espero que me puedas entender que pasa con esto
 
Me acuerdo que esos valores del DmxRXField lo obtenías del puerto serie.

Lo que no queda claro es la utilidad de DmxRXField[3].

la cosa es ., como bien me preguntas al final [/LEFT]
Y te lo ejemplifico de esta manera (como yo lo entiendo ., puedo estar equivocado al entenderlo)​
aca tenemos el PWM de los led
PHP:
for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
Donde yo le estoy dando un valor de comparacion ., PWM_timer=0 donde cero es el comienzo del PWM (cero en el potenciometro virtual y cero en la salida del led) ., PWM_timer<255 ., máximo de 255 en el potenciometro virtual y máximo de 255 en la salida del led​
PWM_timer++ ., vendria siendo el valor variable o mometanio reflejado​
en el caso de la salida de los led tengo definido de esta manera​
PHP:
if (DmxRxField[0]>PWM_timer)		//ROJO	
			{
				PORTB &= ~(1<<PB0);				//LED OFF (APAGADO)
			}else{
				PORTB |= (1<<PB0);				//LED ON  (ENCENDIDO)		
			}
Donde el valor individual esta definido por >PWM_timer ., al final de la IF ., y así tengo tres valores individuales de PWM ., que uno., es independiente de otro​

Hasta ahí vamos bien, en esa parte de la rutina forzás el led según los dutys recibidos en DmxRxField[0] a DmxRxField[2].

Viendo que esto es así .,( supongo) que a DmxRxField 3 le tenemos que dar un valor [/LEFT]
Que seria del cero a < 255 y por supuesto con un "++" para que sea variable y acompañe la señal del potenciometro virtual​


El valor de DmxRxField[3] es el 4to que recibiste por el puerto serie. Es tu referencia y no deberías tocarlo.

Pero no se entiende su uso, hasta no saberlo, es difícil ayudarte. Los dos códigos que pusiste arriba sobre su uso, es inconsistente, por eso es necesario que aclares bien que hacés con ese valor.​
 
bueno me alegra que me puedes entender ., aunque sea por partes​
Me acuerdo que esos valores del DmxRXField lo obtenías del puerto serie.

Lo que no queda claro es la utilidad de DmxRXField[3].



Hasta ahí vamos bien, en esa parte de la rutina forzás el led según los dutys recibidos en DmxRxField[0] a DmxRxField[2].



El valor de DmxRxField[3] es el 4to que recibiste por el puerto serie. Es tu referencia y no deberías tocarlo.

Pero no se entiende su uso, hasta no saberlo, es difícil ayudarte. Los dos códigos que pusiste arriba sobre su uso, es inconsistente, por eso es necesario que aclares bien que hacés con ese valor.
bueno la compilación ., la probé en lo físico ., DmxRxField[3] ., no hace nada​
y tendría que ser el MASTER_DIMMER que es el control de los tres dimmer anteriores​
bueno eso se usa porque de esa manera se puede dimerizar la mezcla de colores o sea RGB​
PHP:
 if ((DmxRxField[0]*DmxRxField[3])/255) //red
            {
                PORTB &= ~(1<<PB0);                //LED OFF
                }else{
                PORTB |= (1<<PB0);                //LED ON
            }
 
            if ((DmxRxField[1]*DmxRxField[3])/255) //green
            {
                PORTB &= ~(1<<PB1);                //LED OFF
                }else{
                PORTB |= (1<<PB1);                //LED ON
            }
 
            if ((DmxRxField[2]*DmxRxField[3])/255) //blue
            {
                PORTB &= ~(1<<PB2);                //LED OFF
                }else{
                PORTB |= (1<<PB2);                //LED ON
            }
de esa manera manejas con un solo potenciometro el brillo o valor de los tres canales juntos ., sin importar su valor si no ., eso tenes que manejar ., los dos o tres valores individualmente (mas difícil de manejar)​
y como te conté antes la funciones son
PHP:
DmxRxField[0] - Rojo
DmxRxField[1] - Verde
DmxRxField[2] - Azul
DmxRxField[3] - master dimmer
DmxRxField[4] - Strobe, 0 = apagado, 1 el tiempo más largo, 255 el menor tiempo
O sea que si ., tengo que hacer algo (y me parece que el error esta en lo que te explique antes)​
ahora si nos remitimos a las formulas ((DmxRxField [0] * DmxRxField [3]) / 255> PWM_timer)//rojo
Si estudias un poco el código te darás cuenta ., que DmxRxField[3] no tiene ningún valor activo dentro de la compilación​
por esa razón supongo cual es el error​
de esa manera ver como se puede tener un valor activo., dentro de la compilación​
porque hasta ahora el valor esta solo en la USART (recepción nada mas)​
bueno espero que entiendas la duda ., y ¡¡¡¡ mil gracias por enseñar !!!!
 
Ahora puede quede un poco más claro. Entonces el DmxRxField[3] si es un especie de controlador general de las luces.

¿Cuándo se usan los canales rojo, verde, azul por separado (sin que DmxRxField[3] intervenga)? y ¿cuándo no?

PD: no es necesario que pongas "me gusta", hasta ahora no llegamos a nada. :LOL:
 
PD: no es necesario que pongas "me gusta", hasta ahora no llegamos a nada. :LOL:
Bueno ., depende del punto de vista ., porque si es de mi parte ., todo lo que escribís es muy útil y no tiene desperdicio​
desde el punto de vista del foro., también es muy bueno ., porque respondes un tema ., eso implica que tomas tu tiempo., y eso vale​
Ahora puede quede un poco más claro. Entonces el DmxRxField[3] si es un especie de controlador general de las luces.
¿Cuándo se usan los canales rojo, verde, azul por separado (sin que DmxRxField[3] intervenga)? y ¿cuándo no?
En cuanto a los usos ., de unos o otros ., se usan siempre ., porque si tenes el color puro .,(cualquiera de los tres ) actua igual​
de la misma manera que cuando los mezclas ., para obtener los otros colores​
en valores ., te lo ejemplifico así : 255 ,0,0 ,255 ., donde los tres primeros valores son los led ., y el cuarto valor es el máster​
seria el rojo puro ., con el máster al máximo brillo​
entonces tomalo como regla general ., de que se usa siempre .,​
 
Última edición:
Creo que quedó claro, yo haría esto:

PHP:
unsigned int control_maestro_aux;
//...
while(1)                                   
        {
        get_dips();
 
        //-------------------- PWM LED
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
        {                                                                                                                        
            control_maestro_aux=DmxRxField[0];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //ROJO    
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)        
            }

            control_maestro_aux=DmxRxField[1];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //Verde    
            {
                PORTB &= ~(1<<PB1);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB1);                //LED ON  (ENCENDIDO)        
            }

            control_maestro_aux=DmxRxField[2];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //Azul   
            {
                PORTB &= ~(1<<PB2);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB2);                //LED ON  (ENCENDIDO)        
            }
 
        }

        //...
}

O un poco más elaborado, pero que resultaría lo mismo:

PHP:
unsigned int control_maestro_aux;
unsigned char canal;
//...
while(1)                                   
        {
        get_dips();
 
        //-------------------- PWM LED
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
        {                                                                                                                        
            for(canal=0; canal<3; canal++) //Canal: 0= Rojo, 1= Verde, 2= Azul
            {
               control_maestro_aux=DmxRxField[canal];
               control_maestro_aux=control_maestro_aux*DmxRxField[3];
               control_maestro_aux=(control_maestro_aux>>8);

               if ((unsigned char)(control_maestro_aux)>PWM_timer)        //Cada canal    
               {
                  PORTB &= ~(1<<canal);                //LED OFF (APAGADO)
               }else{
                  PORTB |= (1<<canal);                //LED ON  (ENCENDIDO)        
               }
            }
        }

        //...
}
 
Última edición:
..............................
gracias.gif
Creo que quedó claro, yo haría esto:

PHP:
unsigned int control_maestro_aux;
//...
while(1)                                   
        {
        get_dips();
 
        //-------------------- PWM LED
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
        {                                                                                                                        
            control_maestro_aux=DmxRxField[0];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //ROJO    
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)        
            }

            control_maestro_aux=DmxRxField[1];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //Verde    
            {
                PORTB &= ~(1<<PB1);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB1);                //LED ON  (ENCENDIDO)        
            }

            control_maestro_aux=DmxRxField[2];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //Azul   
            {
                PORTB &= ~(1<<PB2);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB2);                //LED ON  (ENCENDIDO)        
            }
 
        }

        //...
}

O un poco más elaborado, pero que resultaría lo mismo:

PHP:
unsigned int control_maestro_aux;
unsigned char canal;
//...
while(1)                                   
        {
        get_dips();
 
        //-------------------- PWM LED
        for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
        {                                                                                                                        
            for(canal=0; canal<3; canal++) //Canal: 0= Rojo, 1= Verde, 2= Azul
            {
               control_maestro_aux=DmxRxField[canal];
               control_maestro_aux=control_maestro_aux*DmxRxField[3];
               control_maestro_aux=(control_maestro_aux>>8);

               if ((unsigned char)(control_maestro_aux)>PWM_timer)        //Cada canal    
               {
                  PORTB &= ~(1<<canal);                //LED OFF (APAGADO)
               }else{
                  PORTB |= (1<<canal);                //LED ON  (ENCENDIDO)        
               }
            }
        }

        //...
}
!!!!!! funciona cosme ¡¡¡¡¡
perfectamente ., teniendo el master al maximo los otros tres canales tienen el "duty" perfecto ., lo que funciono queda asi
PHP:
	int PWM_timer;																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																												
 unsigned int control_maestro_aux;		
	
	
	while(1)									//p?tla g?ówna
	    {
		get_dips();								//Sprawdzenie dipswitchy i pobranie adresu DMX
 
	
		
 
		//-------------------- PWM LED
		for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
		   
           
         {																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																														
		
			 control_maestro_aux=DmxRxField[0];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //azul   
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)        
            }

            control_maestro_aux=DmxRxField[1];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //verde    
            {
                PORTB &= ~(1<<PB1);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB1);                //LED ON  (ENCENDIDO)        
            }
              control_maestro_aux=DmxRxField[2];
            control_maestro_aux=control_maestro_aux*DmxRxField[3];
            control_maestro_aux=(control_maestro_aux>>8);

            if ((unsigned char)(control_maestro_aux)>PWM_timer)        //ROJO    
            {
                PORTB &= ~(1<<PB2);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB2);                //LED ON  (ENCENDIDO)        
            
			}
 
		}
	}
}
bueno ., hasta aquí sabemos que funciona ., ahora hay que agregar el strobo yo lo tenia de otra manera pero con este agregado no se como​
 
Última edición:
Explicá que función cumpliría el strobo, vos pusiste:

DmxRxField[4] - Strobe, 0 = apagado, 1 el tiempo más largo, 255 el menor tiempo

¿A qué te referís con tiempo largo y corto? y ¿qué pasa cuando está apagado?

¿Estos canales además deberían prenderse y apagarse según el estrobo?
 
bueno vamos por partes​
Explicá que función cumpliría el strobo, vos pusiste:
¿A qué te referís con tiempo largo y corto? y ¿qué pasa cuando está apagado?
¿Estos canales además deberían prenderse y apagarse según el estrobo?
aca te explico mas o menos​
¿A qué te referís con tiempo largo y corto?
el tiempo largo es cuando ., entre destello y destello es mas espaciado​
y se situá cerca del valor cero o 1 ., pero en la realidad se usa desde el valor > 10 o mas​
El tiempo corto se refiere al espacio ., entre destello y destello ., es corto o muy pequeño ., en lo que probé ., son fracciones de segundo y es al valor de 255​
y ¿qué pasa cuando está apagado?
bueno ., en realidad lo que hace el estrobo ., es apagar los led​
pero se pueden dar las condiciones., que si tenias el canal activado a un valor cualquiera quede prendido (obviamente después que la función strobo termine ) o lo pongas en CERO​
¿Estos canales además deberían prenderse y apagarse según el estrobo?
exactamente así funciona ., y la razón es que por ejemplo : puedas hacer destellar un color definido ., rojo ,azul ,amarillo o cualquiera que elijas., así son los equipos DMX profecionales​
 
Última edición:
Para hacerla más fácil y probar rápido, se podría hacer un delay variable según el strobo. Para agregar el delay, casi al principio del código es necesario que agregues la librería "delay.h". Será necesario que pruebes con distintos valores de delay para alcanzar los tiempos que estás buscando.

Probá con esto:

PHP:
#include <util/delay.h>
...
unsigned int control_maestro_aux;
unsigned char canal;
unsigned char flag_estrobo=0;
//...
while(1)                                   
        {
        get_dips();
         
          //-------------------- PWM LED
          for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Loop del timer aplicado al bucle while
          {                                                                                                                        
              for(canal=0; canal<3; canal++) //Canal: 0= Rojo, 1= Verde, 2= Azul
              {
                 if(flag_estrobo) //El flag estrobo habilita o no el encendido/apagado de LEDS!   
                 {
                   control_maestro_aux=DmxRxField[canal];
                   control_maestro_aux=control_maestro_aux*DmxRxField[3];
                   control_maestro_aux=(control_maestro_aux>>8);
                 
                   if (((unsigned char)(control_maestro_aux)>PWM_timer))        //Cada canal.
                   {
                      PORTB &= ~(1<<canal);                //LED OFF (APAGADO)
                   }else{
                      PORTB |= (1<<canal);                //LED ON  (ENCENDIDO)        
                   }
                 }//if(flag_estrobo)

                 if(DmxRxField[4]!=255) //Pregunto si son tiempos cortos o largos
                 {
                    _delay_ms(1); //Si el for para el PWM es de 255 => el periodo final serán 255mS
                 }
                 else
                 {
                   _delay_ms(4); //Si el for para el PWM es de 255 => el periodo final será 1,02 Seg	
                 }

              }// for(canal=0; canal<3; canal++)
          }//for (PWM_timer=0; PWM_timer<255 ; PWM_timer++)    
          
          if(DmxRxField[4])  //Si el estrobo está habilitado!
          {
            flag_estrobo ^= 1; //Cambia el estado del flag estrobo, habilita o no destello
          }
          else
          {
            flag_estrobo=1; //Si el estrobo no está habilitado => los leds están siempre funcionando.
          }
        //...
}

Los valores dentro del delay están puesto "a lo que me pareció", debe haber valores preestablecidos para los tiempos del destello.

Para jugar con esos valores deberías hacer este cálculo:

[LATEX]Tiempo_{\left(destello\right)}=Tiempo_{\left(delay\right)}.255[/LATEX]

Si por ej. quisiera un destello c/1Seg:

[LATEX]Tiempo_{\left(delay\right)}=\frac{Tiempo_{\left(destello\right)}}{255}= \frac{1 S}{255}=3,92 mS[/LATEX]

Entonces el código queda:

PHP:
...
_delay_ms(3.92);
...

Se puede dar la condición que un canal esté en 255 y en esa condición el estrobo no funcionaría, para solucionar eso, se puede agregar esta línea en el if de los canales:

PHP:
...
if(flag_estrobo) //El flag estrobo habilita o no el encendido/apagado de LEDS!   
{
  control_maestro_aux=DmxRxField[canal];
  control_maestro_aux=control_maestro_aux*DmxRxField[3];
  control_maestro_aux=(control_maestro_aux>>8);
                 
  if (((unsigned char)(control_maestro_aux)>PWM_timer))        //Cada canal.
  {
    PORTB &= ~(1<<canal);                //LED OFF (APAGADO)
  }else{
    PORTB |= (1<<canal);                //LED ON  (ENCENDIDO)        
  }
}//if(flag_estrobo)
else
{
  PORTB &= ~(1<<canal);  //LED OFF (APAGADO) => Se fuerza el apagado del led debido al estrobo.
}
...

Editado:

Me había quedado mal el "if" del estrobo, ahí lo corregí.
 
Última edición:
Atrás
Arriba