diff --git a/lightmeter.ino b/lightmeter.ino index 4e97fd8..59ea258 100644 --- a/lightmeter.ino +++ b/lightmeter.ino @@ -42,6 +42,7 @@ BH1750 lightMeter; #define PIN_ON PB9 //pin for hardware latch #define TIME_AUTOPOWEROFF 120000 #define TIME_METERINGMODESELECTION_CLOSE 60000 +#define TIME_METERINGMODESELECTION_SHUTDOWN_SHORTCUT 500 #define LDRDELAY 100 //delay between ldr switches. New analog_high or low reading after that time. Transistor for lower value pulldown resistor switches in between #define LDRFILTERDELAY 1 //delay in ms between readings sequent readings for smoothing . LDRFILTERDELAY*64 > LDRDELAY #define LDRSWITCHDELAY 30 //time to wait after transistor switched @@ -134,10 +135,11 @@ uint16_t analog_reading_filtering=0; uint8_t analog_reading_count=0; float ev=0; //calculated EV from LDR readings (reflected) or from Luxmeter (incident) -float ev_min=6,ev_max=12,ev_last=8; +float ev_min=-255,ev_max=-255,ev_last=-255; float showAperature=0; float showShutter=0; +bool manualev_mode=false; //manual ev change by left/right //Usersettings float setAperature=8; //set to use aperature. 0 for auto @@ -222,9 +224,9 @@ void setup() { pinMode(PIN_ON, OUTPUT); digitalWrite(PIN_ON, HIGH); pinMode(PIN_LED, OUTPUT); - digitalWrite(PIN_LED, HIGH);//blink led on + analogWrite(PIN_LED,255); //blink led on delay(50); - digitalWrite(PIN_LED,LOW); //blink led off + analogWrite(PIN_LED,0); //LED OFF //blink led off millis_lastchange=millis(); @@ -291,18 +293,18 @@ void loop() { void readEEPROM(){ if (!digitalRead(PIN_BTNLEFT) && !digitalRead(PIN_BTNCENTER) && !digitalRead(PIN_BTNRIGHT) ){ //push all front buttons (left, center, right) to restore default settings - digitalWrite(PIN_LED,HIGH); + analogWrite(PIN_LED,255); delay(1000); //1s led on confirmation - digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); //LED OFF saveSettingsToEEPROM(true); //force writing. userSettings contains the default values at this point delay(200); - digitalWrite(PIN_LED,HIGH); + analogWrite(PIN_LED,255); delay(200); //1s led on confirmation - digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); //LED OFF delay(200); - digitalWrite(PIN_LED,HIGH); + analogWrite(PIN_LED,255); delay(200); //1s led on confirmation - digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); //LED OFF delay(1000); } @@ -327,9 +329,9 @@ void readEEPROM(){ if (eeprom_userSettings.minimumAperatureIndex==255){ //after flashing eeprom contains FF.., check one value for (int i=0;i<10;i++){ //blink a few times to show that eeprom was clean delay(50); - digitalWrite(PIN_LED,HIGH); + analogWrite(PIN_LED,255); delay(50); //1s led on confirmation - digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); } }else{ // //apply @@ -562,14 +564,14 @@ void handleInputs() void poweroff(){ bool _eepromwritten=saveSettingsToEEPROM(false); //save only changes to eeprom - digitalWrite(PIN_LED,HIGH); //Blink led + analogWrite(PIN_LED,255); //Blink led delay(100); - digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); if (_eepromwritten){ delay(100); - digitalWrite(PIN_LED,HIGH); + analogWrite(PIN_LED,255); delay(100); - digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); } digitalWrite(PIN_ON, LOW); //Turn off hardware latch } @@ -586,24 +588,27 @@ void handleInputs_Lightmeter() } - if (setShutter==0 && setAperature==0){ //Auto + if (manualev_mode){ //Manual Ev //Value Change if ( button_left ) { - + ev-=1.0/3; } if ( button_right ) { - + ev+=1.0/3; } //Change Mode - if ( button_hold_left ){ //Auto -> T - setShutter=showShutter; - setAperature=0; - } - if ( button_hold_right ){ //Auto -> Av + if ( button_hold_left ){ // Manual Ev -> Av setAperature=showAperature; setShutter=0; + manualev_mode=false; + } + if ( button_hold_right ){ // Manual Ev -> T + setShutter=showShutter; + setAperature=0; + manualev_mode=false; } }else if(setShutter==0){ //Aperature Priority + manualev_mode=false; //Value Change if ( button_left ) { changeAperature(1); //Decrement Aperature @@ -612,15 +617,15 @@ void handleInputs_Lightmeter() changeAperature(-1); //Increment Aperature } //Change Mode - if ( button_hold_left ){ //change from Aperature Priority to Auto, Av -> Auto - setAperature=0; - setShutter=0; + if ( button_hold_left ){ //Av -> Manual Ev + manualev_mode=true; } if ( button_hold_right ){ //Av -> T setShutter=showShutter; setAperature=0; } }else if (setAperature==0){ //Shutter Priority + manualev_mode=false; //Value Change if ( button_left ) { changeShutter(1); //Decrement Aperature @@ -633,17 +638,39 @@ void handleInputs_Lightmeter() setAperature=showAperature; setShutter=0; } - if ( button_hold_right ){ //T -> Auto - setAperature=0; - setShutter=0; + if ( button_hold_right ){ //T -> Manual Ev + manualev_mode=true; } } - if (button_trigger || button_hold_trigger) { //Trigger + if (button_trigger) { //Trigger + ev_last=ev; ev=getEV(); //set ev to current measurement by selected mode + if (evev_max){ //new ev is greater + ev_max=ev; + } debug_analog_high=analog_high; debug_analog_low=analog_low; - blinkLED(20); + //LED Brightness on trigger + uint8_t triggerblinkbrightness=255; + if (ev<4){ //dim led when dark + triggerblinkbrightness=map(ev,4,0,255,50); + } + blinkLED(20,triggerblinkbrightness); + } + + if (button_hold_trigger) { //Trigger hold, resets ev_min,max and last + ev_min=-255; //placeholder for "not set" + ev_max=-255; + ev_last=-255; + //LED Brightness on trigger + uint8_t triggerblinkbrightness=255; + if (ev<4){ //dim led when dark + triggerblinkbrightness=map(ev,4,0,255,50); + } + blinkLED(400,triggerblinkbrightness); } } @@ -727,6 +754,9 @@ void handleInputs_Settings() void handleInputs_Meteringmodeselection() { if ( button_center ) { //next or back to main screen + if (millis()-millis_lastchange0){ //Aperature Priority Mode - display.drawRect(xpos_aperature-2, ypos_aperature-2, 40, 18, WHITE); + if (!manualev_mode){ //selection + display.drawRect(xpos_aperature-2, ypos_aperature-2, 40, 18, WHITE); //normal border + }else{ //manual ev selection + drawRectCorners(xpos_aperature-2, ypos_aperature-2, 40, 18, 5,WHITE); //alternative border + } } @@ -1178,7 +1212,12 @@ void updateDisplay_Lightmeter() //Lightmeter display } //Shutter border if (setShutter>0){ //Shutter Priority Mode - display.drawRect(xpos_shutter-2, ypos_shutter-2, 60, 18, WHITE); + if (!manualev_mode){ //selection + display.drawRect(xpos_shutter-2, ypos_shutter-2, 60, 18, WHITE); //normal border + }else{ //manual ev selection + drawRectCorners(xpos_shutter-2, ypos_shutter-2, 60, 18, 5, WHITE); //alternative border + } + } if (meteringmode == METERINGMODE_REFLECTIVE){ @@ -1193,11 +1232,11 @@ void updateDisplay_Lightmeter() //Lightmeter display //EV Scale int8_t _startev=-5; //first ev to display, 13 ev values can fit on screen - if (ev>2){ - _startev=2; + if (ev>2 && (ev_min<-254 || ev_min>2)){ //TODO make this better + _startev=0; } - if (ev>13){ - _startev=5+ev-13; + if (ev>11 || ev_max>11){ + _startev=5+ev-11; } #define FULLEVLINEDISTANCE 9 @@ -1205,7 +1244,7 @@ void updateDisplay_Lightmeter() //Lightmeter display #define ypos_evtext 7 #define ypos_icon_arrow 6 - uint8_t xpos_arrow=(ev-_startev*1.0) *FULLEVLINEDISTANCE; + uint8_t xpos_arrow=(ev-_startev*1.0) *FULLEVLINEDISTANCE; //calculate display position for ev display.setTextSize(1); display.drawLine(THIRDEVLINEDISTANCE,0,THIRDEVLINEDISTANCE,0,WHITE); //first third line @@ -1219,17 +1258,21 @@ void updateDisplay_Lightmeter() //Lightmeter display 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 + if (_current_evvalue>9 || _current_evvalue<0){ //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 + display.setCursor(_xpos_center_evtext-_evtextmove,ypos_evtext); display.print(_current_evvalue); //EV Text at scale line } } } //Arrow at current ev - float _ev_decimals=ev-((int)ev); + float _ev_decimals=abs(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 + if (manualev_mode){ //in manual ev mode + display.drawXBitmap(xpos_arrow - icon_arrow_width/2.0 -1, ypos_icon_arrow, icon_arrow_bits, icon_arrow_width, icon_arrow_height, WHITE); //arrow icon //draw bold + display.drawXBitmap(xpos_arrow - icon_arrow_width/2.0 +1, ypos_icon_arrow, icon_arrow_bits, icon_arrow_width, icon_arrow_height, WHITE); //arrow icon //draw bold + } 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; @@ -1237,12 +1280,22 @@ void updateDisplay_Lightmeter() //Lightmeter display int _displayev=(int)ev; if (_ev_decimals > 0.8333 ){ - _displayev=(int)(ev+1);//EV Value under arrow. Ceil + if (ev>=0){ //ev is positive + _displayev=(int)(ev+1);//EV Value under arrow. Ceil + }else if (ev<0){ //ev is negative + _displayev=(int)(ev-1);//EV Value under arrow. Ceil (negative) + } + } - if (_displayev>=10){ + //int _xpos_current_fraction_move=0; //move fraction icon + if (_displayev>=10 || ev<-0.1666){ //displayev is two digits long (>=10 or negative sign) _xpos_current_evtext_move+=6; //move digits to left. positive means left + } display.setCursor(xpos_arrow-_xpos_current_evtext_move,ypos_icon_arrow+icon_arrow_height+2); //current ev text position + if (ev<0 && _displayev==0){ //ev is negative but displayev is zero + display.print("-"); // add minus in front + } display.print(_displayev); //EV Value under arrow @@ -1253,6 +1306,29 @@ void updateDisplay_Lightmeter() //Lightmeter display }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 } + + //ev min & max + uint8_t xpos_ev_min=(ev_min-_startev*1.0) *FULLEVLINEDISTANCE; //calculate display position for ev + uint8_t xpos_ev_max=(ev_max-_startev*1.0) *FULLEVLINEDISTANCE; //calculate display position for ev + + bool arrow_is_between_minmax=true; + if (xpos_arrowxpos_ev_max){ + arrow_is_between_minmax=false; //selected ev is not between min and max ev + } + if (ev_min>-254){ //ev_min is set (-255 is placeholder for "not set") + display.drawLine(xpos_ev_min,2,xpos_ev_min,5,WHITE); + if ((xpos_arrow-xpos_ev_min)>3 && arrow_is_between_minmax){ //arrow is not overlaying line and is in between min and max + display.drawLine(xpos_ev_min,4,xpos_arrow - 4,4,WHITE); //line from left horizontally to arrow + display.drawLine(xpos_ev_min,5,xpos_arrow - 4,5,WHITE); //line from left horizontally to arrow + } + } + if (ev_max>-254){ //ev_min is set (-255 is placeholder for "not set") + display.drawLine(xpos_ev_max,2,xpos_ev_max,5,WHITE); + if ((xpos_ev_max-xpos_arrow)>3 && arrow_is_between_minmax){ //arrow is not overlaying line and is in between min and max + display.drawLine(xpos_ev_max,4,xpos_arrow + 3,4,WHITE); //line from right horizontally to arrow + display.drawLine(xpos_ev_max,5,xpos_arrow + 3,5,WHITE); //line from right horizontally to arrow + } + } @@ -1266,9 +1342,13 @@ void updateDisplay_Lightmeter() //Lightmeter display display.print(" |"); display.print(incident);*/ - display.print(debug_analog_low); + /*display.print(debug_analog_low); display.print(" : "); - display.print(debug_analog_high); + display.print(debug_analog_high);*/ + + display.print(ev_min,1); + display.print(":"); + display.print(ev_max,1); } @@ -1334,13 +1414,34 @@ void updateDisplay_Meteringmodeselection() } } +void drawRectCorners(uint8_t px,uint8_t py, uint8_t pw, uint8_t ph, uint8_t pcornerlength, uint8_t pc){ + //px py are top left + display.drawLine(px,py,px+pcornerlength,py, pc); + display.drawLine(px,py,px,py+pcornerlength, pc); + + display.drawLine(px+pw,py, px+pw-pcornerlength,py, pc); + display.drawLine(px+pw,py, px+pw,py+pcornerlength, pc); + + display.drawLine(px+pw,py+ph, px+pw-pcornerlength,py+ph, pc); + display.drawLine(px+pw,py+ph, px+pw,py+ph-pcornerlength, pc); + + display.drawLine(px,py+ph, px+pcornerlength,py+ph, pc); + display.drawLine(px,py+ph, px,py+ph-pcornerlength, pc); + +} + void blinkLED(long duration){ - digitalWrite(PIN_LED,HIGH); + blinkLED(duration,255); +} +void blinkLED(long duration,uint8_t brightness){ + //digitalWrite(PIN_LED,HIGH); + analogWrite(PIN_LED,brightness); millis_ledoff=loopmillis+duration; } void checkLED(){ if (loopmillis>=millis_ledoff && digitalRead(PIN_LED)){ - digitalWrite(PIN_LED,LOW); + //digitalWrite(PIN_LED,LOW); + analogWrite(PIN_LED,0); //LED OFF } }