# Current Amplifiers

That should be simple enough by using Ohm's law... Once you read the voltage you can convert it to lux by using lux = 150 * uA... according to your results and with a little rounding I put the data into WolframAlpha polynomial calculator and got a nice simple straight line (after converting 1uA to 150lx and 30uA to 4500 lux).

Your circuit converts current to voltage, so you have a nice lux to voltage converter. With 56k, just use Ohm's law. 1uA on 56k = 56mV.

Looks like 160lx per 1uA (8000lx/50uA), so 160lx/uA divided by 56mV/uA = 2.857lx/mV at the output of the Op Amp. That'll top out before 20,000lx at about 7V, so you might want to scale that so the max you need to measure fits under 5V.

BTW, the 0.47uF across the 56k resistor is a lowpass filter already.

@polymorph

i changed my circuit to the one attached below: It has a 68k resistor added in

does that just mean i do the same but just treat

the resistance as 124k

The current measurement is just from the photodiode itself

Well... the Op Amp should provide enough voltage, and therefore enough current, through the 56k resistor to keep the inverting input at 0V, and therefore no current should flow through the 68k resistor.

It is like having a second input with zero volts on it. So no, you don't count it towards the gain of the current to voltage from the photodiode. The gain is still Vout = -Idiode * Rf

ahh i see....so its just what you said before using 56k ohms and not using the 68k.

Right,right. Yep I think I understand that, thanks

I just need to scale it and i should be good to be go :)

@rlogiacco

Im trying to view the woolfram graph - but for some reason the images arent loading for the values you put.

Ill have to look at it later at home, thanks for you input

Although I’m not sure what the appropriate code would be to scale it. I havent done a lot of coding on arduino.

unless you just mean to do like:

int voltage = sensorValue * (7.0/1023.0);

But by doing that I feel like I am stretching the existing error rather than scaling the whole lot.

I dont know if you guys know, but im trying to write some code to activate buttons and what not

getting errors like In function 'void loop()': 163: error: a function-definition is not allowed before '{' token 199: error: expected '}' at end of input

``````//------------------------------------
//----------------
//------------------------------------

/*-------Import required libraries---------*/
#include

/*-------Declare objects----------------*/
LiquidCrystal lcd(8,9,4,5,6,7);

/* ---------Button Information--------------

Right: 0.00V ; 0 @ 10 bit

UP: 0.71V ; 145 @ 10 bit

DOWN: 1.61V ; 329 @ 10 bit

LEFT: 2.47V ; 505 @ 10 bit

SELECT: 3.62V ; 741 @ 10 bit

-------------------------------------------*/

/*-------Definitions--------------*/
#define BUTTON_ADC_PIN A0  // A0 is the button ADC input
#define LCD_BACKLIGHT_PIN  // D3 controls LCD backlight

// ADC readings expected for the 5 buttons on the ADC input

#define RIGHT_10BIT_ADC 0    //right
#define UP_10BIT_ADC 145     //up
#define DOWN_10BIT_ADC 329   //down
#define LEFT_10BIT_ADC 505   //left
#define SELECT_10BIT_ADC 741 //select
#define BUTTONHYSTERESIS 10  //hysteresis for valid button sensing window

//return values for ReadButtons()

#define BUTTON_NONE 0
#define BUTTON_RIGHT 1
#define BUTTON_UP 2
#define BUTTON_DOWN 3
#define BUTTON_LEFT 4
#define BUTTON_SELECT 5

//Variables

byte buttonJustPressed = false; // This will be true after a ReadButtons() call if triggered
byte buttonJustReleased = false; // This will be true after a ReadButtons() call if triggered
byte buttonWas = BUTTON_NONE; // used by ReadButtons() for detection of button events

/*---------------------------------------------------------------
setup()
Called by the Arduino framework once, before the main loop begins
----------------------------------------------------------------*/
void setup() {
// button ADC input
pinMode(BUTTON_ADC_PIN,INPUT); //ensures A0 is an input
digitalWrite(BUTTON_ADC_PIN,LOW); // ensures pullup is off on A0
lcd.begin(16,2);
//Print Starting TEXT

lcd.print("Hi");
lcd.setCursor(0,1);
lcd.print("There");

delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start: ");
delay(5000);
}

/*
Approximation of 150 lux per 1uA
V = IR , (1uA)(56k ohms) = 56mV

150lx/1uA/56mV/1uA

150lx/56mV = 2.67857lx/mV

*/

