Browse Source

change ev calculation and calibration to log(analog reading) and add digital timetable and ev calculation bugfix

master
interfisch 4 years ago
parent
commit
0d2cbe50bb
  1. BIN
      calibration/20180413_calibration.ods
  2. BIN
      calibration/20180413_high_log_5coeffs_greater2.png
  3. BIN
      calibration/20180413_low_log_4coeffs_less2.7.png
  4. 32
      calibration/calibration.py
  5. 129
      lightmeter.ino

BIN
calibration/20180413_calibration.ods

Binary file not shown.

BIN
calibration/20180413_high_log_5coeffs_greater2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
calibration/20180413_low_log_4coeffs_less2.7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

32
calibration/calibration.py

@ -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

@ -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…
Cancel
Save