Forum: Mikrocontroller und Digitale Elektronik Lux-Sensor Adafruit TSL2591 und ESP8266


von Christian S. (solder)


Angehängte Dateien:

Lesenswert?

Hallo,

für mein Projekt habe ich einen Adafruit TSL2591 mit dem ESP8266 per I2C 
verbunden. Ich möchte (draußen) die Beleuchtungsstärke messen und per 
WLAN an den Server übertragen.

Im Moment habe ich nur einen einzigen TSL2591, es soll aber noch ein 
weiterer (abgeschatteter) dazukommen, mit dem ich dann Sonnnenschein 
oder Bewölkung unterscheiden kann. Irgendwann könnte ich mit der 
Information dann die Rollläden steuern, vor allem im Sommer, damit es 
nicht so warm wird, wenn die Sonne reinscheint.

Anbei der Code, wobei ich das Hauptsächlich vom TSL2591 übernommen habe 
und die bekannten Teile für den ESP8266 hinzugefügt. Ich habe versucht, 
eine Logik zu erstellen, dass die Verstärkung des Chips an die Messwerte 
angepasst wird und dynamisch nach Bedarf gewählt wird. Die Daten werden 
an den Volkszähler übermittelt.

Aktuell ist es so, dass die Daten bei 5% Änderung übertragen werden oder 
nach ca. 5 Minuten. Teilweise erfolgt dann die Datenübermittlung sehr 
oft hintereinander, wenn sich so wie heute ständig die Bewölkung ändert, 
teilweise im Sekundentakt.

Was nicht so funktioniert (und ich würde mich über einen Kommentar oder 
Anregung zur Abhilfe freuen):

1.) Ich bekomme nur 2 Nachkommastellen. Laut Beschreibung, soll der 
TSL2591 aber bis 0,000118 Lux herunter können. Ich würde gern auch die 
Nächte unterscheiden können, ob z.B. der Mond schien oder Schnee liegt. 
Ich habe den Quellcode schon auf Double geändert, auch in der Lib, aber 
es blieb bislang bei 2 Ausgabestellen nach dem Komma. Ich kann das nicht 
ganz nachvollziehen, denn selbst das Basic vom C64 hatte da mehr 
Stellen. Oder liegt es eher an den Ausgabefunktionen (Serial.print)? 
Aber auch die Werte in der Datenbank haben nur 2 Nachkommastellen.

2.) Kennt jemand eine Lösung, dem Volkszähler-Frontend eine 
logarithmische Skala zu verschaffen? Gibt es überhaupt eine Möglichkeit, 
die Skalierung selbst festzulegen? So ärgert es mich auch, dass die 
Skala für Luftdruck von 0 bis 1000+ geht, dabei wäre ein Bereich von 
800-1100 sinnvoller.

Für die Außenanwendung wollte ich alles in ein Einportion-Marmeladenglas 
packen und zuschrauben. Ich bin noch nicht sicher, ob da alles reingeht: 
Also 2x TSL2591, ESP-03, Si7021, Mini-Schaltregler.

Für die TSL2591 brauche ich einen I2C-Muxer, aber die fertigen 
Baugruppen sind mir alle zu groß. Außerdem brauche ich 8-fach nicht. Ich 
habe in einem Thread gefunden, dass es mit dem HC4066 geht. Als SO-14 
auf einer Adapterplatine sollte es klein genug werden.

Außerdem wäre vielleicht ein Widerstand als Beheizung nicht schlecht. 
Mit dem Si7021 wollte ich die Umgebungsbedingungen im Gläschen 
überwachen. Vorteil, ich bleib' bei I2C.

Anbei noch ein Screenshot mit Ausschnitt vom heutigen Tag. Wir hatten 
stark wechselnde Bewölkung (typisches Aprilwetter halt). Der Sensor lag 
im Fenster (Ostseite) und hat leider nur kurz die Sonne gesehen.

Christian

Nachtrag: Für 1 ist eine Lösung in Sicht. Für alle .print-Ausgaben kann 
man die Anzahl der Stellen nach einem Komma angeben. Für die 
Übermittlung an den Server wird das bei mir erst in einen String 
umgewandelt und zusammengebastelt. Aber ich habe eine Seite gefunden, wo 
das auch gelöst werden konnte. Das wird sich sicher übertragen lassen.