void loop() {

byte button;

// get the latest button pressed and buttonJustPressed and buttonJustReleased flags.

/*button = ReadButtons();
if(buttonJustPressed || buttonJustReleased)
{
lcd.clear();
lcd.setCursor(0,0);
}*/

lcd.clear();
lcd.setCursor(0,0);

switch(button)
{
case BUTTON_NONE:
{
lcd.clear();
lcd.setCursor(0,0);
break;
}
case BUTTON_RIGHT:
{
break;
}
case BUTTON_UP:
{
break;
}
case BUTTON_DOWN:
{
break;
}
case BUTTON_LEFT:
{
break;
}
case BUTTON_SELECT:
{
lcd.clear();
lcd.setCursor(0,0);
float photoDiode_1 = analogRead(A1);
float photoDiode_2 = analogRead(A1);
float photoDiode_3 = analogRead(A1);
float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;

float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);
float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);
float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;

float lux = 2.67857 * averageVoltage;

lcd.print(averagetoprint);
lcd.setCursor(0,1);
lcd.print(lux);
lcd.print( " Lux");

delay(5000);
break;
}
default:
{
break;
}
} // end switch case

byte ReadButtons()
{
unsigned int buttonVoltage;
byte button = BUTTON_NONE; //return no button pressed if the below checks dont write to button

//read the button ADC pin voltage

buttonVoltage = analogRead(BUTTON_ADC_PIN);

//sense ifthe voltage falls within valid voltage windows

if(buttonVoltage < (RIGHT_10BIT_ADC + BUTTONHYSTERESIS))
{
button = BUTTON_RIGHT;
}
else if (buttonVoltage >=(UP_10BIT_ADC - BUTTONHYSTERESIS))
&& buttonVoltage <=(UP_10BIT_ADC + BUTTONHYSTERESIS))
{
button = BUTTON_UP;
}
else if (buttonVoltage >=(DOWN_10BIT_ADC - BUTTONHYSTERESIS)
&&buttonVoltage <=(DOWN_10BIT_ADC + BUTTONHYSTERESIS))
{
button = BUTTON_DOWN;
}
else if (buttonVoltage >= (LEFT_10BIT_ADC - BUTTONHYSTERESIS)
&& buttonVoltage<=(LEFT_10BIT_ADC + BUTTONHYSTERESIS))
{
button = BUTTON_LEFT;
}
else if (buttonVoltage >=(SELECT_10BIT_ADC - BUTTONYHYSTERESIS)
&&buttonVoltage <=(SELECT_10BIT_ADC + BUTTONHYSTERESIS))
{
button = BUTTON_SELECT;
}
//Handle button flags for just pressed and just released events
}
}
``````

Not sure if anyone here can help, essentially im trying to use a switch case but i tried making a button function

Have a new version and cleaner version of the code

``````#include

/******************************************

******************************************/

LiquidCrystal lcd(8,9,4,5,6,7);

//define some values used by panel and buttons

int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

//read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(A0); // read value

if(adc_key_in > 1000) return btnNONE;

if(adc_key_in < 50) return btnRIGHT;

if(adc_key_in < 250) return btnUP;

if(adc_key_in < 450) return btnDOWN;

if(adc_key_in < 650) return btnLEFT;

if(adc_key_in < 850) return btnSELECT;

return btnNONE; // If all else fails

void setup()
{
lcd.begin(16,2); // start
lcd.setCursor(0,0);
lcd.print("Hi");
lcd.setCursor(0,1);
lcd.print("There");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
}

