implement incident bh1750 sensor and lux ev calculation
This commit is contained in:
parent
4832f6a365
commit
c238ad34ae
114
lightmeter.ino
114
lightmeter.ino
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue