Jump to content

Ambient Light V3 und Sättigung


Recommended Posts

Hallo zusammen,

habe ein kleines Verständnisproblem bezüglich der Sättigung. Laut Doku soll das Bricklet ja "0" zurückliefern wenn das der Fall ist. Ich hab dem Bricklet dann auch mal kurz einen Kochtopf übergestülpt und gesehen, daß "1" geliefert wurde, also dachte ich mir, wird das wohl ein "+1" hart verdrahtet in der Firmware stehen so daß unter normalen Umständen kein Wert von 0 kommen kann.

Jetzt sehe ich im Log, daß nachts doch immer wieder mal 0 vorkommt, aber das kann ja nun wirklich keine Sättigung sein.

Ich möchte den Sensor für meine Wetterstation benutzen, wo er sich später in einem Diffusor-Gehäuse befindet was das Licht abschwächt. Ich habe noch keine Idee welcher Messbereich da am passendsten ist und wollte mich dem quasi experimentell nähern, aber dazu müsste ich eben den Zustand der Sättigung zuverlässig vom Zustand der absoluten Dunkelheit irgendwie unterscheiden können … bin über Tipps dankbar!

André

Link to comment
Share on other sites

Moin André,

Sind die Werte 0 und 1 Rohwerte, die das Bricklet zurück liefert oder hast du da schon durch 100 geteilt um Lux zu bekommen? Falls ja: Ist das Problem einfach, dass du keine float-Division machst, weshalb Rohwerte kleiner 100 eine 0 erzeugen?

Ich habe mal in der Firmware nachgesehen, der zurückgegebene Wert wird auf 1 gesetzt, wenn bei der Berechnung etwas kleineres rauskommen sollte (siehe hier). Das heißt die 0 (als Rohwert) bedeutet wirklich, dass der Sensor saturiert ist (siehe hier). Das sind die einzigen beiden Stellen, an denen der Illuminance-Wert zugewiesen wird.

Gruß,
Erik

Link to comment
Share on other sites

Hallo Erik,

nein das sind Rohwerte, und sie wurden via Callback eingeliefert (falls das einen Unterschied ausmachen sollte).

Auch heute Nacht ist wieder zig mal eine 0 im Log vorhanden, es oszilliert dann zwischen 0 und 1 (siehe Screenshot)1092937674_Bildschirmfoto2020-04-07um09_21_28.png.75fbe2ec93942c3819214e55f7b43874.png

Der Callback ist mit 1000ms gesetzt.

André

 

Link to comment
Share on other sites

Nachtrag: Ich habe das gesamte Log nochmals durchgesehen. So sehen die Daten davor aus (Achtung, Zeiten sind UTC also zwei Stunden Versatz):

2035003335_Bildschirmfoto2020-04-07um10_37_38.png.872fcb0beba0eedc1fcca930e21e45c2.png

Also um 0:22 Uhr bin ich glaube ich zu Bett gegangen und hab das Licht ausgeknipst ;)

Wie man sieht, hat das Bricklet dann auch brav nochmal ne "1" geschickt und sich dann auch schlafen gelegt.

Um 6:13 wird vermutlich schon die Morgendämmerung eingesetzt haben, jedenfalls oszilliert es ab da noch ne Weile (ca. 20 Minuten) zwischen 0 und 1 bevor dann die ersten "richtigen" Werte auftauchen.

Kann es also sein, daß dieses Status-Flag "ALS_Data_Valid" (ja, ich hab mich mal durchs Datenblatt gewühlt) auch bei zu kleinem Wert gesetzt wird? Leider schweigt sich das Datenblatt dazu ja aus.

Was mir zudem aufgefallen ist: Wenn das Bit gesetzt ist, wird ja anscheinend kein Read-Kommando über den I2C geschickt. Offenbar wird durch das Auslesen des letzten Bytes aber irgendwas im Chip angetriggert (siehe Seite 19: "When the I2C read operation starts, all four ALS data registers are locked until the I2C read operation of register 0x8B is completed.")

André

Link to comment
Share on other sites

Das Datenblatt schweigt sich darüber aus was ALS_Data_Valid heißt. Experimentell zeigt sich aber, dass das auf Invalid geht wenn der Messwert intern im Sensor zu groß wird. Das kannst du selbst mit einer Lichtquelle nah am Sensor testen. Dazu am besten die Illuminance Range auf Unlimited stellen. Bis zu einer bestimmten Helligkeit misst der Sensor noch und dann kommt springt er auf Invalid. Daher habe ich daraus abgeleitet, dass der Sensor dann gesättigt ist, bzw. der interne Messwert überläuft. Dazu passt auch, dass der Wert bei dem da passiert kleiner wird je länger die Integration Time ist.

