Ich habe Mühe, eine echte Umrechnungsformel zu finden, um den RAW-Wert in ein sinnvolles Ergebnis umzuwandeln. Ich verwende einen OPT3001- Sensor von TI und ATTiny25 als MUC.
Ich habe ein Beispiel online gefunden, aber es gibt nicht den richtigen Wert in Lux an, die dort verwendete Gleichung lautet wie folgt:
/*Convert to LUX*/
//extract result & exponent data from raw readings
result = raw&0x0FFF;
exponent = (raw>>12)&0x000F;
lux=0.01*pow(2,eksponent)*result;
Dies ergibt laut meinem Luxmeter, den ich als Referenz habe, falsche Werte, und zum Beispiel sagt das Luxmeter 420 Lux im Büro. Die obige Gleichung gibt mir das Ergebnis 110 Lux , was nicht realistisch ist. Der Sensor funktioniert einwandfrei, als ich ihn durch einen neuen ersetzte, um zu 100% zu sagen, dass es sich nicht um ein sensorbezogenes Problem handelt.
Das Ergebnis ist sehr nah, wenn ich nur nehme result = raw&0x0FFF;
, aber dann schlägt es bei höheren Werten fehl (wenn ich meinen Sensor unter die Glühbirne der Lampe halte).
Ich glaube nicht, dass es ein Fehler in meinem I2C-Code ist, aber ich werde hier auch den Teil meines Codes für UpdateLight anhängen:
// I2C OPT address
#define OPT_ADDR_W 0x88
#define OPT_ADDR_R 0x89
// I2C OPT registers
#define OPT_RESULT_REG 0x00
#define OPT_CONFIG_REG 0x01
// OPT config bits - automatic full scale mode, 100 ms conversion, single-shot
#define OPT_CONFIGURATION_H 0xC2
#define OPT_CONFIGURATION_L 0x00
void UpdateLight(void)
{
uint8_t error = 0;
// start conversion
I2C_Start();
error |= I2C_Write(OPT_ADDR_W);
error |= I2C_Write(OPT_CONFIG_REG);
error |= I2C_Write(OPT_CONFIGURATION_H);
error |= I2C_Write(OPT_CONFIGURATION_L);
I2C_Stop();
// wait for conversion
_delay_ms(150);
// set result register
I2C_Start();
error |= I2C_Write(OPT_ADDR_W);
error |= I2C_Write(OPT_RESULT_REG);
I2C_Stop();
// read data and update scratchpad
I2C_Start();
error |= I2C_Write(OPT_ADDR_R);
if (error == 0)
{
scratchpad[1] = I2C_Read(1);
scratchpad[0] = I2C_Read(0);
}
else
{
// report error value
scratchpad[1] = 0xFF;
scratchpad[0] = 0xFF;
}
I2C_Stop();
}
Und das ist meine alte Formel, die ich mir ausgedacht habe, aber sie liefert noch lächerlichere Ergebnisse als die obige aus dem Internet:
// calculate light ( LUX = (MANTISA << EXPONENT) / 100 )
light = (int16_t)((float)((uint32_t)((spad[SPAD_MSB] << 8) | spad[SPAD_LSB]) << (uint32_t)((spad[SPAD_MSB] >> 4) & 0x0F)) / (83865.60 / LIGHT_MULTIPLIER));
debug_printf("L_RAW: %02X%02X\r\n", spad[SPAD_MSB], spad[SPAD_LSB]);
debug_printf("L_VAL: %d\r\n", light);
Hinzufügen der Ausgabezeilen der obigen Druckanweisungen:
L: 5460 - 824
L: 5464 - 824
L: 5462 - 824
L: 5462 - 824
Der erste Wert sollte RAW MSB und LSB sein, und der zweite ist der konvertierte Wert in Lux, unter Verwendung der obigen Formel.
Außerdem bin ich überrascht, dass TI im Datenblatt keine Umrechnungsformel angegeben hat?
Jede Hilfe wird sehr geschätzt.
Auf Seite 20
des Datenblattes ist die detaillierte Beschreibung der Berechnung gegeben. Aus dem angegebenen Beispielwert aus den Kommentaren 0x5461
erhalten wir den 0x5
Wert für den Exponenten, der 0.32 lux per LSB
. Die Mantisse ist 0x461
oder 1121 in Dezimalzahl. Der resultierende Wert liegt 1121*0.32=358.72lux
nahe am erwarteten Bereich.
Der funktionierende Konvertierungscode:
#include <stdio.h>
#include <stdint.h>
int main(void) {
uint16_t raw = 0x5461;
uint16_t result, exponent;
float lux;
result = raw & 0x0FFF;
exponent = (raw>>12) & 0x000F;
lux=0.01*(1<<exponent)*result;
printf("%f\n", lux);
return 0;
}
Oder führen Sie es hier aus .
Bitte achten Sie genau auf die verwendeten Datentypen, diese könnten Ihnen ebenfalls Probleme bereitet haben.
463
in Hex sind.lux
ein subjektives Maß ist (angepasst an das menschliche Auge), das neben der Intensität stark von den Wellenlängen beeinflusst wird. Sie müssen also bei der Messung unbedingt für beide Sensoren identische Bedingungen schaffen. Und Sie können einen kontinuierlichen Test durchführen, um zu überprüfen, wie sich die Werte ändern, wenn das Licht erhöht oder verringert wird. Wenn sie sich allmählich ohne große Sprünge ändern, ist dies ein guter Hinweis darauf, dass sie korrekt gemessen wurden (bis zur Vorspannung des Sensors..)
Eugen Sch.
David Kasabji
Eugen Sch.
David Kasabji
Eugen Sch.
Eugen Sch.
David Kasabji
Passant
Eugen Sch.
Passant
Eugen Sch.
Bence Kaulics