implement incident bh1750 sensor and lux ev calculation

This commit is contained in:
interfisch 2018-03-23 20:21:27 +01:00
parent 4832f6a365
commit c238ad34ae
1 changed files with 97 additions and 19 deletions

View File

@ -28,19 +28,24 @@ BH1750 lightMeter;
#define PIN_ON PB9
#define TIME_AUTOPOWEROFF 120000
#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 BUTTONTIMEHOLD 1000 //time for button hold
#define BUTTONTIMEHOLD 750 //time for button hold
#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[]={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
#define MAXIMUM_SHUTTERSELECTIONMODES 1
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};
#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};
#define APERATURESTHIRD_MAXINDEX 33
String settingsnameAperatureSelectionMode[]={"Full","Half","Third"}; //names for tables
#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 last_ldrReading=0;
long last_incidentReading=0;
long millis_lastchange=0;
long millis_lastinput=0;
@ -88,6 +94,7 @@ Settings userSettings= {1,1, 1,2};
#define OLED_RESET 4
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_high=0; //better for bright light (higher pulldown resistor for ldr)
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
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);
@ -123,12 +134,13 @@ void setup() {
Serial.begin(9600);
Serial.println("Started");
Serial.println("Init Display");
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
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
//lightMeter.write8(71); //01000111 //high bit: 01000xxx bits 7,6,5
//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();
calculateEV();
@ -262,6 +271,7 @@ void handleInputs()
//Voltage
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 (!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
/*
if ( !digitalRead(PIN_TRIGGER) ) {
@ -338,6 +358,13 @@ void handleInputs_Lightmeter()
if ( button_hold_center ) { //Go to 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
//Value Change
@ -479,17 +506,21 @@ float reciprocFloat(float p){
void calculateEV()
{
//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 lowev=-0.763427709 + 0.0138031137*analog_low + -0.00000576990095*pow(analog_low,2) + 0.000000000871611285*pow(analog_low,3);
if (meteringmode == METERINGMODE_REFLECTIVE){
//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 lowev=-0.763427709 + 0.0138031137*analog_low + -0.00000576990095*pow(analog_low,2) + 0.000000000871611285*pow(analog_low,3);
if (lowev>14){
ev=highev;
}else if(lowev<12.5){
ev=lowev;
}else{ //mix of both
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;
if (lowev>14){
ev=highev;
}else if(lowev<12.5){
ev=lowev;
}else{ //mix of both
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;
}
}else if (meteringmode == METERINGMODE_INCIDENT){
ev = luxToEv(incident);
}
if (setAperature>0){ //Aperature Priority
@ -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
{
//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 _lastminDistance=100000;
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
{
if (_index>_maxindexpossible){ //this index will be out of bounds
return _maxindexpossible;
}
_lastminDistance=_minDistance;
switch(pMethod){
@ -608,7 +666,8 @@ uint8_t findAperatureIndex(float pAperature,uint8_t pMethod) //find index of clo
}
_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 _lastminDistance=_minDistance;
uint8_t _index=0;
uint8_t _maxindexpossible=0;
switch(pMethod){
case 1:
_maxindexpossible=SHUTTERTIMES1_MAXINDEX;
break;
}
while (_lastminDistance>=_minDistance) //until distance increases
{
if (_index>_maxindexpossible){ //this index will be out of bounds
return _maxindexpossible;
}
_lastminDistance=_minDistance;
switch(pMethod){
@ -654,7 +724,8 @@ uint8_t findShutterIndex(float pShutter,uint8_t pMethod) //find index of closest
}
_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
@ -801,6 +872,13 @@ void updateDisplay_Lightmeter() //Lightmeter display
display.print("V ");
display.print("Ev=");
display.print(ev);
display.print(" |");
display.print(incident);
display.setTextSize(1);
display.setCursor(10,10);
display.print(meteringmode);
}
void updateDisplay_Settings()