FadeIn e FadeOut

Oi gente.

Estou com um projeto, onde tenho varios leds com 74HC595, transitando com fade entre um e outro.

Tenho os leds no shift no anodo, e o PWM no catodo dos leds

Minha lógica é a seguinte:

Seto 11111111, faço o fadein e o fadeout
Seto 10111111, faço o fadein e o fadeout
Seto 11011111, faço o fadein e o fadeout
...

Funciona, porem tenho 2 problemas

Gostaria de começar um fadein, e começar o fadeout do led anterior. Hoje eu faço o fadein/fadeout de um led, fadein/fadeout do seguinte, ...

Sacaram?

O outro problema é que eu preciso que essa transição dure 1 segundo, pois isso vai ser um relógio.

Pensei em usar 2 portas PWM, mas não consegui pensar em como. E a parte do segundo, não consigo fazer ideia de como garantir que isso rode em 1 segundo

Se não ficou claro, tento fazer um video ok?

Abraços

Sem o código aqui é impossível de dizer como fazer... se já fazes o fade-in e out... alterar o código para fazer e o outro será simples.

O fade é feito através da variacão do duty cycle. Quando o teu fade out comecar, o duty cycle estará a 100% (assumindo que o LED está directamente polarizado). Imaginando que diminuis o teu fade em passos de 10%...

O cálculo dos fades será:

unsigned int fade_in = 0, fade_out=100, fade=0;

for (int i = 0; i<=100; i+10) {
   fade_in = fade_in + i;       //enquanto um aumenta...
   fade_out = fade_out - i;   //o outro decresce na mesma medida. 
}

Claro que isto não é linear uma vez que a luminosidade do LED não é linear, mas deve dar o efeito que pretendes.

Para garantires um segundo certo... precisas dum RTC. O problema é que um RTC não te dá milisegundos para realizares o teu PWM.
A opcão que tens para garantires que tens um segundo (mais ou menos um erro inaceitável para um relógio de pulso) é usando o millis().

Sendo assim... 1000 milisegundos são 1 segundo. Se olhares ao código anterior onde uso passos de 10%, fica claro que tenho de alterar o PWM de 100 em 100 ms.
Isto é um exemplo... eu não faco ideia das limitacões do teu sistema, logo podes ter de alterar isto para passos de 20 ou 30% devido à velocidade do sistema. Isso deixo contigo.

Sendo assim... e aproveitando o código anterior...

#define PWM_STEP    10

unsigned long tempo = 0; 

unsigned int fade_in = 0, fade_out=100, fade = 0;
unsigned char num_LED = 0; //vamos iniciar com o LED 0

...

//se já passou 100ms... 
if (millis()-tempo>= 100) {
   tempo = millis();
   fade_in = fade_in + fade;       //enquanto um aumenta...
   fade_out = fade_out - fade;   //o outro decresce na mesma medida. 
   fade +=PWM_STEP; //incrementa em 10. 
   if (fade >= 100) { completamos o fadeout/fadein
      fade = 0; //reinicia
      num_LED++; //passa para o outro LED. 
   }
}

Claro que não compilei nem testei isto, mas esta é uma possibilidade.

Isto é apenas uma parte... a outra, mais complicada, envolve passar do fade_in/fade_out para o 595... mas isso já fizeste, né? :slight_smile:

Bubulindo,

Você foi muito esclarecedor. Inclusive me senti um tanto constrangido por nao ter pensado na simplicidade da sua lógica

Sobre os segundos, desconhecia o milis(), vai ajudar muito, por que tb tenho um rtc. Assim talvez eu possa ter um relogio interno, e a cada 5 minutos comparar com o rtc e calcular o valor do milisegundo com base na diferença entre os 2. Algo assim. Nao preciso de tanta precisao.

Desculpe não ter postado o código antes, ele esga o mais simples possivel ainda

Obrigado pelas ideias. Posto meu resultado em alguns dias :smiley: