Logarithmic sensor data

I have an AMBI light sensor from Liquidware all set up and working. It provides input on an analog pin as opposed to a pulse like on the more popular TAOS sensor. However, it is also logarithmic. My question is, how would I go about converting the value from this sensor to something more useful, such as lux? If it was linear I could use a map command because I know the range of it, but I don think that'll work in this case. Any help is appreciated.

The data sheet for the sensor should show a graph of sensor output vs. real world conditions. If the sensor is truly logarithmic, one axis should be linear, the other powers of 10 or e, depending on the log function, and the graph should be a straight line.

A link the sensor's data sheet would be helpful.

Depending on the accuracy you are looking for, you might create a lookup table with a few points, and interpolate between the points for other values.

Here's the datasheet: http://sharp-world.com/products/device/lineup/data/pdf/datasheet/ga1a1s201wp_e.pdf. Accuracy is important in my project.

The chart at the top of page 4 implies that current is a function of light intensity. Since the Arduino is capable of reading voltage on the analog pins, how are you connecting this sensor? Is it part of come additional circuit?

Nope. What amounts to pin 1 to ground, pin 3 to an analog pin, and pin 4 to +5v. Example code is available on this page, where I bought it from: http://www.liquidware.com/shop/show/SEN-LTE/AMBI+Light+Sensor

According to the data sheet:

*1 Sensor output vs. illuminance is logarithmic. IO = 10 × log(EV) in [ch956]A.
*2 EV = Illuminance by CIE standard light source A (tungsten lamp).

EV = 10( IO / 10 ) <<That’s 10 raised to the powerof…
I don’t know how hard this would be to implement with an arduino. I doubt that…

int EV;
int outputCurrent;

outputCurrent = outputCurrent / 10;
EV = 10 ^ outputCurrent;

…would work. I don’t even know if the “^” works like “raise to the power of…”.Easy enough to do with a calculator…

I would certainly like for someone to educate us on how to carry out more advanced arithmetic with an arduino. (I have no formal training with programming other than what I taught myself)

Nope. What amounts to pin 1 to ground, pin 3 to an analog pin, and pin 4 to +5v.

The sensor AndyJarosz linked to wasn’t on a breakout board. There IS extra circuitry. It looks like there is a filter capacitor and a 100K resistor(presumably to ground). The resistor would allow for reading the current output from the sensor as a voltage. V = I * R. Since IO ranges from pretty much zero Amps to 45uA… Voltage ranges from 0 to (45 x10-6) * 100,000 = 4.5V

It is important to understand why things work the way they do. :wink:

Musta slipped my mind, oh well.

I'll try playing with that code and tell you how it goes. Math was never my strong subject--so we'll see just how this goes...

I don't even know if the "^" works like "raise to the power of.."

Well, there's always the pow function, if it doesn't.

If that works, the output should be in lux ranging from ~0 to ~55,000… Again, I don’t think math works like that in c/c++, but maybe it will work. Oh… I just realized that the value for outputCurrent can’t be measured by the arduino directly. If you have that breakout board that PaulS said he has, you would just use analogRead() to calculate the outputCurrent… It gets more complicated from here. We really need someone who better knows how to do this math in c/c++.

The fscale function looks like it may be useful as well. I don't know how to make a link that has a different name than its own address. Anyway: http://arduino.cc/playground/Main/Fscale

Er, well. This returns a constant value of "0.00"

double Light = analogRead(5) / 10;
double EV = pow( Light, 10 );

If I take the value of Light, it appears to be working fine. EV is constantly 0 though. Yes, I have math.h included.

I don't know how to make a link that has a different name than its own address.

Select the word or phrase that you want to be the link. Then, select the URL button. Then, after the url, but before the ], insert = and the URL address, so it looks like this some phrase...

Shouldn’t that be 10Light, rather than Light10?

Ehh… it should be more like this…

double Light = analogRead(5) / 10;
double EV = pow( 10, Light );

Light = 10^(outputCurrent)
We need to get the output current… Which is from 0 to 45uA (that is micro-amps 45/1,000,000 Amps).
outputCurrent = voltageMeasured / 100,000
The problem with this is that the arduino wont see values so small as 45 * 10 ^ -6 even if double worked. This is where I get confused. We need to scale the values to something preferably whole and > 1.

Ok… So I looked at the data sheet again and realized that the output of that equation is in uA and not A. That being said, here is the math you need to make work on the arduino:

IO = V / 100,000
Light = 10 ^(IO * 100,000)

Something like…

double voltage;
double outputCurrent;
double Light;

void setup() {


void loop() {

voltage = (float)analogRead(5);
outputCurrent = voltage * 5.00 / 1023.00; //losing accuracy here
Light = pow(10, outputCurrent);


Serial.print("Voltage = ");
Serial.print("Light = ");


I tried this with a potentiometer in place of the sensor and it works.[/edit]

How about this:

double outputCurrent = map(analogRead(5),0,1023,1000, 10000);

This maps the analog values from 1000-10000 instead of 0-1023.

EDIT: Disregard, trying the above code now ::)

The voltage printed should range from ~0V to ~4.5V (probably wont get that high without really bright light)

[edit]The voltage doesn't output with appropriate decimal places. Looking into that right now..[/edit] [edit]The updated code works.[/edit]

The code does indeed work, thank you so much. I don't have a lux meter to confirm the readings, but I do have a DSLR. It reads about 71300 lux in direct sunlight, which equates to an EV of about 15--pretty much dead on.

One note is that I don't think that 4.5 is the the high value, as I was getting around 4.3V with a reading of about 5400 lux.

However, a problem: on my workbench here I'm reading about 200 lux, but if I shine that 5400 lux light on it then take it away, the reading remains about 2000 and continues to fluctuate, but does not go down to the previous (far more accurate) reading.

Do you have a link to some information on your breakout board? It could be caused by a multitude of things. For instance, the on-board capacitor could be storing enough of the energy to sustain that reading for some duration. There would be a lot of calculations involved for that and I don’t even know what the value of that cap is. That is pretty unlikely to be the problem, though. Do you think it is the code? Does it “lock” onto a value? Does the value slowly drop after removing the light source?