implement incident bh1750 sensor and lux ev calculation
This commit is contained in:
parent
4832f6a365
commit
c238ad34ae
|
@ -28,19 +28,24 @@ BH1750 lightMeter;
|
||||||
#define PIN_ON PB9
|
#define PIN_ON PB9
|
||||||
#define TIME_AUTOPOWEROFF 120000
|
#define TIME_AUTOPOWEROFF 120000
|
||||||
#define LDRDELAY 50 //minimum delay between ldr readings. Transistor for lower value pulldown resistor switches in between
|
#define LDRDELAY 50 //minimum delay between ldr readings. Transistor for lower value pulldown resistor switches in between
|
||||||
|
#define INCIDENTDELAY 100 //minimum delay between incident sensor (BH1750) readings
|
||||||
#define DEBOUNCETIME 50 //time to not check for inputs after key press
|
#define DEBOUNCETIME 50 //time to not check for inputs after key press
|
||||||
#define BUTTONTIMEHOLD 1000 //time for button hold
|
#define BUTTONTIMEHOLD 750 //time for button hold
|
||||||
|
|
||||||
#define voltage_warn 3.4 //voltage per cell //TODO implement warning
|
#define voltage_warn 3.4 //voltage per cell //TODO implement warning
|
||||||
|
|
||||||
//float shuttertimes1[]={1,1.0/2, 1.0/4, 1.0/8, 1.0/15, 1.0/30, 1.0/60, 1.0/125, 1.0/250, 1.0/500, 1.0/1000, 1.0/2000, 1.0/4000, 1.0/8000};
|
//float shuttertimes1[]={1,1.0/2, 1.0/4, 1.0/8, 1.0/15, 1.0/30, 1.0/60, 1.0/125, 1.0/250, 1.0/500, 1.0/1000, 1.0/2000, 1.0/4000, 1.0/8000};
|
||||||
float shuttertimes1[]={64,32,16,8,4,2,1,1.0/2, 1.0/4, 1.0/8, 1.0/15, 1.0/30, 1.0/60, 1.0/125, 1.0/250, 1.0/500, 1.0/1000, 1.0/2000, 1.0/4000, 1.0/8000};
|
float shuttertimes1[]={64,32,16,8,4,2,1,1.0/2, 1.0/4, 1.0/8, 1.0/15, 1.0/30, 1.0/60, 1.0/125, 1.0/250, 1.0/500, 1.0/1000, 1.0/2000, 1.0/4000, 1.0/8000};
|
||||||
|
#define SHUTTERTIMES1_MAXINDEX 19
|
||||||
String settingsnameShutterSelectionMode[]={"Analog"}; //names for tables
|
String settingsnameShutterSelectionMode[]={"Analog"}; //names for tables
|
||||||
#define MAXIMUM_SHUTTERSELECTIONMODES 1
|
#define MAXIMUM_SHUTTERSELECTIONMODES 1
|
||||||
|
|
||||||
float aperaturesFull[]={1,1.4, 2, 2.8, 4, 5.6, 8, 11, 16, 22, 32};
|
float aperaturesFull[]={1,1.4, 2, 2.8, 4, 5.6, 8, 11, 16, 22, 32};
|
||||||
|
#define APERATURESFULL_MAXINDEX 10
|
||||||
float aperaturesHalf[]={1, 1.2, 1.4, 1.7, 2, 2.4, 2.8, 3.4, 4, 4.8, 5.6, 6.7, 8, 9.5, 11, 13, 16, 19, 22};
|
float aperaturesHalf[]={1, 1.2, 1.4, 1.7, 2, 2.4, 2.8, 3.4, 4, 4.8, 5.6, 6.7, 8, 9.5, 11, 13, 16, 19, 22};
|
||||||
|
#define APERATURESHALF_MAXINDEX 18
|
||||||
float aperaturesThird[]={1, 1.1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.5, 2.8, 3.2, 3.5, 4, 4.5, 5.0, 5.6, 6.3, 7.1, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 29, 32, 36, 40, 45};
|
float aperaturesThird[]={1, 1.1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.5, 2.8, 3.2, 3.5, 4, 4.5, 5.0, 5.6, 6.3, 7.1, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 29, 32, 36, 40, 45};
|
||||||
|
#define APERATURESTHIRD_MAXINDEX 33
|
||||||
String settingsnameAperatureSelectionMode[]={"Full","Half","Third"}; //names for tables
|
String settingsnameAperatureSelectionMode[]={"Full","Half","Third"}; //names for tables
|
||||||
#define MAXIMUM_APERATURESELECTIONMODES 3
|
#define MAXIMUM_APERATURESELECTIONMODES 3
|
||||||
|
|
||||||
|
@ -51,6 +56,7 @@ float isoThird[]={12,16,20,25,32,40,50,64,80,100,125,160,200,250,320,400,500,640
|
||||||
|
|
||||||
long loopmillis=0; //only use one millis reading each loop
|
long loopmillis=0; //only use one millis reading each loop
|
||||||
long last_ldrReading=0;
|
long last_ldrReading=0;
|
||||||
|
long last_incidentReading=0;
|
||||||
long millis_lastchange=0;
|
long millis_lastchange=0;
|
||||||
long millis_lastinput=0;
|
long millis_lastinput=0;
|
||||||
|
|
||||||
|
@ -88,6 +94,7 @@ Settings userSettings= {1,1, 1,2};
|
||||||
#define OLED_RESET 4
|
#define OLED_RESET 4
|
||||||
Adafruit_SSD1306 display(OLED_RESET);
|
Adafruit_SSD1306 display(OLED_RESET);
|
||||||
|
|
||||||
|
uint16_t incident=0; //incident reading from bh1750
|
||||||
uint16_t analog_low=0; //better for low light
|
uint16_t analog_low=0; //better for low light
|
||||||
uint16_t analog_high=0; //better for bright light (higher pulldown resistor for ldr)
|
uint16_t analog_high=0; //better for bright light (higher pulldown resistor for ldr)
|
||||||
float ev=0; //calculated EV from LDR readings (reflected) or from Luxmeter (incident)
|
float ev=0; //calculated EV from LDR readings (reflected) or from Luxmeter (incident)
|
||||||
|
@ -112,6 +119,10 @@ String settingStrings[]={"ISO:","F-Stops:","Timetable:","Turn Off"};
|
||||||
#define SETTINGS_SELECTEDITEM_MAX 3 //inclusive. 2 means 3 items available
|
#define SETTINGS_SELECTEDITEM_MAX 3 //inclusive. 2 means 3 items available
|
||||||
boolean settings_itemActive=false; //item in settings selected to change value
|
boolean settings_itemActive=false; //item in settings selected to change value
|
||||||
|
|
||||||
|
#define METERINGMODE_REFLECTIVE 0
|
||||||
|
#define METERINGMODE_INCIDENT 1
|
||||||
|
uint8_t meteringmode=METERINGMODE_REFLECTIVE;
|
||||||
|
|
||||||
|
|
||||||
char tempstring[16]; //for dtostrf //dtostrf(modefactor,1,3,tempstring);
|
char tempstring[16]; //for dtostrf //dtostrf(modefactor,1,3,tempstring);
|
||||||
|
|
||||||
|
@ -123,12 +134,13 @@ void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
Serial.println("Started");
|
Serial.println("Started");
|
||||||
|
|
||||||
|
Serial.println("Init Display");
|
||||||
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
|
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.display();
|
display.display();
|
||||||
|
|
||||||
lightMeter.begin(BH1750_CONTINUOUS_HIGH_RES_MODE_2);
|
Serial.println("Init BH1750");
|
||||||
|
lightMeter.begin(BH1750_CONTINUOUS_HIGH_RES_MODE_2); //max reading=54612
|
||||||
//set measurement time (for higher resolution) http://www.raspberry-pi-geek.de/Magazin/2015/04/Digital-Light-Sensor-BH1750-am-Raspberry-Pi
|
//set measurement time (for higher resolution) http://www.raspberry-pi-geek.de/Magazin/2015/04/Digital-Light-Sensor-BH1750-am-Raspberry-Pi
|
||||||
//lightMeter.write8(71); //01000111 //high bit: 01000xxx bits 7,6,5
|
//lightMeter.write8(71); //01000111 //high bit: 01000xxx bits 7,6,5
|
||||||
//lightMeter.write8(126); //01111110 //log bit: 011xxxxx bits 4,3,2,1,0
|
//lightMeter.write8(126); //01111110 //log bit: 011xxxxx bits 4,3,2,1,0
|
||||||
|
@ -159,9 +171,6 @@ void loop() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t lux = lightMeter.readLightLevel();
|
|
||||||
|
|
||||||
|
|
||||||
handleInputs();
|
handleInputs();
|
||||||
|
|
||||||
calculateEV();
|
calculateEV();
|
||||||
|
@ -262,6 +271,7 @@ void handleInputs()
|
||||||
//Voltage
|
//Voltage
|
||||||
vbat=map(analogRead(PIN_VBAT), 0,3910,0,8400)/1000.0; //180k and 300k voltage divider. 8,4V -> 3,15V=3910
|
vbat=map(analogRead(PIN_VBAT), 0,3910,0,8400)/1000.0; //180k and 300k voltage divider. 8,4V -> 3,15V=3910
|
||||||
|
|
||||||
|
//LDR
|
||||||
if ( loopmillis-last_ldrReading>LDRDELAY )
|
if ( loopmillis-last_ldrReading>LDRDELAY )
|
||||||
{
|
{
|
||||||
if (!digitalRead(PIN_BRIGHTMODE)){
|
if (!digitalRead(PIN_BRIGHTMODE)){
|
||||||
|
@ -274,6 +284,16 @@ void handleInputs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Lightsensor BH1750
|
||||||
|
if ( loopmillis-last_incidentReading>INCIDENTDELAY )
|
||||||
|
{
|
||||||
|
incident = lightMeter.readLightLevel(); //value in lux from sensor
|
||||||
|
last_incidentReading=loopmillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Test asdf
|
//Test asdf
|
||||||
/*
|
/*
|
||||||
if ( !digitalRead(PIN_TRIGGER) ) {
|
if ( !digitalRead(PIN_TRIGGER) ) {
|
||||||
|
@ -338,6 +358,13 @@ void handleInputs_Lightmeter()
|
||||||
if ( button_hold_center ) { //Go to Settings
|
if ( button_hold_center ) { //Go to Settings
|
||||||
displaymode=settings;
|
displaymode=settings;
|
||||||
}
|
}
|
||||||
|
if ( button_center ) { //Change Refelctive - Incident
|
||||||
|
if (meteringmode == METERINGMODE_REFLECTIVE){
|
||||||
|
meteringmode = METERINGMODE_INCIDENT;
|
||||||
|
}else if (meteringmode == METERINGMODE_INCIDENT) {
|
||||||
|
meteringmode = METERINGMODE_REFLECTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (setShutter==0 && setAperature==0){ //Auto
|
if (setShutter==0 && setAperature==0){ //Auto
|
||||||
//Value Change
|
//Value Change
|
||||||
|
@ -479,6 +506,7 @@ float reciprocFloat(float p){
|
||||||
|
|
||||||
void calculateEV()
|
void calculateEV()
|
||||||
{
|
{
|
||||||
|
if (meteringmode == METERINGMODE_REFLECTIVE){
|
||||||
//ev=map(analog_low,500, 3500 ,500, 1400)/100.0; //for testing
|
//ev=map(analog_low,500, 3500 ,500, 1400)/100.0; //for testing
|
||||||
double highev=11.7400532 + 0.000216655133*analog_high + 0.00000111372253*pow(analog_high,2) + -0.000000000163800818 *pow(analog_high,3);
|
double highev=11.7400532 + 0.000216655133*analog_high + 0.00000111372253*pow(analog_high,2) + -0.000000000163800818 *pow(analog_high,3);
|
||||||
double lowev=-0.763427709 + 0.0138031137*analog_low + -0.00000576990095*pow(analog_low,2) + 0.000000000871611285*pow(analog_low,3);
|
double lowev=-0.763427709 + 0.0138031137*analog_low + -0.00000576990095*pow(analog_low,2) + 0.000000000871611285*pow(analog_low,3);
|
||||||
|
@ -491,6 +519,9 @@ void calculateEV()
|
||||||
float mix=min(1.0, max(0.0,(lowev-12.5)/(14-12.5))); //0 to 1, 0-> use only lowev, 1-> use only highev
|
float mix=min(1.0, max(0.0,(lowev-12.5)/(14-12.5))); //0 to 1, 0-> use only lowev, 1-> use only highev
|
||||||
ev=lowev*(1-mix)+highev*mix;
|
ev=lowev*(1-mix)+highev*mix;
|
||||||
}
|
}
|
||||||
|
}else if (meteringmode == METERINGMODE_INCIDENT){
|
||||||
|
ev = luxToEv(incident);
|
||||||
|
}
|
||||||
|
|
||||||
if (setAperature>0){ //Aperature Priority
|
if (setAperature>0){ //Aperature Priority
|
||||||
showAperature=setAperature; //use user set Aperature
|
showAperature=setAperature; //use user set Aperature
|
||||||
|
@ -506,6 +537,16 @@ void calculateEV()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double evToLux(double ev) {
|
||||||
|
return pow(2, ev) * 2.5;
|
||||||
|
}
|
||||||
|
double luxToEv(uint16_t lux){
|
||||||
|
if (lux <= 2){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return log (lux/2.5) / log (2);
|
||||||
|
}
|
||||||
|
|
||||||
float calculateShutter(float pEv, uint16_t pIso, uint16_t pAperature) //returns calculated Shutter speed given Ev, ISO and Aperature
|
float calculateShutter(float pEv, uint16_t pIso, uint16_t pAperature) //returns calculated Shutter speed given Ev, ISO and Aperature
|
||||||
{
|
{
|
||||||
//EV = log2 ( 100* Aperature^2 / (ISO * Time ))
|
//EV = log2 ( 100* Aperature^2 / (ISO * Time ))
|
||||||
|
@ -590,9 +631,26 @@ uint8_t findAperatureIndex(float pAperature,uint8_t pMethod) //find index of clo
|
||||||
float _minDistance=90000;
|
float _minDistance=90000;
|
||||||
float _lastminDistance=100000;
|
float _lastminDistance=100000;
|
||||||
uint8_t _index=userSettings.minimumAperatureIndex;
|
uint8_t _index=userSettings.minimumAperatureIndex;
|
||||||
|
uint8_t _maxindexpossible=0;
|
||||||
|
|
||||||
|
switch(pMethod){
|
||||||
|
case 1:
|
||||||
|
_maxindexpossible=APERATURESFULL_MAXINDEX;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_maxindexpossible=APERATURESHALF_MAXINDEX;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_maxindexpossible=APERATURESTHIRD_MAXINDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
while (_lastminDistance>_minDistance) //until distance increases
|
while (_lastminDistance>_minDistance) //until distance increases
|
||||||
{
|
{
|
||||||
|
if (_index>_maxindexpossible){ //this index will be out of bounds
|
||||||
|
return _maxindexpossible;
|
||||||
|
}
|
||||||
|
|
||||||
_lastminDistance=_minDistance;
|
_lastminDistance=_minDistance;
|
||||||
|
|
||||||
switch(pMethod){
|
switch(pMethod){
|
||||||
|
@ -608,7 +666,8 @@ uint8_t findAperatureIndex(float pAperature,uint8_t pMethod) //find index of clo
|
||||||
}
|
}
|
||||||
_index++; //next
|
_index++; //next
|
||||||
}
|
}
|
||||||
return _index-2;
|
|
||||||
|
return _index-2; //use index with closest value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -641,10 +700,21 @@ uint8_t findShutterIndex(float pShutter,uint8_t pMethod) //find index of closest
|
||||||
float _minDistance=abs(pShutter-shuttertimes1[0]);
|
float _minDistance=abs(pShutter-shuttertimes1[0]);
|
||||||
float _lastminDistance=_minDistance;
|
float _lastminDistance=_minDistance;
|
||||||
uint8_t _index=0;
|
uint8_t _index=0;
|
||||||
|
uint8_t _maxindexpossible=0;
|
||||||
|
|
||||||
|
switch(pMethod){
|
||||||
|
case 1:
|
||||||
|
_maxindexpossible=SHUTTERTIMES1_MAXINDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
while (_lastminDistance>=_minDistance) //until distance increases
|
while (_lastminDistance>=_minDistance) //until distance increases
|
||||||
{
|
{
|
||||||
|
if (_index>_maxindexpossible){ //this index will be out of bounds
|
||||||
|
return _maxindexpossible;
|
||||||
|
}
|
||||||
|
|
||||||
_lastminDistance=_minDistance;
|
_lastminDistance=_minDistance;
|
||||||
|
|
||||||
switch(pMethod){
|
switch(pMethod){
|
||||||
|
@ -654,7 +724,8 @@ uint8_t findShutterIndex(float pShutter,uint8_t pMethod) //find index of closest
|
||||||
}
|
}
|
||||||
_index++; //next
|
_index++; //next
|
||||||
}
|
}
|
||||||
return _index-2;
|
|
||||||
|
return _index-2; //use index with closest value
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeISO(int8_t pchange){ //pchange>0 means more light exposure (brighter image), higher iso
|
void changeISO(int8_t pchange){ //pchange>0 means more light exposure (brighter image), higher iso
|
||||||
|
@ -801,6 +872,13 @@ void updateDisplay_Lightmeter() //Lightmeter display
|
||||||
display.print("V ");
|
display.print("V ");
|
||||||
display.print("Ev=");
|
display.print("Ev=");
|
||||||
display.print(ev);
|
display.print(ev);
|
||||||
|
display.print(" |");
|
||||||
|
display.print(incident);
|
||||||
|
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(10,10);
|
||||||
|
display.print(meteringmode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDisplay_Settings()
|
void updateDisplay_Settings()
|
||||||
|
|
Loading…
Reference in New Issue