Noch eine Frage dazu: Der Arduino Uno hat nur float und kein double. Ist 
das dann synonym (damit's kein Fehler gibt) oder wird für den ESP doch 
double verfügbar (wie bei Arduino Due)? Ok, kann man bestimmt auch 
wieder googeln.

: Bearbeitet durch User
von Christian S. (solder)


Lesenswert?

Das war leider nichts. Jetzt habe ich zwar 4 Stellen hinterm Komma, aber 
die niedrigen Lux-Werte schwanken extrem, sind teilweise sogar negativ. 
Wenn ich mir jedoch die dazugehörigen Rohwerte (IR, Full) ansehe, dann 
sieht das eigentlich noch ganz gut aus. Da werde ich mir mal die 
Berechnung in der Lib ansehen müssen. Vielleicht ist die Reihenfolge der 
Rechenschritte für so kleine Werte einfach ungünstig.
1
Gain: 48 Timing: 5 IR: 10026  Full: 14576  Visible: 4550  Lux: -0.0016
2
Gain: 48 Timing: 5 IR: 9994  Full: 14638  Visible: 4644  Lux: 0.0029
3
Gain: 48 Timing: 5 IR: 10041  Full: 14735  Visible: 4694  Lux: 0.0040
4
Gain: 48 Timing: 5 IR: 10108  Full: 14780  Visible: 4672  Lux: 0.0019
5
Gain: 48 Timing: 5 IR: 10137  Full: 14727  Visible: 4590  Lux: -0.0020
6
Gain: 48 Timing: 5 IR: 10097  Full: 14669  Visible: 4572  Lux: -0.0020
7
Gain: 48 Timing: 5 IR: 10060  Full: 14658  Visible: 4598  Lux: -0.0002
8
Gain: 48 Timing: 5 IR: 10056  Full: 14698  Visible: 4642  Lux: 0.0016
9
Gain: 48 Timing: 5 IR: 10080  Full: 14639  Visible: 4559  Lux: -0.0022
10
Gain: 48 Timing: 5 IR: 10042  Full: 14671  Visible: 4629  Lux: 0.0014
11
Gain: 48 Timing: 5 IR: 10063  Full: 14687  Visible: 4624  Lux: 0.0008
12
Gain: 48 Timing: 5 IR: 10076  Full: 14758  Visible: 4682  Lux: 0.0029
13
Gain: 48 Timing: 5 IR: 10134  Full: 14734  Visible: 4600  Lux: -0.0015
14
Gain: 48 Timing: 5 IR: 10113  Full: 14533  Visible: 4420  Lux: -0.0084
15
Gain: 48 Timing: 5 IR: 9970  Full: 14602  Visible: 4632  Lux: 0.0028
16
Gain: 48 Timing: 5 IR: 10022  Full: 14662  Visible: 4640  Lux: 0.0022
17
Gain: 48 Timing: 5 IR: 10061  Full: 14694  Visible: 4633  Lux: 0.0012
18
Gain: 48 Timing: 5 IR: 10084  Full: 14695  Visible: 4611  Lux: -0.0002
19
Gain: 48 Timing: 5 IR: 10081  Full: 14644  Visible: 4563  Lux: -0.0020
20
Gain: 48 Timing: 5 IR: 10046  Full: 14765  Visible: 4719  Lux: 0.0049
21
Gain: 48 Timing: 5 IR: 10090  Full: 14652  Visible: 4562  Lux: -0.0023
22
Gain: 48 Timing: 5 IR: 10018  Full: 14682  Visible: 4664  Lux: 0.0032

von Christian S. (solder)


Lesenswert?

Hmm,

in "Excel" kommt aber was vernünftiges raus... Ich habe mal double 
(siehe 1. Post) wieder in Float geändert. Vielleicht bringt das schon 
was. Wenn nicht, sollte ich die Berechnung vielleicht auf 
Integer-Opearationen ändern.

Hier die Berechnung aus der Lib:
1
cpl = (atime * again) / TSL2591_LUX_DF;
2
3
lux1 = ( (float)ch0 - (TSL2591_LUX_COEFB * (float)ch1) ) / cpl;
4
lux2 = ( ( TSL2591_LUX_COEFC * (float)ch0 ) - ( TSL2591_LUX_COEFD * (float)ch1 ) ) / cpl;
5
lux = lux1 > lux2 ? lux1 : lux2;

Bis auf chx (uint16) sind alles float. Hier mal noch die COEFC-Werte aus 
dem Header-File
1
#define TSL2591_LUX_DF            (408.0F)
2
#define TSL2591_LUX_COEFB         (1.64F)  // CH0 coefficient 
3
#define TSL2591_LUX_COEFC         (0.59F)  // CH1 coefficient A
4
#define TSL2591_LUX_COEFD         (0.86F)  // CH2 coefficient B
Für den Fall der größten Verstärkung (bei ganz dunkel) ist atime=600 und 
again=9876.

Im Datenblatt des TSL2591 habe ich gar nichts zu der Berechnung des 
Lux-Wertes gefunden. Vielleicht gibt's irgendwo eine App-Note, aber so 
bin ich nicht traurig, dass es in der Lib von Adafruit schon drin ist.

von Christian S. (solder)


Lesenswert?

So, auf float zurück gesetzt. Sieht gut aus. Auch der Übergang zwischen 
den einzelnen Verstärkungsstufen (bzw. Integrationsdauer) ist ok. 
Schwankungen in den Nachkommastellen sind auf akzeptablem Niveau.

Wenn jetzt noch die Darstellung im Volkszähler Frontend logarithmisch 
wäre...

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.