Thin film thickness using digital light sensor

So I have this project I am working on for a thin film solar cell research lab at my university…

Using this equation: t = (ln(It/Io))/-a) {where It is the light transmitted, Io is the initial light (light incident on the material) and a is a known constant} you can come up with a pretty decent measurement of the thickness of the thin film layer deposited on the substrate (glass).

So here’s the layout of what I want to do…

I believe I have the design and concept worked out pretty well. I just suck at programming…trying to learn tho!

Grove digital light sensor in a black box. Led faces sensor. Slot to drop sample slide in question in between LED and sensor. All scattering of light will be minimized in design of the black box…those details are not important here. Adafruit LCD display on the front to display measurement values.

So this is how I want the program to run:
Turn unit on
LCD display(“Calibrate? Press a button…”)
Press a button on LCD to begin
get calibrationValue /calibration value will be light transmitted without slide in box (Io) LED turns on milliseconds before sensor. Senor “turns on” starts collecting light data for 5 seconds. Average of data collected (data point each second/5) is stored in calibrationValue/
LCD display(“Ready for Transmission. Press any button…”) /Program stops and waits for user input so user can load slide in box/
Press Button
get testValue /* (It)/*
display(calibrationValue)
display(testValue)

thickness= (log(It/Io)/log(2.71828))/-100000) /ln(x) is not a usable function with arduino but log(x) is. ln(x)=log(x)/log(2.71828). 100000 is the a we will be using./

display(thickness)
display (“Run another test?”)
If yes
repeat program
else do nothing

So I haven’t yet bought the LCD screen. I will cross that bridge of code when it comes. For now I have been trying to use the serial monitor, but to no avail.

Here is the code I have come up with so far:

``````#include <Wire.h>
#include <Digital_Light_TSL2561.h>
#include <math.h>

int ledPin = 13;
int inputRead = 0;
int calcThickness(int trans, int initial)//It = I transmitted; I0 = I initial
{
int result;
result = (log(trans/initial)/log(2.71828))/-100000;
}

void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("Begin calibration? y/n");
pinMode(ledPin, OUTPUT);
}
void loop()
{
while (Serial.available())
{
inputRead = Serial.read();

if (inputRead == 'y')
{
while (millis () <10200<0)
{
digitalWrite (ledPin, HIGH);
delay(5);
while (millis () <10000<0)
{
TSL2561.init();
digitalWrite (ledPin, HIGH);
unsigned long  Lux;
TSL2561.getLux();
}
}
int initI = ((TSL2561.calculateLux(0,0,1))/10);
Serial.print("Calibration light value is: ");
Serial.println(initI);
Serial.print("Test sample? y/n");
while (Serial.available())
{
inputRead = Serial.read();
if (inputRead == 'y')
{
while (millis () <10200){
digitalWrite(ledPin, HIGH);
delay(5);
while (millis () <10000) {
TSL2561.init();
digitalWrite (ledPin, HIGH);
unsigned long  Lux;
TSL2561.getLux();
}
}
digitalWrite (ledPin, LOW);
int testI = ((TSL2561.calculateLux(0,0,1))/10);
Serial.print("Transmission light value: ");
Serial.println(testI);
int thickness;
thickness = calcThickness(testI, initI);
Serial.print("Sample Thickness: ");
Serial.println(thickness);
}
}
}
else {
digitalWrite(ledPin, LOW);
Serial.print('Waiting for input');
}
}
}
``````

I tried setting up the calculation as a function as one tutorial out there showed me. But other tutorials have shown me other ways of doing math within the program that might be easier. I might revert to doing it a different way.

Also, I tried just purely making this raw calculation with the arduino and it seems the variable I am using are not correct. In one attempt I used int for “thickness” or the result of the equation and got a serial print of inf (infinity). Changed it to a float and it gave me a really long negative number.

Also, I believe there is an issue with all my if and while functions and using serial commmands.

ANY help would be GREATLY appreciated! Been messing with this for a few weeks now with not much success.

Thanks,
Tim

here are the results of what happens in the serial monitor....

Begin calibration? y/n
Calibration light value is: 0
Test sample? y/n30068Calibration light value is: 0
Test sample? y/n30068Calibration light value is: 0
Test sample? y/n300683006830068Calibration light value is: 0
Test sample? y/n300683006830068Calibration light value is: 0
Test sample? y/n30068Calibration light value is: 0
Test sample? y/n30068

commands were y,y,n,y,n,y

and the led is not turning on now

Your use of integer variables is a problem. In the function below one line in particular stands out:

``````int calcThickness(int trans, int initial)//It = I transmitted; I0 = I initial
{
int result;
result = (log(trans/initial)/log(2.71828))/-100000;
}
``````

"log(trans/initial)" is not a valid function call, because the argument to log() is of type double (or float, on an Arduino) and I'm surprised that the compiler would allow it. The compiler is probably doing an integer divide, reducing accuracy or worse, if trans is less than initial (which probably is the case), you would be taking the log of zero.

Finally, it is not a good idea to store the result of the calculation, which is of type double (or float) in "result", an integer. I believe you also need to add a line "return result;" at the end of the function.

Incidentally log() calculates the natural logarithm to the base e, or ln in your notation.

I suggest something like:

``````#define a -100000.
float thickness(int trans, int initial) {
float ft = trans;
float fi = initial;
return log(ft/fi)/a;
}
``````

The equation for film thickness does not look correct.
I think that you can make this work but need at least different colour light sources, and should go to the library and find a book on "Optics" by "Hecht and Zajak".