diff --git a/calibration/20180413_calibration.ods b/calibration/20180413_calibration.ods index a20c963..5b00836 100644 Binary files a/calibration/20180413_calibration.ods and b/calibration/20180413_calibration.ods differ diff --git a/calibration/20180413_high_log_5coeffs_greater2.png b/calibration/20180413_high_log_5coeffs_greater2.png new file mode 100644 index 0000000..8f31bb8 Binary files /dev/null and b/calibration/20180413_high_log_5coeffs_greater2.png differ diff --git a/calibration/20180413_low_log_4coeffs_less2.7.png b/calibration/20180413_low_log_4coeffs_less2.7.png new file mode 100644 index 0000000..e4dca0b Binary files /dev/null and b/calibration/20180413_low_log_4coeffs_less2.7.png differ diff --git a/calibration/calibration.py b/calibration/calibration.py index cc2b06b..85e43e9 100644 --- a/calibration/calibration.py +++ b/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() diff --git a/lightmeter.ino b/lightmeter.ino index 44606f8..4e97fd8 100644 --- a/lightmeter.ino +++ b/lightmeter.ino @@ -6,7 +6,7 @@ //Letters 5x7 at Size 1 - +#include //#include #include #include @@ -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 "); - 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);*/