From 737aabd03b1534c37c74f5b47d5904e96a16f7bf Mon Sep 17 00:00:00 2001 From: Fisch Date: Mon, 26 Mar 2018 17:55:17 +0200 Subject: [PATCH] add ev scale --- icon_arrow.c | 4 + icon_arrow.xcf | Bin 0 -> 777 bytes icon_incident.c | 6 ++ icon_incident.xcf | Bin 2162 -> 1300 bytes icon_one_half.c | 4 + icon_one_third.c | 4 + icon_spot.c | 6 ++ icon_spot.xcf | Bin 1353 -> 1060 bytes icon_thirds.xcf | Bin 0 -> 2554 bytes icon_two_third.c | 4 + lightmeter.ino | 222 ++++++++++++++++++++++++++++++---------------- 11 files changed, 175 insertions(+), 75 deletions(-) create mode 100644 icon_arrow.c create mode 100644 icon_arrow.xcf create mode 100644 icon_incident.c create mode 100644 icon_one_half.c create mode 100644 icon_one_third.c create mode 100644 icon_spot.c create mode 100644 icon_thirds.xcf create mode 100644 icon_two_third.c diff --git a/icon_arrow.c b/icon_arrow.c new file mode 100644 index 0000000..dfb6ecf --- /dev/null +++ b/icon_arrow.c @@ -0,0 +1,4 @@ +#define icon_arrow_width 5 +#define icon_arrow_height 8 +static unsigned char icon_arrow_bits[] = { + 0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04 }; diff --git a/icon_arrow.xcf b/icon_arrow.xcf new file mode 100644 index 0000000000000000000000000000000000000000..394fa92119670bd51149f1ace2ccb91ecf392e8f GIT binary patch literal 777 zcmb_a%TB{E5VXUqlvcbsaquxc1hu~ahr$7gUq} z5EWS_bAvsj;@Mp(LnCAHqRm`PA0D5ma?)6J7AhI2Qpcph&6!`Bbt*+wq&gn;{X|7Y zT9m?XQc$W{D8@JACOXKZEsfAR>u9xg@i(E?Rka8sohvc1|AM&g5?d`;=Gq9IM{`+G ze~~1WG+zg#?%&c@`QA$R&<6jo4B363!M)CnELFM8n|t$G-##)uPYuvp5~mk9Y&jCU zc6i_6M-Cr2eCY6Fa62QQ?7*qn(XeMh$$KUf!k!&trt{4=KRex7Pc4>W?YP2KbIBl`R0*FzImhP|+PHaRj1+PPtwQV2ixgAdIr2xa zZ4Yg2Cs-_`AH!!9?B0fQ9LuSAR`E=X?jIg0(n(U)V(dxV3)Pf3WOLSw;>}!&D445h zzu9v=CzuDJ=q1Juy~$V%t_O*ffMFWyqjXYIn#INMfJ)cVa_lJI6T|E*kef0x9q;||-I5{UP zJZM=sY(GI^tn$|XQ`7eT?5^v~(xf%k(G}Lk!s$6!u*teCI2;aH5Z}NqlBZ_1)Q9?I Gy}tl-LQhfv literal 2162 zcmeHI%We}f6!knZnY@%ffE5c@s8YHZ)bI&KsIWj{#hPT|nOaI_s+p;1S8NdMP*?C7 z>{<7x*kI0eZ0d+%0gDJBu5|3<`>>sRJvX^ro%72y$ z$pz`)?XgMSTrCB!%cWc#^(R@Lmdmo@6FntWKA-X9hsRo4$kdpQ5IS!OwRZk%LZO%S z`7D)1&ZqV)D6iU-MweU^vf;8w&qPh}WtP>V`Efyt{#muwY=%-EjCfxd3qB*;H;i>Z zSS@B-E6Q%~$y^kIKX^oTp9V+-P@NPI8?K!V$HeYCyzlUV!-ozZIeZLG`&#LO(0L^8 z8(C|ZUmIdC4qyNMrq2IF>kj*-*pP;Rd1_#=kGao$z*7k@1|MVYYVN6?4TyK}Oo@Y5!W_5}z19 TduP--ez~cOGg`kvv$FUOtF@Vv diff --git a/icon_one_half.c b/icon_one_half.c new file mode 100644 index 0000000..16291b3 --- /dev/null +++ b/icon_one_half.c @@ -0,0 +1,4 @@ +#define icon_one_half_width 5 +#define icon_one_half_height 12 +static unsigned char icon_one_half_bits[] = { + 0x04, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x06, 0x08, 0x0c, 0x02, 0x0e }; diff --git a/icon_one_third.c b/icon_one_third.c new file mode 100644 index 0000000..7191f9e --- /dev/null +++ b/icon_one_third.c @@ -0,0 +1,4 @@ +#define icon_one_third_width 5 +#define icon_one_third_height 12 +static unsigned char icon_one_third_bits[] = { + 0x04, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x06, 0x08, 0x06, 0x08, 0x06 }; diff --git a/icon_spot.c b/icon_spot.c new file mode 100644 index 0000000..4b419ff --- /dev/null +++ b/icon_spot.c @@ -0,0 +1,6 @@ +#define icon_spot_width 16 +#define icon_spot_height 16 +static unsigned char icon_spot_bits[] = { + 0x80, 0x01, 0x80, 0x01, 0xe0, 0x07, 0xb8, 0x1d, 0x88, 0x11, 0x8c, 0x31, + 0x04, 0x20, 0x3f, 0xfc, 0x3f, 0xfc, 0x04, 0x20, 0x8c, 0x31, 0x88, 0x11, + 0xb8, 0x1d, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01 }; diff --git a/icon_spot.xcf b/icon_spot.xcf index 0dfac7a9f6ded30acb06828e7ea7708277e2ce22..eb3632955d6817069b2e304f397cca99ad0480e8 100644 GIT binary patch literal 1060 zcmeHFOHRWu5Vg}UO)JWG#lp*WQBl+Y10yxL#1ZZEsF-Cx$0(IcrfH>uy!A;&CbU|j}}Z!+l>aweWsF&C4&`v;2j%TyJ6p&W&onwf0Q26?fLq{!1q&4!&p5c+A9 zW@1pfQ5H@;F}@s^wufAq&=955J*74-{w7qq$`_uml2BaPy&$gliAEbO6IBS6_;Z<4 zeHsM0EPe*0>fh2v*)64WFvj04gSYoX$KAbENg=Z^TPEeXIVP_OPgkOWw&9e2U^pDR zsPImOyA|H8@Lq)U2>EfCs|%sve}3nb^UjBIB|uJgRBIj^*CYR-Cqs~fDP9rl4g z(0Duz{lzp#z#&pA2`xCQknITrPuF7-QMtbq{n;DNYb`q=UwYUo-5vhq}u&x2|6@YU*)_~^GBVz>EI^Y2tz^368hdCc$ z?8I0$2-E3QCI#kJlsQ07yq561Wtx?LWQ5$qXJS6e3|nMkqQC!b>i>KN&K zG|)7>3^p7C+ph4X3U61qU*Vk!Uk0ajtu;WX9+|xxv`J&ml_7THh;{DgHRplmb;fmr zdHR`Y&9tjIbMzb29z8f_9pDw7CPm==eC@C{v>l)g{?q?`g|D?6s8#KUGN~vpBm+ i%Fq2T+*bSLV5_w)+Az%CRu@|EAz7_v0BY7G`GD@bQfV8032_QG2mW9VQ zwEgtG5LC!*s14nL-qo0PcVK^rwj1NM{UDvq!g+zd;NY!;EcA#xxn1ng!r%{xL#SaHL`)6vwtWM=VXt6#C z(fo+e_(C}E5QzgJya#3!tq0wLa+lrWB$a~!kZ_=kQVDHqj7FK0r`(4c+*!icmN3)7 z*mRfh4Pd_4hznrsOolLpv^3soVBCdm<9wBCd|>|q9+z%;Daux9i57uVHiTW;q6?zE z7y+wn?8-(NR*y}4&mI=gyizN_D}>E3yT#zP2Ln0rrx7=4ozZ1v>!NE41%~aHbP8hp zMRe_8K^e}@+26FN{4IapEb_DponarQC@t-;8qk)WBC$P__?q+Z4~7Hk$9t1JtDHKJ&qg6m@6HhYwJwg|t6Ll| XV=dli4UEHF+?Q3(`^Ns`a`F2P?bR9f literal 0 HcmV?d00001 diff --git a/icon_two_third.c b/icon_two_third.c new file mode 100644 index 0000000..15a6c19 --- /dev/null +++ b/icon_two_third.c @@ -0,0 +1,4 @@ +#define icon_two_third_width 5 +#define icon_two_third_height 12 +static unsigned char icon_two_third_bits[] = { + 0x06, 0x08, 0x0c, 0x02, 0x0e, 0x1f, 0x00, 0x06, 0x08, 0x06, 0x08, 0x06 }; diff --git a/lightmeter.ino b/lightmeter.ino index 9399f82..fa61272 100644 --- a/lightmeter.ino +++ b/lightmeter.ino @@ -12,6 +12,8 @@ #include #include // http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/ //128 x 64 px +#define WIDTH 128 +#define HEIGHT 64 #include //from: https://github.com/mysensors/MySensorsArduinoExamples/tree/master/libraries/BH1750 BH1750 lightMeter; @@ -27,6 +29,7 @@ BH1750 lightMeter; #define PIN_ON PB9 #define TIME_AUTOPOWEROFF 120000 +#define TIME_METERINGMODESELECTION_CLOSE 4000 #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 @@ -60,6 +63,7 @@ long last_incidentReading=0; long millis_lastchange=0; long millis_lastinput=0; + long timebuttonpressed_trigger; long timebuttonpressed_left; long timebuttonpressed_center; @@ -111,7 +115,8 @@ uint16_t setISO=100; //set to ISO enum displaymode { lightmeter, - settings + settings, + meteringmodeselection }; displaymode displaymode=lightmeter; uint8_t settings_selectedItem=0; //in settings display @@ -124,56 +129,25 @@ boolean settings_itemActive=false; //item in settings selected to change value uint8_t meteringmode=METERINGMODE_REFLECTIVE; + + char tempstring[16]; //for dtostrf //dtostrf(modefactor,1,3,tempstring); #if (SSD1306_LCDHEIGHT != 64) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif -//Icon Spot -#define ICON_METERINGMODE_HEIGHT 16 -#define ICON_METERINGMODE_WIDTH 16 -static const unsigned char PROGMEM icon_spot[] = -{ B00000001, B10000000, - B00000001, B10000000, - B00000111, B11100000, - B00011101, B10111000, - B00010001, B10001000, - B00110001, B10001100, - B00100000, B00000100, - B11111100, B00111111, - B11111100, B00111111, - B00100000, B00000100, - B00110001, B10001100, - B00010001, B10001000, - B00011101, B10111000, - B00000111, B11100000, - B00000001, B10000000, - B00000001, B10000000 -}; +//Icons. Exported as .xbm from gimp and renamed to .c +#include "icon_incident.c" +#include "icon_spot.c" -static const unsigned char PROGMEM icon_incident[] = -{ B10000010, B00000000, - B10000100, B00011000, - B11100000, B01100000, - B10111001, B10000000, - B10001100, B00000110, - B10000100, B00111000, - B10000110, B11000000, - B10000010, B00000000, - B10000010, B00000000, - B10000110, B11000000, - B10000100, B00111000, - B10001100, B00000110, - B10111001, B10000000, - B11100000, B01100000, - B10000100, B00011000, - B10000010, B00000000 -}; +#include "icon_arrow.c" +#include "icon_one_third.c" +#include "icon_one_half.c" +#include "icon_two_third.c" - -void setup() { +void setup() { Serial.begin(9600); Serial.println("Started"); @@ -215,8 +189,9 @@ void loop() { handleInputs(); + - calculateEV(); + calculateFromEV(); updateDisplay(); @@ -381,6 +356,9 @@ void handleInputs() case settings: handleInputs_Settings(); break; + case meteringmodeselection: + handleInputs_Meteringmodeselection(); + break; } @@ -390,7 +368,7 @@ void handleInputs() } if ( button_trigger || button_left || button_center || button_right ) { - millis_lastchange=millis(); //for auto poweroff + millis_lastchange=millis(); //for auto poweroff and auto closes millis_lastinput=millis(); //for debouncing } @@ -398,16 +376,14 @@ void handleInputs() void handleInputs_Lightmeter() { + if ( button_center ) { //open meteringmode selection + displaymode=meteringmodeselection; + } + 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 @@ -462,6 +438,10 @@ void handleInputs_Lightmeter() } } + if (button_trigger) { //Trigger + ev=getEV(); //set ev to current measurement by selected mode + } + } @@ -539,6 +519,26 @@ void handleInputs_Settings() } +void handleInputs_Meteringmodeselection() +{ + if ( button_center ) { //next or back to main screen + displaymode=lightmeter; + } + + if ( button_left ){ + meteringmode = METERINGMODE_REFLECTIVE; + displaymode=lightmeter; // and close + } + if ( button_right ) { + meteringmode = METERINGMODE_INCIDENT; + displaymode=lightmeter; // and close + } + + if (millis()-millis_lastchange>TIME_METERINGMODESELECTION_CLOSE){ //Automatic close + displaymode=lightmeter; + } +} + float reciprocFloat(float p){ if (p<1){ return (1.0f/( (int)(p*1000000) ) )*1000000 ; @@ -547,25 +547,32 @@ float reciprocFloat(float p){ } } -void calculateEV() -{ - if (meteringmode == METERINGMODE_REFLECTIVE){ +float getEV(){ + float _ev=0; + if (meteringmode == METERINGMODE_REFLECTIVE){ //### SPOT //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; + _ev=highev; }else if(lowev<12.5){ - ev=lowev; + _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; + _ev=lowev*(1-mix)+highev*mix; } - }else if (meteringmode == METERINGMODE_INCIDENT){ - ev = luxToEv(incident); + }else if (meteringmode == METERINGMODE_INCIDENT){ //### INCIDENT + _ev = luxToEv(incident); } + return _ev; +} + +void calculateFromEV() +{ + + if (setAperature>0){ //Aperature Priority showAperature=setAperature; //use user set Aperature showShutter=calculateShutter(ev,setISO, setAperature); @@ -834,6 +841,9 @@ void updateDisplay() case settings: updateDisplay_Settings(); break; + case meteringmodeselection: + updateDisplay_Meteringmodeselection(); + break; } @@ -844,7 +854,7 @@ void updateDisplay_Lightmeter() //Lightmeter display { #define xpos_aperature 2 #define ypos_aperature 29 - #define xpos_shutter 60 + #define xpos_shutter 50 #define ypos_shutter 29 #define xpos_icon 112 //128-16 #define ypos_icon 29 @@ -904,17 +914,70 @@ void updateDisplay_Lightmeter() //Lightmeter display } //Shutter border if (setShutter>0){ //Shutter Priority Mode - display.drawRect(xpos_shutter-2, ypos_shutter-2, 40, 18, WHITE); + display.drawRect(xpos_shutter-2, ypos_shutter-2, 60, 18, WHITE); } if (meteringmode == METERINGMODE_REFLECTIVE){ - display.drawBitmap(xpos_icon, ypos_icon, icon_spot, ICON_METERINGMODE_HEIGHT, ICON_METERINGMODE_WIDTH, 1); + display.drawXBitmap(xpos_icon, ypos_icon, icon_spot_bits, icon_spot_width, icon_spot_height, WHITE); }else if (meteringmode == METERINGMODE_INCIDENT) { - display.drawBitmap(xpos_icon, ypos_icon, icon_incident, ICON_METERINGMODE_HEIGHT, ICON_METERINGMODE_WIDTH, 1); + display.drawXBitmap(xpos_icon, ypos_icon, icon_incident_bits, icon_incident_width,icon_incident_height, WHITE); } //ISO display.setCursor(xpos_iso,ypos_iso); display.setTextSize(1); display.print("ISO "); display.print(setISO); + + //EV Scale + uint8_t _startev=2; //first ev to display, 13 ev values can fit on screen + + #define FULLEVLINEDISTANCE 9 + #define THIRDEVLINEDISTANCE 3 + #define ypos_evtext 7 + #define ypos_icon_arrow 6 + + uint8_t xpos_arrow=(ev-_startev*1.0) *FULLEVLINEDISTANCE; + + display.setTextSize(1); + 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; + 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); + display.drawLine(_xpos_center_evtext+THIRDEVLINEDISTANCE+THIRDEVLINEDISTANCE,0,_xpos_center_evtext+THIRDEVLINEDISTANCE+THIRDEVLINEDISTANCE,0,WHITE); + if (_fullevline%2==1){ //only every second + + uint8_t _evtextmove=2; //movement of left point of text to the left. Compensation for center position + if (_current_evvalue>9){ //text has two digits + _evtextmove=5; + } + if ( (xpos_arrow-7 > _xpos_center_evtext) || (xpos_arrow+7 < _xpos_center_evtext) ) { //drawn arrow not too close to ev text + display.setCursor(_xpos_center_evtext-_evtextmove,ypos_evtext); display.print(_current_evvalue); //EV Text + } + } + } + //Arrow at current ev + float _ev_decimals=ev-((int)ev); + display.drawXBitmap(xpos_arrow - icon_arrow_width/2.0, ypos_icon_arrow, icon_arrow_bits, icon_arrow_width, icon_arrow_height, WHITE); //arrow icon + uint8_t _xpos_current_evtext_move=5; //for text centering + if (_ev_decimals <= 0.1666 || _ev_decimals > 0.8333) { //without fraction displayed + _xpos_current_evtext_move=2; + } + display.setCursor(xpos_arrow-_xpos_current_evtext_move,ypos_icon_arrow+icon_arrow_height+2); //current ev text position + if (_ev_decimals > 0.8333 ){ + display.print((int)ev+1); //EV Value under arrow. Ceil + }else{ + display.print((int)ev); //EV Value under arrow + } + + if ( _ev_decimals > 0.1666 && _ev_decimals <= 0.4166) { + display.drawXBitmap(xpos_arrow , ypos_icon_arrow+icon_arrow_height-(icon_one_third_height-8)/2 +2, icon_one_third_bits, icon_one_third_width, icon_one_third_height, WHITE); //one third + }else if ( _ev_decimals > 0.4166 && _ev_decimals <= 0.5833) { + display.drawXBitmap(xpos_arrow , ypos_icon_arrow+icon_arrow_height-(icon_one_half_height-8)/2 +2, icon_one_half_bits, icon_one_half_width, icon_one_half_height, WHITE); //one half + }else if ( _ev_decimals > 0.5833 && _ev_decimals <= 0.8333) { + display.drawXBitmap(xpos_arrow , ypos_icon_arrow+icon_arrow_height-(icon_two_third_height-8)/2 +2, icon_two_third_bits, icon_two_third_width, icon_two_third_height, WHITE); //two third + } + //DEBUG Message display.setTextSize(1); @@ -963,17 +1026,26 @@ void updateDisplay_Settings() display.setCursor(SETTINGS_XPOS_OFFSET,display.getCursorY()+SETTINGS_YPOS_INCREMENT); //move cursor to next entry } - - - /* - if (settings_selectedItem==1){ - if (settings_itemActive){ - display.drawRect(display.getCursorX()-2, display.getCursorY()-2, 126 , 11, WHITE); - }else{ - display.drawCircle(0, display.getCursorY()+4,2, display.getCursorY()+6); - } - } - display.print("TestTest");*/ - +} + +void updateDisplay_Meteringmodeselection() +{ + display.clearDisplay(); + display.setTextColor(WHITE); + #define xpos_center_icon_spot 30 + #define ypos_icon_spot 20 + #define xpos_center_icon_incident 97 + #define ypos_icon_incident 20 + + display.drawXBitmap(xpos_center_icon_spot-icon_spot_width/2, ypos_icon_spot, icon_spot_bits, icon_spot_width, icon_spot_height, WHITE); //Spot icon + display.drawRect(xpos_center_icon_spot-icon_spot_width/2-2, ypos_icon_spot-2, icon_spot_width+4,icon_spot_height+4,WHITE); + display.drawXBitmap(xpos_center_icon_incident-icon_incident_width/2, ypos_icon_incident, icon_incident_bits, icon_incident_width, icon_incident_height, WHITE); //incident icon + display.drawRect(xpos_center_icon_incident-icon_incident_width/2-2, ypos_icon_incident-2, icon_incident_width+4,icon_incident_height+4,WHITE); + + display.setTextSize(1); + display.setCursor(xpos_center_icon_spot-10,ypos_icon_spot+icon_spot_height +6); //text position upper left + display.print("SPOT"); //7x5 characters, xpos_center_icon_spot-(5*#chars /2) + display.setCursor(xpos_center_icon_incident-20,ypos_icon_incident+icon_incident_height+6); //text position upper left + display.print("INCIDENT"); }