fade in en uit in 1 seconde ledstrip (ws2801)

Hallo,

ik ben bezig met een klok projectje.
setup: nano v3, rtcclip, ledstip ws2801 60 ledjes.

nu heb ik al de nodige klokken weergaven gemaakt.
alleen bij allemaal verspringt de seconde, dus dacht als ik die nu over 2 leds laat in en uit faden.
dan lijkt het of hij rond draaid ipv verspringt.

probleem lijkt nu, de brightness waarde is van 0 tot 255 maar die totale loop duurt geen seconde.
dus nu verspringen ze om de 2 a 3 seconden terug als de loop te snel is en 2/3 leds verder als hij te lang is (spelen met delay() ).

is er een mogelijkheid om er voor te zorgen dat de fade-in(led1 van secondewijzer) en fade-out (led2 van secondewijzer) precies 1 seconde duurt (nier na elkaar maar tegelijk).
heb al wel wat met timers zitten klootzakken maar dat werd tot nu nog niks (of ik doe het niet goed.)
hoe kan ik elke waarde verhoging van de brightness (0-255) zo lang maken (mapping?) dat van 0 naar 255, 1000 ms duurt ?

suggesties en ideeën zijn zeer welkom.

m.v.g.
Mark

hier de code (back to basic)

#include <FastLED.h>
#include <chipsets.h>
#include <Wire.h>
#include "RTClib.h" 

#define NUM_LEDS 60

CRGB leds[NUM_LEDS];
RTC_DS1307 rtc;

void setup() { 

 // Serial.begin(115200);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); 
#endif  
  rtc.begin();
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  }
    FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
}
 
void loop() {
   
     DateTime now = rtc.now();   // de tijd uit de rtcclip
     memset(leds, 0, NUM_LEDS * 3);  //zet alles op zwart
  
    //minuten
    leds[((now.minute()-1)%60)] = CRGB::Red;   // laat de minuten(wijzer)zien
    leds[(now.minute())%60] = CRGB::Red; 
    
    //uren
     unsigned char hourpos = (now.hour()%12)*5; // laat de uren(wijzer) zien
     leds[((59+hourpos)%60)%60] = CRGB::Green;
     leds[(hourpos)%60] = CRGB::Green;
     leds[((hourpos+1))%60] = CRGB::Green; 
    
   ///////////////////////////////////////// probleem gedeelte////////////  de seconde wijzer
   
    // seconde optie A
     for(int k = 0; k < 255; k++) { 
       leds[(now.second())%60].b = k;                          // leds[] geeft aan welke led in de strip
       leds[(now.second()-1)%60].b = map(k, 0, 255, 255, 0);   // .b de kleur, en na de = de brightness 0-255
       delay(2);                                          // met delay loopt ie +- 10 sec goed
       FastLED.show();                                         // stuur de data naar de ledstrip
       
    }
     
    // seconde optie B    
    //  static int k = 0;  
    // leds[(now.second())%60].b = k; 
    //   leds[(now.second()-1)%60].b = map(k, 0, 255, 255, 0);
    //     //FastLED.delay(3.33333333);
    //     k++;
    //	if (k == 255) {
    //		k = 0;
    //	}
    //     FastLED.show();
 
           
}

Je kunt delay(2) veranderen in delayMicroseconds(2000) en dat finetunen , maar dat lijkt me niet de beste oplossing.
Je zou die waarde in delayMicroseconds variabel moeten maken en die waarde dan synchroniseren met je secondetick.

Wanneer je een LED gaat dimmen tussen 255 en 0 (of andersom), dan zou je wel eens kunnen zien dat je in werkelijkheid een mooi egaal verloop aanstuurt, maar dat je dat in de LED helderheid zo niet ziet.
Dat komt omdat de menselijke sensoren (de ogen in dit geval) een logaritmische schaal hebben.
Wat je daarom ook kunt proberen, is een aantal stappen gaan gebruiken (stuk of 8 of misschien 16 ?).
Dan dus een berekening loslaten op de PWM waarde van beide aan te sturen LEDs, zodat de een omlaag, de ander omhoog zal zijn.
Door het kleiner aantal stapjes dat je zo nodig zal hebben, maak je ook wat tijd vrij voor andere zaken, zoals synchronisatie van de seconden met je RTC.

