Forum: Mikrocontroller und Digitale Elektronik Logarithmische Berechnung der LED Helligkeit


von Stefan (Gast)


Lesenswert?

Habe ein kleines Problem mit dem Fading 3er LEDs auf einem WS2812 Strip. 
Die 3 Leds sollen einen Sekundenzeiger anzeigen. Jedoch hackeln die LEDs 
noch ein bisschen.
Grund ist die lineare Berechnung der Helligkeit (-> Berechnung Fading).

Wie sieht die logarithmische Berechung genau aus? Mit einem Array möchte 
ich ungern arbeiten, da die Zeit vom loop abhängig ist. Soll heißen, der 
loop braucht z.B. einmal 20ms und das nächste mal 30ms. Das würde 
bedeuten das innerhalb einer Sekunde mir die letzen Werte eines Arrays 
nicht zur Verfügung stehen.

Zum Einsatz kommt ein Arduino Pro Mini 328P. Der Arduino ist nur für die 
Anzeige einer Uhr zuständig. (Stunden, Minuten und Sekundenzeiger).
1
static byte sAlt;
2
unsigned long aZeit = millis();
3
static unsigned long vZeit;
4
static unsigned long dZeit;
5
6
if(s != sAlt) {
7
  vZeit = aZeit;
8
  sAlt = s;
9
}
10
11
// Vergangene Zeit seit der letzen Sekundenänderung
12
dZeit = aZeit - vZeit;
13
// Berechnung des Fadings
14
float x = 255-(255*dZeit/1000);
15
float y = 255;
16
float z = 255*dZeit/1000;
17
    
18
leds[s].b = x;
19
leds[s+1].b = y;
20
leds[s+2].b = z;

: Bearbeitet durch User
von Jörg E. (jackfritt)


Lesenswert?


: Bearbeitet durch User
von Ralf (Gast)


Lesenswert?

Neben dem bereits genannten Artikel hab ich es folgendermaßen berechnet 
und war recht zufrieden:
k = n^(1/m), wobei n die maximale (PWM-)Stufe ist und m die Anzahl der 
Schritte. k ergibt einen Faktor, mit dem multipliziert wird.

Beispiel mit n = 255 und m = 10:
Schritt 0: 0
Schritt 1: k -> 1,7404198105
Schritt 2: (Schritt 1) * k -> 3,0290611167
...
Schritt 10: (Schritt 9) * k -> 255

Ob das nun der Formel aus dem Artikel entspricht bezweifle ich, mir hat 
es jedenfalls für meine Anwendung gereicht...

Ralf

von Stefan (Gast)


Lesenswert?

Den Artikel hatte ich schon gesehen(wird man ja tausendfach von Google 
drauf weitergeleitet ;)). Hab davon heute mittag mit der Tabelle 
gearbeitet. Da trat aber dann das Problem auf, das wenn die loopTime mal 
um ein paar ms verspringt, nicht mehr alle Werte des daraus erzeugten 
Wertes angesprochen wurden.

@Ralf, ich werde mal schaun ob ich das entsprechend anpassen kann für 
meine Aufgabe. Danke schon mal.

von holger (Gast)


Lesenswert?

>Hab davon heute mittag mit der Tabelle
>gearbeitet. Da trat aber dann das Problem auf, das wenn die loopTime mal
>um ein paar ms verspringt, nicht mehr alle Werte des daraus erzeugten
>Wertes angesprochen wurden.

Dann zeig mal deinen Code dazu.

Mit deinem float Geraffel gewinnst du jedenfalls keinen
Blumentopf oder einen Zeitvorteil gegenüber einer Tabelle;)

von Konrad S. (maybee)


Lesenswert?

Immer wieder gerne von mir empfohlen:
http://www.zabex.de/site/sofabeleuchtung.html

von Stefan (Gast)


Lesenswert?

Das hier ist vorerst mein derzeitiger Sketch. Im Endeffekt soll hier ein 
sauberer Überlauf der Sekunden geschehen. Das heißt, man soll den 
"Ausschlag" des Sekundenzeigers nicht sehen.
leds[s] fadet runter
leds[s+1] fadet hoch und wieder runter // oder aber konstant 255 wenn es 
flüssig aussieht mit s und s+2
leds[s+2] fadet hoch

Habe derzeit nur einen WS2812 Strip mit insgesamt 15 RGB Leds im 
Einsatz. Der Fade sieht für mich noch nicht so prickelnd aus. Derzeit 
handelt es sich um die RGB Stips mit 60Leds/m. Im richtigen Prototypen 
kommen 60 zum ein Einsatz mit 144Leds/m. Somit werden vermutlich die 
Übergänge automatisch weicher. Ich lasse mich aber eines besseren 
belehren.