Aus dem Datenblatt geht nicht zwingend hervor, dass man den Messwert auslesen MUSS wenn das Status Register sagt, dass ein neuer Wert vorliegt. Wenn das so wäre, dann würde kein neuer Wert vom Sensor mehr geliefert, wenn der Wert einmal Invalid gewesen wäre und das Bricklet ihn dann nicht ausgelesen hätte. Der Hinweis auf Seite 19 besagt nur, dass man zwingend alle 4 Register des Messwertes auslesen muss, wenn man das erste Register gelesen hat. Das hat den Zweck zu verhindern, dass der Sensor den Messwert in den 4 Registern ändert während das Bricklet den Wert ausließt. Wenn das passieren würde, dann könnte es vorkommen, dass das Bricklet die ersten 2 Register gelesen hat, dann den Sensor die 4 Register aktualisiert und das Bricklet dann die letzten 2 Register liest, die aber jetzt einen Wert beinhalten der nicht mehr zu den 2 schon gelesenen Registern gehört, der Wert also verfälscht ist. Da das Bricklet aber immer alle 4 Register in der Reihenfolge und am Stück ausließt wie es das Datenblatt vorschreibt, kann das nicht das Problem sein.

Link to comment
Share on other sites

Mit welchen Einstellungen arbeitet du da genau?

Welche Illuminance Range?

Welche Integration Time?

Hast du den Callback mit value-has-to-change auf true oder false bei 1000ms Periode laufen?

Was hast du sonst noch so an Bricks und Bricklets in deinem Aufbau und wie sind die verbunden?

Ist auf allen Bricks und Bricklets die aktuelle Firmware (Brick Viewer zeigt das an)? Wenn nicht, ändert ein Update etwas an dem Verhalten?

Sprich, ich würde gerne deine Aufbau möglichst exakt nachbauen, um zu sehen ob ich das Problem nachstellen kann.

Link to comment
Share on other sites

Ich schicke Dir am besten mal einen Screenshot aus dem Brick Viewer:

1503179198_Bildschirmfoto2020-04-07um20_16_38.png.e314b0c396b7ce5c341769e67703eaa6.png

Das ist der komplette Aufbau für meine Wetterstation.

Die Versionen sind alle aktuell wenn ich das richtig sehe.

Die Initialisierung des Bricklets sieht so aus:

/* Messbereich und Integrationszeit: */
ambient_light_v3_set_configuration(bl_light, AMBIENT_LIGHT_V3_ILLUMINANCE_RANGE_32000LUX, AMBIENT_LIGHT_V3_INTEGRATION_TIME_100MS);
ambient_light_v3_set_status_led_config(bl_light, AMBIENT_LIGHT_V3_STATUS_LED_CONFIG_OFF);

/* Callback für Umgebungshelligkeit: 1s */
ambient_light_v3_register_callback(bl_light, AMBIENT_LIGHT_V3_CALLBACK_ILLUMINANCE, (void (*)(void))cb_illuminance, NULL);
ambient_light_v3_set_illuminance_callback_configuration(bl_light, 1000, true, AMBIENT_LIGHT_V3_THRESHOLD_OPTION_OFF, 0, 0);

Wie gesagt, ich hab schon bemerkt daß der Sensor bei Sonne im Freien recht schnell in die Sättigung läuft wenn man eine der höheren Integration Times nimmt, deshalb hab ich erstmal so angefangen und will es eventuell noch anpassen. Ich würde lieber mit einer längeren Integration time arbeiten damit es nicht so "rauscht".

 

Link to comment
Share on other sites

Ich habe das jetzt mal nur mit Ambient Light Bricklet 3.0 an einem Master Brick per USB angeschlossen seit gestern Laufen lassen, mit deinen Einstellungen, und das Problem tritt nicht auf. Ich habe das noch nicht in deinem Gesamtaufbau getestet.

Link to comment
Share on other sites

Merkwürdig, ich habe den Aufbau hier die letzen beiden Tage auch mal kontinuierlich durchlaufen lassen und immer das gleiche beobachtet: Sobald ich im Arbeitszimmer das Licht ausmache wenn ich zu Bett gehe geht es gleich auf "1" und immer so gegen Morgen um kurz nach sechs beginnt dann die Phase wo es zwischen "0" und "1" wechselt.

Ich habe ja das ganze in so einem weißen Kunststoffgehäuse drin, vielleicht simulierst Du das mal mit einem Joghurtbecher?