thanx, gaat nog ff het nodige proberen.

Zoals MAS al zei. Ik gebruik zelf altijd dit tabelletje om te faden:

/** array with nice fading settings from 0 to max */
byte fadeArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 22, 26,
        30, 35, 40, 45, 50, 56, 62, 68, 74, 81, 88, 95, 102, 110, 118, 126, 135,
        143, 152, 161, 170, 180, 190, 200, 210, 221, 232, 243, 249, 254 };

Het heeft de vorm van een S-curve. Ooit eens een formule ervoor gehad maar die kan ik niet meer vinden :slight_smile:

@nico
en waaromgebruik je 254 en niet 255?

Geen enkele specifieke reden :grin: Ooit had ik dit aan een klant gegeven om te experimenteren.... Hij kwam met dit lijstje terug.... Ik heb het toen verder zo geïmplementeerd.... hij blij.... ik blij.... Nu maakt het in dat gebied sowieso weinig uit voor de intensiteit. Maar dit werkt prima op zowel gewone leds als RGB led strips.

nicoverduin:
Geen enkele specifieke reden :grin: Ooit had ik dit aan een klant gegeven om te experimenteren.... Hij kwam met dit lijstje terug.... Ik heb het toen verder zo geïmplementeerd.... hij blij.... ik blij.... Nu maakt het in dat gebied sowieso weinig uit voor de intensiteit. Maar dit werkt prima op zowel gewone leds als RGB led strips.

bedankt. Ik zal daar ook eens goed naar moeten kijjken.
jantje

Voor mij geeft de volgende look-up tabel de beste resultaten:

byte EyeLineairArray [ ] = 
{ 0, 1, 2, 3, 4, 5, 7, 9, 12, 15, 18, 22, 27, 32, 38, 44, 51, 58, 67, 76, 86, 96, 108, 120, 134, 148, 163, 180, 197, 216, 235, 255 };

32 waarden tussen 0 en 255. Het verloop is logaritmisch. (Een S-curve heb ik er nooit in kunnen ontdekken)
Ik experimenteerde met RGB strips en wilde een regenboog rond laten draaien. Eerst gebruikte ik een gewone lineaire schaal en berekende de waarden met SIN en COS om 6 strips met een faseverschil van 60 graden aan te sturen.
Het resultaat was dat het licht gemiddeld te helder (wit) was en daaroverheen liep een regenboog van onverzadigde kleuren.
Nadat ik de lookup tabel gebruikte en het aantal stappen had teruggebracht tot 32 was het effekt zoals ik het wilde, een duidelijke regenboog met verzadigde kleuren.

edit: Ik moet mezelf even corrigeren. Het verloop is natuurlijk exponentieel en niet logaritmisch.

Je zult eerst een beetje moeten experimenteren met een tabel om een mooi glijdend verloop te vinden.
dat is nogal afhankelijk van de led en de weerstand.
de laagste waarde is bijv 10, (net niet zichtbaar), dan 12 zeer zwak en zo tot bijv 120 (helder)
en daartussen dan een aantal waarden zoeken. (bijv 25 waarden, waarom volgt nog)

als de seconde is versprongen in de RTC dan sla je de millis() op
je weet dat na 1 seconde de RTC weer verspringt en dat zijn dan 1000 ms.
in de loop kijk je naar de tijd die reeds verlopen is sinds de laatste verspringing. dus millis()-oude waarde
dat wordt hoogstens 1000.
stel de waarde is 126
dan doe je met map deze verbouwen naar 25 dus (0,1000,0,25)
uitkomst is tabel[5] en die heeft dan een waarde 16 bijv.
dan kijk je in de tabel welke waarde daarbij hoort, en die stuur je alleen als deze is verandert uit.
een exponentiele tabel is een goed uitgangspunt want onze ogen werken precies als ons gehoor.

Sorry, voor de late reactie, beetje druk zo voor de feestdagen.
niet veel tijd gehad om te spelen :slight_smile:

ik heb wat leuke ideeen op gedaan uit jullie reacties.
weer tijd om wat te experimenteren...

Voor ik het vergeet
Fijne dagen allemaal!!