1
// RTC
2
#include <DS3232RTC.h>
3
#include <Time.h>
4
#include <Wire.h>
5
6
// F-Makro
7
#include <Streaming.h>
8
9
// LED Strip
10
#include <FastSPI_LED2.h>
11
#define NUM_LEDS 60
12
#define DATA_PIN 4
13
CRGB leds[NUM_LEDS];
14
15
// Ausgabe Debug Serial Monitor
16
byte debug = 3;
17
unsigned long lZeit = 0;
18
19
20
void setup() {
21
  Serial.begin(115200);
22
23
  // RTC Zeit setzen - zum testen!
24
  time_t t;
25
  tmElements_t tm;
26
  tm.Year = 2000;
27
  tm.Month = 1;
28
  tm.Day = 1;
29
  tm.Hour = 0;
30
  tm.Minute = 3;
31
  tm.Second = 0;
32
  t = makeTime(tm);
33
  RTC.write(tm);
34
  setTime(t);
35
36
  // LED Strip
37
  FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
38
}
39
40
41
void loop() {
42
  // Erfassung der loopZeit
43
  unsigned long aZeit = millis();
44
45
  // Aktivieren des Debuggers über den Serial Monitor
46
  if(Serial.available()) debug = Serial.parseInt();
47
48
  // Alle LEDs löschen
49
  for(int x = 0; x < 60; x++) leds[x] = CRGB(0,0,0);
50
51
  // RTC
52
  tmElements_t tm;
53
  RTC.read(tm);
54
  byte h = tm.Hour * 5;
55
  byte m = tm.Minute;
56
  byte s = tm.Second;
57
58
  rtcSekunden(s);
59
  FastLED.show();
60
61
  // Erfassung der loopZeit
62
  lZeit = millis() - aZeit;
63
  if(debug == 0) {
64
    Serial << F("lZeit : ") << dig2(lZeit) << endl;
65
  }
66
}
67
68
void rtcSekunden(byte s) {
69
  byte ledArray[] = {
70
    59, 0,1,2,3,4,5,6,7,8,9,10,
71
    11,12,13,14,15,16,17,18,19,20,
72
    21,22,23,24,25,26,27,28,29,30,
73
    31,32,33,34,35,36,37,38,39,40,
74
    41,42,43,44,45,46,47,48,49,50,
75
    51,52,53,54,55,56,57,58,59, 0
76
  };
77
78
  byte pwmFadeX[] = {
79
    69,66,64,61,59,57,54,52,50,48,
80
    46,44,43,41,39,38,36,35,34,32,
81
    31,30,29,28,26,25,24,23,23,22,
82
    21,20
83
  };
84
  
85
  byte pwmFadeY[] = {
86
    74,81,88,95,103,112,122,132,144,156,
87
    169,184,199,216,235,255,255,235,216,199,
88
    184,169,156,144,132,122,112,103,95,
89
    88,81,74
90
  };
91
92
  byte pwmFadeZ[] = {
93
    20,21,22,23,23,24,25,26,28,29,
94
    30,31,32,34,35,36,38,39,41,43,
95
    44,46,48,50,52,54,57,59,61,64,
96
    66,69  
97
  };
98
99
  // Vergangene Zeit seit der letzen Sekundenänderung
100
  static byte sAlt;
101
  unsigned long aZeit = millis();
102
  static unsigned long vZeit;
103
  static unsigned long dZeit;
104
  if(s != sAlt) {
105
    vZeit = aZeit;
106
    sAlt = s;
107
  }
108
  dZeit = aZeit - vZeit;
109
110
  // Berechnung des Fadings
111
  byte i = dZeit/31.25;
112
  if(i >= 32 ) i = 31;
113
114
  // 10 Schritte/Sekunde
115
  byte x = pwmFadeX[i];
116
  byte y = pwmFadeY[i];
117
  byte z = pwmFadeZ[i];
118
119
  // Zuweisung
120
  leds[ledArray[s]].b = x;
121
  leds[ledArray[s+1]].b = y;
122
  leds[ledArray[s+2]].b = z;
123
124
  // Debuginfo
125
  if(debug == 3) {
126
    Serial << F("s : ") << dig2(s);
127
    Serial << F("   i : ") << dig3(i);
128
    Serial << F("   leds[0] : ") << dig3(x);
129
    Serial << F("   leds[1] : ") << dig3(y);
130
    Serial << F("   leds[2] : ") << dig3(z);
131
    Serial << F("   lZeit : ") << dig2(lZeit);
132
    Serial << endl;
133
  }
134
}
135
136
// 2 stellige Ausgabe von Zahlen
137
byte dig2(byte i) {
138
  if(i < 10) Serial << " ";
139
  return i;
140
}
141
142
// 3 stellige Ausgabe von Zahlen
143
byte dig3(byte i) {
144
  if(i < 10) Serial << " ";
145
  if(i < 100) Serial << " ";
146
  return i;
147
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.