void loop()
{
lcd_key = read_LCD_buttons(); //read the buttons

switch (lcd_key)    //Depending on button pressed, perform action
{
case btnRIGHT
{
lcd.clear()
lcd.print("RIGHT");
delay(3000);
lcd.clear()
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnLEFT
{
lcd.clear();
lcd.print("Left");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnUP
{
lcd.clear();
lcd.print("Up");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnDOWN
{
lcd.clear();
lcd.print("Down");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnSELECT
{
lcd.clear();
float photoDiode_1 = analogRead(A1);
float photoDiode_2 = analogRead(A1);
float photoDiode_3 = analogRead(A1);
float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;

float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);
float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);
float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;

float lux = 2.67857 * averageVoltage;

lcd.print(averagetoprint);
lcd.setCursor(0,1);
lcd.print(lux);
lcd.print( " Lux");
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnNONE;
{
break;
}
}//end switch case
} // end void loop
``````

errors:

In function 'int read_LCD_buttons()': 42: error: a function-definition is not allowed here before '{' token 57: error: a function-definition is not allowed here before '{' token 139: error: expected `}' at end of input

Here is the code with some fixes (I'm at work and so I can't build it myself:

``````#include

/******************************************

******************************************/

LiquidCrystal lcd(8,9,4,5,6,7);

//define some values used by panel and buttons

int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

//read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(A0); // read value

if(adc_key_in > 1000) return btnNONE;

if(adc_key_in < 50) return btnRIGHT;

if(adc_key_in < 250) return btnUP;

if(adc_key_in < 450) return btnDOWN;

if(adc_key_in < 650) return btnLEFT;

if(adc_key_in < 850) return btnSELECT;

return btnNONE; // If all else fails
} // << THIS WAS MISSING

void setup()
{
lcd.begin(16,2); // start
lcd.setCursor(0,0);
lcd.print("Hi");
lcd.setCursor(0,1);
lcd.print("There");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
}

void loop()
{
lcd_key = read_LCD_buttons(); //read the buttons

switch (lcd_key)    //Depending on button pressed, perform action
{
case btnRIGHT: //<< missing colon
{
lcd.clear(); // << missing semi-colon
lcd.print("RIGHT");
delay(3000);
lcd.clear(); // << missing semi-colon
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnLEFT: // missing colon
{
lcd.clear();
lcd.print("Left");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnUP: // << missing colon
{
lcd.clear();
lcd.print("Up");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnDOWN: // << missing colon
{
lcd.clear();
lcd.print("Down");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnSELECT: // << missing colon
{
lcd.clear();
float photoDiode_1 = analogRead(A1);
float photoDiode_2 = analogRead(A1);
float photoDiode_3 = analogRead(A1);
float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;

float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);
float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);
float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;

float lux = 2.67857 * averageVoltage;

lcd.print(averagetoprint);
lcd.setCursor(0,1);
lcd.print(lux);
lcd.print( " Lux");
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("to start");
break;
}
case btnNONE: // << replaced semi-colon with colon
{
break;
}
}//end switch case
} // end void loop
``````

Thanks! that compiled. I didn’t realise i needed colons after case.

I guess i just made a lot of simple errors haha

Thanks again, ill be trying it with my project soon.

Hi again guys, more code troubles: I have got most of the functions working the way i want them ,i can take measurements of light. However I want to be able to navigate through my LCD with buttons it has. Up/down/left/right/Select

I want it such that the program starts up, displays a message. Press select then gives a choice

left for continuous measurement and right for a hold feature. If i hit left, i get the continuous measurement but whilst trying to implement a back button it means i need to a while loop and its just failing and i cant navigate through that screen. If i hit right on the first screen, i can take single measurements with a press of the button, i can keep on pressing right to make more measurements. Hitting select takes me back to the first screen.

Depending on where i am in the whole interface, sometimes buttons i dont want to do anything at the moment -do stuff anyway - i think simply because of their position within the switch case

advice in how to control my flow and maybe how to call certain cases within another case would help. Thanks in advance

``````#include

/******************************************
*
*
*
******************************************/

LiquidCrystal lcd(8,9,4,5,6,7);

/*****************************************
* Definitions
*****************************************/

int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

/* ---------Button Information--------------

Right: 0.00V ; 0 @ 10 bit

UP: 0.71V ; 145 @ 10 bit

DOWN: 1.61V ; 329 @ 10 bit

LEFT: 2.47V ; 505 @ 10 bit

SELECT: 3.62V ; 741 @ 10 bit

-------------------------------------------*/

/*******************************************
* Setup
*******************************************/
void setup()
{
lcd.begin(16,2); // start
lcd.setCursor(0,0);
lcd.print("Hi");
lcd.setCursor(0,1);
lcd.print("There");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("MENU: Press");
lcd.setCursor(0,1);
lcd.print("SELECT to start");
}

/*****************************************************
* Main loop
******************************************************/

void loop()
{
lcd_key = read_LCD_buttons(); //read the buttons
button_switch_case(lcd_key);
}

/**********************************************
* Reading the buttons
***********************************************/

int read_LCD_buttons()
{
adc_key_in = analogRead(A0); // read value

if(adc_key_in > 1000) return btnNONE;

if(adc_key_in < 50) return btnRIGHT;

if(adc_key_in < 250) return btnUP;

if(adc_key_in < 450) return btnDOWN;

if(adc_key_in < 650) return btnLEFT;

if(adc_key_in < 850) return btnSELECT;

return btnNONE; // If all else fails
}

/*********************************************************************************
* Switch case for buttons
**********************************************************************************/

void button_switch_case(int lcd_key)
{
switch (lcd_key)    //Depending on button pressed, perform action
{

/*******************************************************************************
* Right Button
*******************************************************************************/
case btnRIGHT:
{
lcd.clear();
float photoDiode_1 = analogRead(A1);
float photoDiode_2 = analogRead(A1);
float photoDiode_3 = analogRead(A1);
float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;

float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);
float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);
float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;

float lux = 2.67857 * averageVoltage;

lcd.print("SEL:BACK >:AGAIN");
lcd.setCursor(0,1);
lcd.print(lux);
lcd.print( " Lux");
delay(1000);
//if(adc_key_in<=650 && adc_key_in>=450)lcd_key=btnLEFT;

break;

}
/*******************************************************************************
* Left Button
*******************************************************************************/
case btnLEFT:
{
while(!lcd_key < btnSELECT)
{
lcd.clear();
float photoDiode_1 = analogRead(A1);
float photoDiode_2 = analogRead(A1);
float photoDiode_3 = analogRead(A1);
float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;

float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);
float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);
float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;

float lux = 2.67857 * averageVoltage;

lcd.print("SEL: BACK");
lcd.setCursor(0,1);
lcd.print(lux);
lcd.print( " Lux");
delay(1000);
}

}
/*******************************************************************************
* UP Button
*******************************************************************************/
case btnUP:
{
btnSELECT;
break;
}

/*******************************************************************************
* Down Button
*******************************************************************************/
case btnDOWN:
{
lcd.clear();
lcd.print("Calibration");
break;
}

/*******************************************************************************
* Select Button
*******************************************************************************/
case btnSELECT:
{
lcd.clear();
lcd.print("<: Continuous");
lcd.setCursor(0,1);
lcd.print(">: Hold,^ RETURN");
break;
}
/*******************************************************************************
* No Button Pressed
*******************************************************************************/
case btnNONE:
{
break;
}
}
}
``````

some of the code i currently have in the while loop etc are wrong, i was just experimenting

Thanks in advance

Figured out part of the problem:

lcd_key = read_LCD_buttons()

i ended up using a system in my while look which looks for a flag essentially, while(flag!=0)

then when it was 0 as a result of the select button, it took me back. That solves that issue to some degree

( i need to have a delay to actually see my measurement, but that means when i hit the button, it wont respond depending on when i press it because of the delay, so i just hold it instead)

My flow of navigation is so weird though, in some spots i can press random buttons and get other locations in the interface

How can I say within a case that i want to go to another case if something happens?

for example

id go:

lcd_key=read_LCD_buttons(); if(adc_key_in<850 && adc_key_in>650) { //now something in here to make me go to another case (not sure how to do that or if its possible) }

The If for that diode is 50 mA. file:///M:/Temp/ARDUINO%20UNO/DATASHEETS/bpw21r.pdf

You need to use a current limiting resistor to convert the current to a voltage that can be amplified by an op amp instrumentation amplifier Ideally, you would want to convert 50 mA to 5V dc and read it with an analog input.

5V/0.050 A = 100 ohms.

If you put a 100 ohm resistor in series with it you should get a voltage readable with an analog input. Alternately, you could use a much smaller resistor and amplify the voltage with an op amp non-inverting amplifier.

http://www.linear.com/product/LT1215

Why don't you use a circuit already designed for that diode ?

https://www.google.com/search?q=photodiode+circuit&biw=1704&bih=908&tbm=isch&imgil=I__P3jnW9s4iOM%253A%253BjvpdZIDJLz99aM%253Bhttp%25253A%25252F%25252Felectronics.stackexchange.com%25252Fquestions%25252F33659%25252Fhow-do-i-connect-a-photodiode&source=iu&pf=m&fir=I__P3jnW9s4iOM%253A%252CjvpdZIDJLz99aM%252C_&usg=__qV0dOvw98JnSfROSQl4nq_PEkXo%3D&ved=0CDgQyjc&ei=MKN2VPCdHrGWigKtw4CwCQ#tbm=isch&q=BPW21R+photodiode+circuit&facrc=_&imgdii=_&imgrc=6J5smzuufwTBrM%253A%3BnXynWlFsFfR_vM%3Bhttp%253A%252F%252Fwww.xbitlabs.com%252Fimages%252Fother%252Flcd-testmethods%252Fp11.png%3Bhttp%253A%252F%252Fwww.xbitlabs.com%252Farticles%252Fmonitors%252Fdisplay%252Flcd-testmethods_5.html%3B377%3B225

Can someone please explain to me how to hide the link ?

Ive already got a working circuit now - I am working on Code now. Thank you for your input,

I think part of my problem is that, the switch case just goes in order and i cant prevent thing from occuring at certain stages. There must be a way

I think part of my problem is that, the switch case just goes in order and i cant prevent thing from occuring at certain stages. There must be a way

Can your elaborate and post your code using the CODE toolbutton above ?

You do realize that any use of delay() locks up things during that time?

raschemmel, he's using an Op Amp as a linear current to voltage converter.

EEPROM question split of - http://forum.arduino.cc/index.php?topic=283148.msg1982442#msg1982442 -

raschemmel, he's using an Op Amp as a linear current to voltage converter.

Ok. Thanks.