change ev calculation and calibration to log(analog reading) and add digital timetable and ev calculation bugfix
This commit is contained in:
parent
59d59475c0
commit
0d2cbe50bb
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
|
@ -2,10 +2,15 @@
|
|||
import numpy as np
|
||||
import csv
|
||||
import matplotlib.pyplot as plt
|
||||
import math
|
||||
|
||||
xcolumn=0 #column with readings
|
||||
ycolumn=4 #column with calibration data
|
||||
ncoefs=3 #number of coefficients
|
||||
ncoefs=4 #number of coefficients
|
||||
|
||||
#mit log
|
||||
#low (0), coeffs=4,, <2.7, ab <=2.3 benutzbar
|
||||
#high (1), coeffs=5, >2 ab >=1 knapp benutzbar, ab 2 besser
|
||||
|
||||
xvalues=[]
|
||||
yvalues=[]
|
||||
|
@ -17,9 +22,9 @@ with open('20180413_calibration.csv', 'r') as csvfile:
|
|||
xvalue=row[xcolumn]
|
||||
yvalue=row[ycolumn]
|
||||
if len(xvalue)>0 and len(yvalue)>0 and not firstrow:
|
||||
xvalue=float(xvalue)
|
||||
xvalue=math.log(float(xvalue))
|
||||
yvalue=float(yvalue)
|
||||
if yvalue<=4:
|
||||
if yvalue<2.7:
|
||||
#print(""+str(xvalue)+" - "+str(yvalue))
|
||||
xvalues.append(xvalue)
|
||||
yvalues.append(yvalue)
|
||||
|
@ -28,17 +33,26 @@ with open('20180413_calibration.csv', 'r') as csvfile:
|
|||
coefs=np.polyfit(xvalues,yvalues,ncoefs) #fit polynomial curve
|
||||
print(coefs) #coef 0 is the one with highest polynomial
|
||||
|
||||
xtest=np.arange(max(xvalues)) #x values for test visualization
|
||||
xtest=np.arange(max(xvalues),step=0.001) #x values for test visualization
|
||||
ytest=np.polyval(coefs, xtest) #calculate y values with polynomial function
|
||||
#ytest=[coefs[3]+coefs[2]*pow(x,1)+coefs[1]*pow(x,2)+coefs[0]*pow(x,3) for x in xtest]
|
||||
|
||||
for i in range(200,4000,10):
|
||||
yv=np.polyval(coefs, i)
|
||||
print(str(i)+";"+str(yv))
|
||||
exit()
|
||||
#for i in range(200,4000,10):
|
||||
# yv=np.polyval(coefs, i)
|
||||
# print(str(i)+";"+str(yv))
|
||||
#exit()
|
||||
|
||||
plt.scatter(xvalues,yvalues,s=0.25,c='g') #plot sample data
|
||||
plt.scatter(xvalues,yvalues,s=0.7,c='g') #plot sample data
|
||||
plt.plot(xtest,ytest,c='r') #plot approximated curve
|
||||
plt.xlabel('LDR Value')
|
||||
plt.ylabel('Ev')
|
||||
|
||||
#plt.xlim(0,4096) #ldr
|
||||
plt.ylim(-3,20) #ev
|
||||
|
||||
#limits with lux
|
||||
#plt.xlim(0,4096) #ldr
|
||||
#plt.xlim(0,500) #ldr
|
||||
#plt.ylim(0,1280000) #ev
|
||||
#plt.ylim(0,220) #ev
|
||||
plt.show()
|
||||
|
|
129
lightmeter.ino
129
lightmeter.ino
|
@ -6,7 +6,7 @@
|
|||
|
||||
//Letters 5x7 at Size 1
|
||||
|
||||
|
||||
#include <math.h>
|
||||
//#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
|
@ -54,8 +54,10 @@ BH1750 lightMeter;
|
|||
//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 shuttertimes2[]={30,25,20,15,13,10,8,6,5,4,3.2,2.5,2,1.6,1.3,1,0.8,0.6,0.5,0.4,0.3,1.0/4,1.0/5,1.0/6,1.0/8,1.0/10,1.0/13,1.0/15,1.0/20,1.0/25,1.0/30,1.0/40,1.0/50,1.0/60,1.0/80,1.0/100,1.0/125,1.0/160,1.0/200,1.0/250,1.0/320,1.0/400,1.0/500,1.0/640,1.0/800,1.0/1000,1.0/1250,1.0/1600,1.0/2000,1.0/2500,1.0/3200,1.0/4000};
|
||||
#define SHUTTERTIMES2_MAXINDEX 51
|
||||
String settingsnameShutterSelectionMode[]={"Analog","Digital"}; //names for tables
|
||||
#define MAXIMUM_SHUTTERSELECTIONMODES 2
|
||||
|
||||
float aperaturesFull[]={1,1.4, 2, 2.8, 4, 5.6, 8, 11, 16, 22, 32};
|
||||
#define APERATURESFULL_MAXINDEX 10
|
||||
|
@ -99,7 +101,7 @@ boolean button_hold_left=false;
|
|||
boolean button_hold_center=false;
|
||||
boolean button_hold_right=false;
|
||||
|
||||
float vbat=0;
|
||||
float vbat=100;
|
||||
|
||||
struct Settings {
|
||||
uint8_t minimumAperatureIndex; //see corresponding aperatures table
|
||||
|
@ -233,6 +235,8 @@ void setup() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,7 +431,10 @@ void handleInputs()
|
|||
*/
|
||||
|
||||
//Voltage
|
||||
vbat=map(analogRead(PIN_VBAT), 0,3560,0,8200)/1000.0; //180k and 300k voltage divider. 8,4V -> 3,15V=3910
|
||||
float _vbat=map(analogRead(PIN_VBAT), 0,3560,0,8200)/1000.0; //180k and 300k voltage divider. 8,4V -> 3,15V=3910
|
||||
if (_vbat<vbat){
|
||||
vbat=_vbat; //voltage can only decrease
|
||||
}
|
||||
|
||||
//LDR
|
||||
|
||||
|
@ -483,28 +490,49 @@ void handleInputs()
|
|||
for (float i=1.0/8000;i<32;i*=2){
|
||||
Serial.print(i,6);
|
||||
Serial.print(" -> ");
|
||||
Serial.print(roundShutter(i,1),6);
|
||||
Serial.print(roundShutter(i,2),6);
|
||||
Serial.print(" -- ");
|
||||
Serial.println(reciprocFloat(roundShutter(i,1)));
|
||||
Serial.println(reciprocFloat(roundShutter(i,2)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Serial.println("calculateShutter at iso 100 f8");
|
||||
for (int8_t i=-2;i<18;i++){
|
||||
Serial.println("calculateShutter at iso 100 f2.8");
|
||||
for (float i=-2;i<18;i+=0.25){
|
||||
Serial.print(i);
|
||||
Serial.print(" -> ");
|
||||
Serial.println(calculateShutter(i, (uint16_t)100, 8.0),6);
|
||||
float test_calcshutter=calculateShutter(i, (uint16_t)100, 2.8);
|
||||
//Serial.println(test_calcshutter,6);
|
||||
|
||||
float test_showShutter=roundShutter(test_calcshutter,2);
|
||||
Serial.print("rounded Shutter from "); Serial.print(test_calcshutter,6); Serial.print(" to "); Serial.println(test_showShutter,6); //asdf
|
||||
if (test_showShutter>0.25) //check shuttertime
|
||||
{ //show full seconds
|
||||
Serial.print("int=");
|
||||
Serial.print(int(test_showShutter));
|
||||
if (test_showShutter-int(test_showShutter)>0){ //has decimals
|
||||
Serial.print(" ,");
|
||||
Serial.print((int)round( (test_showShutter-int(test_showShutter))*10)); //show one decimal
|
||||
}
|
||||
Serial.println("");
|
||||
}else{ //show fraction of a second
|
||||
Serial.print("frac= 1/");
|
||||
int _frac_showShutter = (int) ( (1.0f/( (int)(test_showShutter*1000000) ) )*1000000 );
|
||||
Serial.print( _frac_showShutter );
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("calculateAperature at iso 100 1/125s");
|
||||
for (int8_t i=-2;i<18;i++){
|
||||
Serial.println("calculateAperature at iso 100 1/250s");
|
||||
for (float i=-2;i<18;i+=0.25){
|
||||
Serial.print(i);
|
||||
Serial.print(" -> ");
|
||||
Serial.println(calculateAperature(i, (uint16_t)100, 1.0/125),6);
|
||||
Serial.println(calculateAperature(i, (uint16_t)100, 1.0/250),6);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
switch(displaymode){
|
||||
|
@ -625,6 +653,7 @@ void handleInputs_Lightmeter()
|
|||
void handleInputs_Settings()
|
||||
{
|
||||
if ( button_hold_center ) { //Go to Lightmeter
|
||||
settings_itemActive=false; //deselect item
|
||||
displaymode=lightmeter;
|
||||
}
|
||||
|
||||
|
@ -733,19 +762,49 @@ float getEV(){
|
|||
//double lowev=-0.763427709 + 0.0138031137*analog_low + -0.00000576990095*pow(analog_low,2) + 0.000000000871611285*pow(analog_low,3);
|
||||
|
||||
//calibration 20180413
|
||||
double highev=4.76455098 + 0.00961533698*analog_high - 0.00000399325586*pow(analog_high,2) + 0.000000000654378697 *pow(analog_high,3);
|
||||
double lowev=-38.9534785 + 0.310426970*analog_low - 0.000769939297*pow(analog_low,2) + 0.000000639458491*pow(analog_low,3);
|
||||
//polynomial only
|
||||
//double highev=4.76455098 + 0.00961533698*analog_high - 0.00000399325586*pow(analog_high,2) + 0.000000000654378697 *pow(analog_high,3);
|
||||
//double lowev=-38.9534785 + 0.310426970*analog_low - 0.000769939297*pow(analog_low,2) + 0.000000639458491*pow(analog_low,3);
|
||||
|
||||
|
||||
double log_low=log(analog_low);
|
||||
//[-2.47999992e+02 5.59942657e+03 -4.74076773e+04 1.78389539e+05 -2.51728845e+05]
|
||||
double lowev=-251728.845 + 178389.539*log_low - 47407.6773*pow(log_low,2) + 5599.42657*pow(log_low,3) - 247.999992*pow(log_low,4);
|
||||
|
||||
double log_high=log(analog_high);
|
||||
//[7.27310051e-02 -2.02919373e+00 2.23823220e+01 -1.22121768e+02 3.32574527e+02 -3.60445720e+02]
|
||||
double highev=-360.445720 + 332.574527*log_high - 122.121768*pow(log_high,2) + 22.3823220*pow(log_high,3) - 2.02919373*pow(log_high,4) + 0.0727310051*pow(log_high,5);
|
||||
|
||||
/*Serial.print("analog_low="); //asdf
|
||||
Serial.print(analog_low);
|
||||
Serial.print(" log_low=");
|
||||
Serial.print(log_low);
|
||||
Serial.print(" lowev=");
|
||||
Serial.println(lowev);
|
||||
|
||||
Serial.print("analog_high=");
|
||||
Serial.print(analog_high);
|
||||
Serial.print(" log_high=");
|
||||
Serial.print(log_high);
|
||||
Serial.print(" highev=");
|
||||
Serial.println(highev);*/
|
||||
|
||||
|
||||
|
||||
if (lowev>6){
|
||||
if (highev>2){
|
||||
_ev=highev;
|
||||
}else if(lowev<4){
|
||||
Serial.println("using high ev");
|
||||
}else if(lowev<1){
|
||||
_ev=lowev;
|
||||
Serial.println("using low ev");
|
||||
}else{ //mix of both
|
||||
float mix=min(1.0, max(0.0,(lowev-4)/(6-4))); //0 to 1, 0-> use only lowev, 1-> use only highev
|
||||
float mix=min(1.0, max(0.0,(lowev-1)/(2-1))); //0 to 1, 0-> use only lowev, 1-> use only highev
|
||||
_ev=lowev*(1-mix)+highev*mix;
|
||||
Serial.print("mixing mix=");
|
||||
Serial.println(mix);
|
||||
}
|
||||
Serial.print("EV=");
|
||||
Serial.println(_ev);
|
||||
}else if (meteringmode == METERINGMODE_INCIDENT){ //### INCIDENT
|
||||
_ev = luxToEv(incident*INCIDENT_CORRECTION_FACTOR);
|
||||
}
|
||||
|
@ -781,7 +840,7 @@ double luxToEv(uint16_t lux){
|
|||
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, float pAperature) //returns calculated Shutter speed given Ev, ISO and Aperature
|
||||
{
|
||||
//EV = log2 ( 100* Aperature^2 / (ISO * Time ))
|
||||
//100* Aperature^2 / (2^EV * ISO) = Time
|
||||
|
@ -802,6 +861,9 @@ float roundShutter(float pShutter, uint8_t pMethod) //round shutter to typical v
|
|||
case 1: //
|
||||
return shuttertimes1[_index];
|
||||
break;
|
||||
case 2: //
|
||||
return shuttertimes2[_index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -915,6 +977,9 @@ void changeShutter(int8_t pchange){ //pchange>0 means more light exposure (brigh
|
|||
case 1:
|
||||
_maximumShutterIndex=sizeof(shuttertimes1)/sizeof(float);
|
||||
break;
|
||||
case 2:
|
||||
_maximumShutterIndex=sizeof(shuttertimes2)/sizeof(float);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!( -pchange<0 && _newShutterIndex==0)){ //changed value would not yield negative index
|
||||
|
@ -927,6 +992,9 @@ void changeShutter(int8_t pchange){ //pchange>0 means more light exposure (brigh
|
|||
case 1: //
|
||||
setShutter=shuttertimes1[_newShutterIndex];
|
||||
break;
|
||||
case 2: //
|
||||
setShutter=shuttertimes2[_newShutterIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint8_t findShutterIndex(float pShutter,uint8_t pMethod) //find index of closest aperature from given aperature tables (pMethod
|
||||
|
@ -940,6 +1008,9 @@ uint8_t findShutterIndex(float pShutter,uint8_t pMethod) //find index of closest
|
|||
case 1:
|
||||
_maxindexpossible=SHUTTERTIMES1_MAXINDEX;
|
||||
break;
|
||||
case 2:
|
||||
_maxindexpossible=SHUTTERTIMES2_MAXINDEX;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -955,6 +1026,9 @@ uint8_t findShutterIndex(float pShutter,uint8_t pMethod) //find index of closest
|
|||
case 1:
|
||||
_minDistance=abs(pShutter - shuttertimes1[_index]);
|
||||
break;
|
||||
case 2:
|
||||
_minDistance=abs(pShutter - shuttertimes2[_index]);
|
||||
break;
|
||||
}
|
||||
_index++; //next
|
||||
}
|
||||
|
@ -1081,7 +1155,7 @@ void updateDisplay_Lightmeter() //Lightmeter display
|
|||
display.setCursor(xpos_shutter,ypos_shutter);
|
||||
float _showShutter=roundShutter(showShutter,userSettings.shutterSelectionMode);
|
||||
//Serial.print("rounded Shutter from "); Serial.print(showShutter); Serial.print(" to "); Serial.println(_showShutter); //asdf
|
||||
if (_showShutter>=1) //check time
|
||||
if (_showShutter>0.25) //check shuttertime
|
||||
{ //show full seconds
|
||||
display.print(int(_showShutter));
|
||||
if (_showShutter-int(_showShutter)>0){ //has decimals
|
||||
|
@ -1118,7 +1192,10 @@ void updateDisplay_Lightmeter() //Lightmeter display
|
|||
|
||||
|
||||
//EV Scale
|
||||
uint8_t _startev=2; //first ev to display, 13 ev values can fit on screen
|
||||
int8_t _startev=-5; //first ev to display, 13 ev values can fit on screen
|
||||
if (ev>2){
|
||||
_startev=2;
|
||||
}
|
||||
if (ev>13){
|
||||
_startev=5+ev-13;
|
||||
}
|
||||
|
@ -1134,7 +1211,7 @@ void updateDisplay_Lightmeter() //Lightmeter display
|
|||
display.drawLine(THIRDEVLINEDISTANCE,0,THIRDEVLINEDISTANCE,0,WHITE); //first third line
|
||||
display.drawLine(THIRDEVLINEDISTANCE+THIRDEVLINEDISTANCE,0,THIRDEVLINEDISTANCE+THIRDEVLINEDISTANCE,0,WHITE); //second third line
|
||||
for (uint8_t _fullevline=1;_fullevline<=13;_fullevline++){
|
||||
uint8_t _current_evvalue = _fullevline+_startev;
|
||||
int8_t _current_evvalue = _fullevline+_startev;
|
||||
uint8_t _xpos_center_evtext = _fullevline*FULLEVLINEDISTANCE; //center of current ev line x pos
|
||||
display.drawLine(_xpos_center_evtext,0,_xpos_center_evtext,2,WHITE);
|
||||
display.drawLine(_xpos_center_evtext+THIRDEVLINEDISTANCE,0,_xpos_center_evtext+THIRDEVLINEDISTANCE,0,WHITE);
|
||||
|
@ -1182,9 +1259,9 @@ void updateDisplay_Lightmeter() //Lightmeter display
|
|||
//DEBUG Message
|
||||
display.setTextSize(1);
|
||||
display.setCursor(xpos_debug,ypos_debug);
|
||||
/*display.print(vbat);
|
||||
display.print(vbat,2);
|
||||
display.print("V ");
|
||||
display.print("Ev=");
|
||||
/*display.print("Ev=");
|
||||
display.print(ev);
|
||||
display.print(" |");
|
||||
display.print(incident);*/
|
||||
|
|
Loading…
Reference in New Issue