Pwm: spegnere led contemporaneamente

Ciao a tutti,
non riesco ad uscire da questo problema!!

In pratica devo far spegnere contemporaneamente due led accesi con intensità diversa...ho pensato ad una cosa del genere ma uno si spegne sempre prima dell'altro

int maxPwm_bianco = 255;		// valore massimo bianco
int maxPwm_blu = 50;		// valore massimo blu
long durata_pwm = 1000;

int interval_bianco = durata_pwm / maxPwm_bianco;
int interval_blu   = durata_pwm / maxPwm_blu;

void gestione_led(){

	unsigned long currentMillis_Wh = millis();
	unsigned long currentMillis_Bl = millis();
	bool start_Ok;

	if(!start_Ok){

		if(currentMillis_Wh - previousMillisWh > interval_bianco) {
			previousMillis_Wh = currentMillis_Wh;

			if(maxPwm_bianco > 0) {
				maxPwm_bianco--;
				analogWrite(led_bianchi,maxPwm_bianco);
			}

			if(currentMillis_Bl - previousMillis_Bl > interval_blu) {
				previousMillis_Bl = currentMillis_Bl;
				if(maxPwm_blu > 0) {
					maxPwm_blu--;
					analogWrite(led_blu,maxPwm_blu);
				}
			}

		}

Questa è la parte del codice incriminata.
Credo che il problema sia nel calcolo del tempo di intervallo ed eventuali decimali ma non ho idea di come risolvere........

Non lo stai mica spegnendo ma abbassando la luminositá. Questo vuol dire che a secondo del valore PWM servono piú o meno cicli per arrivare a 0.
Se vuoi spegnerli contemporaneamente devi portarli a zero col stesso numero di cocli.
percui il valore piú basso lo diminiusci con 1 e quello piú alto con valore alto /valore basso facendo i calcoli con dei float.
Ciao Uwe

Io però vorrei che la dissolvenza avvenga con uno step alla volta per entrambi i led...per questo volevo agire sul tempo.
Se ho capito bene Con il tuo esempio il led con il valore maggiore ad ogni ciclo decrementera' di 4 step..corretto?

Se un led è a 255 ed uno a 127 nello stesso ciclo decrementi il primo di 2 alla volta ed il secondo solo di uno, per raggiungere zero nello stesso momento..

Se un led è a 255 ed uno a 127 nello stesso ciclo decrementi il primo di 2 alla volta ed il secondo solo di uno, per raggiungere zero nello stesso momento..

Ok, ma come ho risposto a uwefed vorrei che la dissolvenza fosse più "fluida"...mettiamo il caso che il primo led sia a 250 e il secondo a 10, il primo decrementerà ad ogni ciclo di 25...troppo per quello che devo fare!!

Io invece vorrei fare in modo che, se il tempo di spegnimento è di un minuto, il primo decrementerà di uno ogni 230ms circa e il secondo di uno ogni 6secondi (considerando i valori dell'esempio).

acron:
Io invece vorrei fare in modo che, se il tempo di spegnimento è di un minuto, il primo decrementerà di uno ogni 230ms circa e il secondo di uno ogni 6secondi (considerando i valori dell'esempio).

Usa la funzione millis(), che restituisce il numero di millisecondi dall'avvio di Arduino, e crea una funzione di fading basata su di essa.
Ti calcoli in anticipo i due intervalli di decremento dei 2 led e poi esegui il ciclo finché non hai raggiunto lo zero per entrambi

E' quello che ho fatto nel codice del primo post ma arrivano a 0 in due momenti diversi :cold_sweat:

Prova usando un tipo float per interval_bianco e interval_blu.
Se un numero in virgola mobile lo salvi in una variabile di tipo intero (es.: int interval_bianco = durata_pwm / maxPwm_bianco) il compilatore arrotonderà il numero troncandolo all'intero più vicino, quindi 1.2 per esempio diverrà 1. Il resto decimale, accumulandosi, probabilmente ti darebbe la differenza per riallineare i 2 led.

Poi non so se l'errore è quello, non mi sono messo a studiare il codice.

acron:
E' quello che ho fatto nel codice del primo post ma arrivano a 0 in due momenti diversi :cold_sweat:

Non era quello che avevi fatto, avevi messo il interval_blu nel if dell' interval_bianco. Per questo non sono indipendenti e chiamati a intervalli diversi.

	if(currentMillis_Wh - previousMillisWh > interval_bianco) 
		{
		peviousMillis_Wh = currentMillis_Wh;
		if(maxPwm_bianco > 0) 
			{
			maxPwm_bianco--;
			analogWrite(led_bianchi,maxPwm_bianco);
			}
		if(currentMillis_Bl - previousMillis_Bl > interval_blu) 
			{
			previousMillis_Bl = currentMillis_Bl;
			if(maxPwm_blu > 0) 
				{
				maxPwm_blu--;
				analogWrite(led_blu,maxPwm_blu);
				}
			}
		}

cosí é piú chiaro.
Ciao Uwe

Scusate l'assenza dal thread ma ho rimesso mano al codice in questi giorni.
Non so più dove sbattere la testa!!! =(

Come consigliato ho provato a cambiare in float le variabili dell'intervallo tra uno step e l'altro ma non cambia nulla.
Di seguito vi posto il codice della fase di accensione funzionante, arrivano contemporaneamente al valore di pwm massimo.....solo in questo caso però, perché se cambio il valore massimo di luminosità da 100 e 200 in 100 e 250 (quindi l'intervallo risulterà senza decimali) il led con il valore maggiore ci mette, sui 10 secondi stabiliti, 5 secondi in più.
Spero di essermi spiegato :roll_eyes:...ecco il codice:

long previousMillisWh = 0;        // will store last time LED was updated
long previousMillisBl = 0;        // will store last time LED was updated

int minPwm = 1;

long durata_pwm  = 10000;

int maxPwm_bianchi = 100; 	// valore massimo potenza bianchi
int maxPwm_blu	   = 200;	// valore massimo potenza blu

float interval_white; 	//intervallo tra uno step e l'altro
float interval_blu;		//intervallo tra uno step e l'altro


bool accendi(bool start)
{
	if (start == false){
		interval_white = durata_pwm / maxPwm_bianchi; 
		interval_blu   = durata_pwm / maxPwm_blu;		
		
                             analogWrite(led_bianchi, minPwm);
		analogWrite(led_blu, minPwm);
		start = true;
	}

	if(millis() - previousMillisWh > interval_white)
	{
		previousMillisWh = millis();


		if (pwm_Wh < maxPwm_bianchi)
		{
			pwm_Wh++;
			analogWrite(led_bianchi,pwm_Wh);
		}
		else
		{
			analogWrite(led_bianchi,maxPwm_bianchi);
			pwm_Wh = maxPwm_bianchi;
		}
	}

	if(millis() - previousMillisBl > interval_blu)
	{
		previousMillisBl = millis();


		if (pwm_Bl < maxPwm_blu)
		{
			pwm_Bl++;
			analogWrite(led_blu,pwm_Bl);
		}
		else
		{
			analogWrite(led_blu,maxPwm_blu);
			pwm_Bl = maxPwm_blu;
		}
	}
	return start;
}