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_SSD1306.h> // http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/
//128 x 64 px
#define WIDTH 128
#define HEIGHT 64
#include <BH1750.h> //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");
@ -216,7 +190,8 @@ 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,18 +914,71 @@ 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);
display.setCursor(xpos_debug,ypos_debug);
@ -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");
}