add ev scale

This commit is contained in:
interfisch 2018-03-26 17:55:17 +02:00
parent 202fef23b8
commit 737aabd03b
11 changed files with 175 additions and 75 deletions

4
icon_arrow.c Normal file
View File

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

BIN
icon_arrow.xcf Normal file

Binary file not shown.

6
icon_incident.c Normal file
View File

@ -0,0 +1,6 @@
#define icon_incident_width 16
#define icon_incident_height 16
static unsigned char icon_incident_bits[] = {
0x41, 0x00, 0x21, 0x18, 0x07, 0x06, 0x9d, 0x01, 0x31, 0x60, 0x21, 0x1c,
0x61, 0x03, 0x41, 0x00, 0x41, 0x00, 0x61, 0x03, 0x21, 0x1c, 0x31, 0x60,
0x9d, 0x01, 0x07, 0x06, 0x21, 0x18, 0x41, 0x00 };

Binary file not shown.

4
icon_one_half.c Normal file
View File

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

4
icon_one_third.c Normal file
View File

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

6
icon_spot.c Normal file
View File

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

Binary file not shown.

BIN
icon_thirds.xcf Normal file

Binary file not shown.

4
icon_two_third.c Normal file
View File

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

View File

@ -12,6 +12,8 @@
#include <Adafruit_GFX.h> #include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> // http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/ #include <Adafruit_SSD1306.h> // http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/
//128 x 64 px //128 x 64 px
#define WIDTH 128
#define HEIGHT 64
#include <BH1750.h> //from: https://github.com/mysensors/MySensorsArduinoExamples/tree/master/libraries/BH1750 #include <BH1750.h> //from: https://github.com/mysensors/MySensorsArduinoExamples/tree/master/libraries/BH1750
BH1750 lightMeter; BH1750 lightMeter;
@ -27,6 +29,7 @@ BH1750 lightMeter;
#define PIN_ON PB9 #define PIN_ON PB9
#define TIME_AUTOPOWEROFF 120000 #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 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 INCIDENTDELAY 100 //minimum delay between incident sensor (BH1750) readings
#define DEBOUNCETIME 50 //time to not check for inputs after key press #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_lastchange=0;
long millis_lastinput=0; long millis_lastinput=0;
long timebuttonpressed_trigger; long timebuttonpressed_trigger;
long timebuttonpressed_left; long timebuttonpressed_left;
long timebuttonpressed_center; long timebuttonpressed_center;
@ -111,7 +115,8 @@ uint16_t setISO=100; //set to ISO
enum displaymode { enum displaymode {
lightmeter, lightmeter,
settings settings,
meteringmodeselection
}; };
displaymode displaymode=lightmeter; displaymode displaymode=lightmeter;
uint8_t settings_selectedItem=0; //in settings display 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; uint8_t meteringmode=METERINGMODE_REFLECTIVE;
char tempstring[16]; //for dtostrf //dtostrf(modefactor,1,3,tempstring); char tempstring[16]; //for dtostrf //dtostrf(modefactor,1,3,tempstring);
#if (SSD1306_LCDHEIGHT != 64) #if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!"); #error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif #endif
//Icon Spot //Icons. Exported as .xbm from gimp and renamed to .c
#define ICON_METERINGMODE_HEIGHT 16 #include "icon_incident.c"
#define ICON_METERINGMODE_WIDTH 16 #include "icon_spot.c"
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
};
static const unsigned char PROGMEM icon_incident[] = #include "icon_arrow.c"
{ B10000010, B00000000, #include "icon_one_third.c"
B10000100, B00011000, #include "icon_one_half.c"
B11100000, B01100000, #include "icon_two_third.c"
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
};
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
Serial.println("Started"); Serial.println("Started");
@ -215,8 +189,9 @@ void loop() {
handleInputs(); handleInputs();
calculateEV(); calculateFromEV();
updateDisplay(); updateDisplay();
@ -381,6 +356,9 @@ void handleInputs()
case settings: case settings:
handleInputs_Settings(); handleInputs_Settings();
break; break;
case meteringmodeselection:
handleInputs_Meteringmodeselection();
break;
} }
@ -390,7 +368,7 @@ void handleInputs()
} }
if ( button_trigger || button_left || button_center || button_right ) { 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 millis_lastinput=millis(); //for debouncing
} }
@ -398,16 +376,14 @@ void handleInputs()
void handleInputs_Lightmeter() void handleInputs_Lightmeter()
{ {
if ( button_center ) { //open meteringmode selection
displaymode=meteringmodeselection;
}
if ( button_hold_center ) { //Go to Settings if ( button_hold_center ) { //Go to Settings
displaymode=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 if (setShutter==0 && setAperature==0){ //Auto
//Value Change //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){ float reciprocFloat(float p){
if (p<1){ if (p<1){
return (1.0f/( (int)(p*1000000) ) )*1000000 ; return (1.0f/( (int)(p*1000000) ) )*1000000 ;
@ -547,25 +547,32 @@ float reciprocFloat(float p){
} }
} }
void calculateEV() float getEV(){
{ float _ev=0;
if (meteringmode == METERINGMODE_REFLECTIVE){ if (meteringmode == METERINGMODE_REFLECTIVE){ //### SPOT
//ev=map(analog_low,500, 3500 ,500, 1400)/100.0; //for testing //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 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); double lowev=-0.763427709 + 0.0138031137*analog_low + -0.00000576990095*pow(analog_low,2) + 0.000000000871611285*pow(analog_low,3);
if (lowev>14){ if (lowev>14){
ev=highev; _ev=highev;
}else if(lowev<12.5){ }else if(lowev<12.5){
ev=lowev; _ev=lowev;
}else{ //mix of both }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 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){ }else if (meteringmode == METERINGMODE_INCIDENT){ //### INCIDENT
ev = luxToEv(incident); _ev = luxToEv(incident);
} }
return _ev;
}
void calculateFromEV()
{
if (setAperature>0){ //Aperature Priority if (setAperature>0){ //Aperature Priority
showAperature=setAperature; //use user set Aperature showAperature=setAperature; //use user set Aperature
showShutter=calculateShutter(ev,setISO, setAperature); showShutter=calculateShutter(ev,setISO, setAperature);
@ -834,6 +841,9 @@ void updateDisplay()
case settings: case settings:
updateDisplay_Settings(); updateDisplay_Settings();
break; break;
case meteringmodeselection:
updateDisplay_Meteringmodeselection();
break;
} }
@ -844,7 +854,7 @@ void updateDisplay_Lightmeter() //Lightmeter display
{ {
#define xpos_aperature 2 #define xpos_aperature 2
#define ypos_aperature 29 #define ypos_aperature 29
#define xpos_shutter 60 #define xpos_shutter 50
#define ypos_shutter 29 #define ypos_shutter 29
#define xpos_icon 112 //128-16 #define xpos_icon 112 //128-16
#define ypos_icon 29 #define ypos_icon 29
@ -904,17 +914,70 @@ void updateDisplay_Lightmeter() //Lightmeter display
} }
//Shutter border //Shutter border
if (setShutter>0){ //Shutter Priority Mode 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){ 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) { }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 //ISO
display.setCursor(xpos_iso,ypos_iso); display.setTextSize(1); display.print("ISO "); display.print(setISO); 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 //DEBUG Message
display.setTextSize(1); 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 display.setCursor(SETTINGS_XPOS_OFFSET,display.getCursorY()+SETTINGS_YPOS_INCREMENT); //move cursor to next entry
} }
}
/* void updateDisplay_Meteringmodeselection()
if (settings_selectedItem==1){ {
if (settings_itemActive){ display.clearDisplay();
display.drawRect(display.getCursorX()-2, display.getCursorY()-2, 126 , 11, WHITE); display.setTextColor(WHITE);
}else{ #define xpos_center_icon_spot 30
display.drawCircle(0, display.getCursorY()+4,2, display.getCursorY()+6); #define ypos_icon_spot 20
} #define xpos_center_icon_incident 97
} #define ypos_icon_incident 20
display.print("TestTest");*/
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");
} }