Die Status-LED hast Du auch deaktiviert, nehme ich an … denn die wirkt ja wie ein Scheinwerfer ;)

 

Link to comment
Share on other sites

Ja, Status LED ist aus.

Dieser feste zeitliche Ablauf lässt mich denken, dass das Bricklet da korrekt misst und du wirklich kurzzeitig Sättigung sieht. 6:13 Uhr ist nah an Sonnenaufgang dran. Ist das vielleicht irgendeine Reflektion (CDs im Obstbaum des Nachbarn?) oder sonstige Lichtquelle die da morgens auftritt? Teste doch nochmal mit dem Kochtopf. Wenn das ein Problem/Fehler mit dem Bricklet ist, dann müsste das ja auch unter dem Topf auftreten. Wenn das ein Effekt der Umgebung ist dann schirmt der Topf das vielleicht ab.

Link to comment
Share on other sites

Also ich sitze hier im 6. Stock (über den Bäumen) und die beiden Fenster im Arbeitszimmer gehen nach Norden und Westen, da ist frühestens ab sechs Uhr Abends mal direkte Sonne (Arbeitnehmerwohnung halt xD)

Es tritt definitiv auch unter dem Topf und mit dem Brick Viewer auf, ist aber etwas schwieriger hinzukriegen weil man wirklich nur ein winziges Bisschen Licht herein lassen darf. Aber wenn man es geschafft hat sieht man es auch im Brick Viewer zwischen dem kleinsten Messwert und "Sensor is saturated" oszillieren.

Link to comment
Share on other sites

Okay, ich kann das Problem nachstellen mit einem Stück Panzerband und zwei Stück Druckerpapier über dem Sensor. Es tritt auch häufiger auf je kleiner der Messbereich. Bei 0-600 Lux und 50 ms tritt das fast durchgehend auf in diesem Aufbau.

Ich habe mir mal testweise die Firmware so umprogrammiert, dass sie mir den Wert und das Invalid getrennt ausgibt, damit ich sehen kann welcher Wert dabei rum kommt, wenn Invalid gesetzt ist. Es kommen dann immer 0 Lux bei rum, wenn Invalid gesetzt ist in diesem Wenig-Licht-Test.

Wenn ich aber mit viel Licht teste, dann sehe ich beim Wechsel von Valid auf Invalid einen Sprung von so 60000 Lux. Ich kann also da auch nicht einfach das Invalid ignorieren.

Mit dieser Erkenntnis werde ich erstmal die Dokumentation anpassen müssen und dort nicht mehr von gesättigt sprechen können, sondern davon, dass sich der Sensor nicht sicher über den Messwert ist und dies bei sehr viel Licht oder sehr wenig Licht auftreten kann.

Zusätzlich könnte man die API des Bricklets erweitern, um den Illuminance Wert und das Invalid Flag getrennt abfragen zu können, und nicht so wie jetzt in einen Wert gemischt.

Ich habe dir mal zum Testen eine Firmware Version angehängt, die das Invalid Flag einfach ignoriert.

ambient-light-v3-bricklet-firmware-202-no-invalid.zbin

Link to comment
Share on other sites

Aha, da kommen wir der Sache ja schon näher :)

Im Moment (das heißt, für meinen Testaufbau) behelfe ich mir jetzt folgendermaßen:

void cb_illuminance(uint32_t illuminance, void *user_data)
{
	switch (illuminance)
	{
		case 0:
			packet_enqueue(VALUE_EVENT, EV_ILLUMINANCE_INVALID);
			break;

		case 1:
			packet_enqueue(VALUE_ILLUMINANCE, 0);
			break;

		default:
			packet_enqueue(VALUE_ILLUMINANCE, illuminance);
			break;
	}
}

Wenn das Callback 0 liefert wird der Wert also überhaupt nicht zusammen mit den anderen Werten geloggt (sondern in einer Art "Event-Kanal" geschrieben damit ich es mitbekomme) und bei 1 setze ich es hart auf 0 und ansonsten wird er normal durchgereicht.

Ist natürlich unschön, Status und Daten gemischt in einer Variable. Deshalb würde ich folgendes auch begrüßen:

vor 57 Minuten schrieb photron:

Zusätzlich könnte man die API des Bricklets erweitern, um den Illuminance Wert und das Invalid Flag getrennt abfragen zu können, und nicht so wie jetzt in einen Wert gemischt.

 

Das wäre sicherlich die bessere Lösung, auch das "Maximalwert +0,01 Lux" zum Erkennen einer Überschreitung ist nicht gerade optimal …

 

Edited by André K.
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...