Spotmeter based on an STM32 with OLED Display and various features.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1679 lines
58 KiB

4 years ago
//STM32F103C, 64k flash
//upload method: serial (A9 to RX, A10 to TX)
//To upload set Boot0 jumper to 1 (the one further away from reset btn) and press reset (stm will boot from flash wich contains uart to flash uploader)
//upload via arduino IDE
//To boot program after restart set Boot0 jumper to 0
//Letters 5x7 at Size 1
#include <math.h>
4 years ago
//#include <SPI.h>
#include <Wire.h>
#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
4 years ago
#define WIDTH 128
#define HEIGHT 64
#include <EEPROM.h>
4 years ago
#include <BH1750.h> //from: https://github.com/mysensors/MySensorsArduinoExamples/tree/master/libraries/BH1750
BH1750 lightMeter;
#define INCIDENT_CORRECTION_FACTOR 1.17
//with 1125 25 225 2465 120
//wihtout 1335 32 265 2865 145
/*1,186666667
1,28
1,177777778
1,162271805
1,208333333*/
4 years ago
#define PIN_LDR 0 //A0
#define PIN_BRIGHTMODE 1 //A1
#define PIN_VBAT 2 //A2
#define PIN_LED 8 //White status led A8
4 years ago
#define PIN_TRIGGER PB8
#define PIN_BTNLEFT PA15
#define PIN_BTNCENTER PB4
#define PIN_BTNRIGHT PB5
#define PIN_ON PB9 //pin for hardware latch
4 years ago
#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
#define INCIDENTDELAY 100 //minimum delay between incident sensor (BH1750) readings
#define DEBOUNCETIME 20 //time to not check for inputs after key press
#define BUTTONTIMEHOLD 750 //time for button hold
#define BUTTONTIMEHOLDLONG 3000 //time for button long hold
4 years ago
#define VOLTAGE_WARN 3.4 //voltage per cell //TODO implement warning
4 years ago
//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
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
float shuttertimes3[]={3600,2400,1800,1200,900,600,420,300,210,150,100,60,45,30,20,16,10,8,6,4,3,2,1.5,1,0.5,0.25,0.125,1.0/16};
#define SHUTTERTIMES3_MAXINDEX 27
String settingsnameShutterSelectionMode[]={"Analog","Digital","Pinhole"}; //names for tables
#define MAXIMUM_SHUTTERSELECTIONMODES 3
//Aperature numbers https://en.wikipedia.org/wiki/F-number
float aperaturesFull[]={1,1.4, 2, 2.8, 4, 5.6, 8, 11, 16, 22, 32,45};
#define APERATURESFULL_MAXINDEX 11
float aperaturesHalf[]={1, 1.2, 1.4, 1.7, 2, 2.4, 2.8, 3.4, 4, 4.8, 5.6, 6.7, 8, 9.5, 11, 13, 16, 19, 22, 27 ,32, 38, 45};
#define APERATURESHALF_MAXINDEX 22
4 years ago
float aperaturesThird[]={1, 1.1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.5, 2.8, 3.2, 3.5, 4, 4.5, 5.0, 5.6, 6.3, 7.1, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 29, 32, 36, 40, 45};
#define APERATURESTHIRD_MAXINDEX 33
4 years ago
String settingsnameAperatureSelectionMode[]={"Full","Half","Third"}; //names for tables
#define MAXIMUM_APERATURESELECTIONMODES 3
float isoFull[]={0.78,1.56,3.13,6.25,12.5,25,50,100,200,400,800,1600,3200,6400,12500,25600};
uint8_t isoFullDIN[]={0,3, 6, 9, 12, 15,18,21 ,24 ,27 ,30 ,33 ,36 ,39 ,42 ,45};
float isoThird[]={0.78,0.98,1.24,1.56,1.97,2.48,3.13,3.93,4.96,6.25,7.87,9.92,12.5,16,20,25,32,40,50,64,80,100,125,160,200,250,320,400,500,640,800,1000,1250,1600,2000,2500,3200,4000,5000,6400,8000,10000,12500,16000,20000,25600};
uint8_t isoThirdDIN[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, 21, 22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,37 ,38 ,39 ,40 ,41 ,42 ,43 ,44 ,56};
4 years ago
long loopmillis=0; //only use one millis reading each loop
long last_ldrReading=0;
long last_ldrReadingFilter=0;
long last_incidentReading=0;
4 years ago
long millis_lastchange=0;
long millis_lastinput=0;
long millis_ledoff=0; //for led blink
long millis_opened_meteringmodeselection=0; //time when meteringmodeselecten was opened (for led flashlight timing)
#define DELAY_METERINGMODESELECTION_FLASHLIGHT 2000
4 years ago
4 years ago
4 years ago
long timebuttonpressed_trigger;
long timebuttonpressed_left;
long timebuttonpressed_center;
long timebuttonpressed_right;
//Short press (true when button short pressed, on release)
boolean button_trigger=false;
boolean button_left=false;
boolean button_center=false;
boolean button_right=false;
//long press (true when button is held down for BUTTONTIMEHOLD, on time elapsed)
boolean button_hold_trigger=false;
boolean button_hold_left=false;
boolean button_hold_center=false;
boolean button_hold_right=false;
//even longer press
boolean button_hold_long_trigger=false;
long timebuttonpressed_trigger_long=0;
float vbat=100;
4 years ago
struct Settings {
uint8_t minimumAperatureIndex; //see corresponding aperatures table
uint8_t aperatureSelectionMode; //1=Full, 2=Half, 3=Third
uint8_t shutterSelectionMode; //index for which shuttertimes table to use
uint8_t ISOSelectionMode; //1=Full, 2=Thirds
uint8_t manualev_moveamount_frac; // 1=1ev, 2=1/2ev, 3=1/3 ev
4 years ago
};
#define MAXIMUM_MANUAL_EV_MOVEAMOUNT_FRAC 3
4 years ago
bool settingsStructEqual(Settings a, Settings b){
if (a.minimumAperatureIndex!=b.minimumAperatureIndex || a.aperatureSelectionMode!=b.aperatureSelectionMode || a.shutterSelectionMode!=b.shutterSelectionMode || a.ISOSelectionMode!=b.ISOSelectionMode){
return false;
}
return true;
}
Settings userSettings= {1,1, 1,2,1};
Settings eeprom_userSettings; //to store current eeprom status
4 years ago
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
uint16_t incident=0; //incident reading from bh1750
4 years ago
uint16_t analog_low=0; //better for low light
uint16_t analog_high=0; //better for bright light (higher pulldown resistor for ldr)
uint16_t analog_reading_filtering=0;
uint8_t analog_reading_count=0;
4 years ago
float ev=0; //calculated EV from LDR readings (reflected) or from Luxmeter (incident)
float ev_min=-255,ev_max=-255,ev_last=-255;
4 years ago
float showAperature=0;
float showShutter=0;
bool manualev_mode=false; //manual ev change by left/right
4 years ago
//Usersettings
float setAperature=8; //set to use aperature. 0 for auto
float setShutter=0; //set to use shutter time, 0 for auto
float setISO=100; //set to ISO
4 years ago
float eeprom_setAperature=0; //set to use aperature. 0 for auto
float eeprom_setShutter=0; //set to use shutter time, 0 for auto
float eeprom_setISO=0; //set to ISO
#define EEPROMADDRESS_APERATURE 0x801F000 //float = 32bit = 4byte
#define EEPROMADDRESS_SHUTTER 0x801F004 //float = 32bit = 4byte
#define EEPROMADDRESS_ISO 0x801F008 //float 32bit = 4byte
#define EEPROMADDRESS_METERINGMODE 0x801F00C //uint8_t 1byte
#define EEPROMADDRESS_USERSETTINGS 0x801F00D //Settings struct
4 years ago
enum displaymode {
lightmeter,
4 years ago
settings,
meteringmodeselection
4 years ago
};
displaymode displaymode=lightmeter;
uint8_t settings_selectedItem=0; //in settings display
String settingStrings[]={"ISO:","F-Stops:","Timetable:","EV Step:","Turn Off"};
#define SETTINGS_SELECTEDITEM_MAX 4 //inclusive. 2 means 3 items available
4 years ago
boolean settings_itemActive=false; //item in settings selected to change value
#define DISPLAY_UPDATEDELAY 200
long last_displayupdate=0;
4 years ago
#define METERINGMODE_REFLECTIVE 0
#define METERINGMODE_INCIDENT 1
uint8_t meteringmode=METERINGMODE_REFLECTIVE;
uint8_t eeprom_meteringmode=0;
bool eeprom_red=false; //false, if eeprom need to be red
4 years ago
4 years ago
bool debug_printreadings=false;
uint16_t debug_analog_high=0;
uint16_t debug_analog_low=0;
4 years ago
4 years ago
char tempstring[16]; //for dtostrf //dtostrf(modefactor,1,3,tempstring);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
4 years ago
//Icons. Exported as .xbm from gimp and renamed to .c
#include "icon_incident.c"
#include "icon_spot.c"
4 years ago
#include "icon_arrow.c"
#include "icon_one_third.c"
#include "icon_one_half.c"
#include "icon_two_third.c"
4 years ago
void setup() {
Serial.begin(115200);
4 years ago
Serial.println("Started");
Serial.println("Init Display");
4 years ago
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
Serial.println("Init BH1750");
lightMeter.begin(BH1750_CONTINUOUS_HIGH_RES_MODE_2); //max reading=54612
4 years ago
//set measurement time (for higher resolution) http://www.raspberry-pi-geek.de/Magazin/2015/04/Digital-Light-Sensor-BH1750-am-Raspberry-Pi
//lightMeter.write8(71); //01000111 //high bit: 01000xxx bits 7,6,5
//lightMeter.write8(126); //01111110 //log bit: 011xxxxx bits 4,3,2,1,0
pinMode(PIN_LDR, INPUT_ANALOG);
pinMode(PIN_VBAT, INPUT_ANALOG);
pinMode(PIN_TRIGGER, INPUT_PULLUP);
pinMode(PIN_BTNLEFT, INPUT_PULLUP);
pinMode(PIN_BTNCENTER, INPUT_PULLUP);
pinMode(PIN_BTNRIGHT, INPUT_PULLUP);
pinMode(PIN_BRIGHTMODE, OUTPUT);
digitalWrite(PIN_BRIGHTMODE, LOW);
pinMode(PIN_ON, OUTPUT);
digitalWrite(PIN_ON, HIGH);
pinMode(PIN_LED, OUTPUT);
analogWrite(PIN_LED,255); //blink led on
delay(50);
analogWrite(PIN_LED,0); //LED OFF //blink led off
4 years ago
millis_lastchange=millis();
Serial.println("Initialized");
if (!digitalRead(PIN_TRIGGER)){ //hold trigger button during power on activates serial debug printing
debug_printreadings=true;
}
4 years ago
4 years ago
}
bool saveSettingsToEEPROM(bool force){
bool _eepromwritten=false;
//checks and writes changes to eeprom
if (eeprom_setAperature!=setAperature || force){ //value change or write forced
EEPROM_writeAnything(EEPROMADDRESS_APERATURE, setAperature);
_eepromwritten=true;
}
if (eeprom_setShutter!=setShutter || force){ //value change or write forced
EEPROM_writeAnything(EEPROMADDRESS_SHUTTER, setShutter);
_eepromwritten=true;
}
if (eeprom_setISO!=setISO || force){ //value change or write forced
EEPROM_writeAnything(EEPROMADDRESS_ISO, setISO);
_eepromwritten=true;
}
if (eeprom_meteringmode!=meteringmode || force){ //one of the values change or write forced
EEPROM_writeAnything(EEPROMADDRESS_METERINGMODE, meteringmode);
_eepromwritten=true;
}
if (!settingsStructEqual(eeprom_userSettings,userSettings) || force){ //one of the values change or write forced
EEPROM_writeAnything(EEPROMADDRESS_USERSETTINGS, userSettings);
_eepromwritten=true;
}
return _eepromwritten;
}
4 years ago
void loop() {
loopmillis=millis(); //read millis for this cycle
if (!eeprom_red){ //only executed one time
eeprom_red=true;
readEEPROM();
}
4 years ago
handleInputs();
4 years ago
calculateFromEV();
4 years ago
updateDisplay();
checkLED();
}
void readEEPROM(){
4 years ago
if (!digitalRead(PIN_BTNLEFT) && !digitalRead(PIN_BTNCENTER) && !digitalRead(PIN_BTNRIGHT) ){ //push all front buttons (left, center, right) to restore default settings
analogWrite(PIN_LED,255);
delay(1000); //1s led on confirmation
analogWrite(PIN_LED,0); //LED OFF
saveSettingsToEEPROM(true); //force writing. userSettings contains the default values at this point
delay(200);
analogWrite(PIN_LED,255);
delay(200); //1s led on confirmation
analogWrite(PIN_LED,0); //LED OFF
delay(200);
analogWrite(PIN_LED,255);
delay(200); //1s led on confirmation
analogWrite(PIN_LED,0); //LED OFF
delay(1000);
}
4 years ago
//read current eeprom
EEPROM_readAnything(EEPROMADDRESS_APERATURE, eeprom_setAperature);
EEPROM_readAnything(EEPROMADDRESS_SHUTTER, eeprom_setShutter);
EEPROM_readAnything(EEPROMADDRESS_ISO, eeprom_setISO);
EEPROM_readAnything(EEPROMADDRESS_METERINGMODE, eeprom_meteringmode);
EEPROM_readAnything(EEPROMADDRESS_USERSETTINGS, eeprom_userSettings);
Serial.println("");
Serial.println("EEPROM eeprom settings");
Serial.println(eeprom_setAperature);
Serial.println(eeprom_setShutter);
Serial.println(eeprom_setISO);
Serial.println("EEPROM eeprom_userSettings");
Serial.println(eeprom_userSettings.minimumAperatureIndex);
Serial.println(eeprom_userSettings.aperatureSelectionMode);
Serial.println(eeprom_userSettings.shutterSelectionMode);
Serial.println(eeprom_userSettings.ISOSelectionMode);
Serial.println("");
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);
analogWrite(PIN_LED,255);
delay(50); //1s led on confirmation
analogWrite(PIN_LED,0);
}
}else{ //
//apply
setAperature=eeprom_setAperature;
setShutter=eeprom_setShutter;
setISO=eeprom_setISO;
meteringmode=eeprom_meteringmode;
userSettings=eeprom_userSettings;
}
4 years ago
}
4 years ago
void handleInputs()
{
//Short press (true when button short pressed, on release)
button_trigger=false;
button_left=false;
button_center=false;
button_right=false;
//long press (true when button is held down for BUTTONTIMEHOLD, on time elapsed)
button_hold_trigger=false;
button_hold_left=false;
button_hold_center=false;
button_hold_right=false;
//even longer press
button_hold_long_trigger=false;
4 years ago
if (millis()-millis_lastinput>DEBOUNCETIME) //Button debouncing
{
//Trigger
if (timebuttonpressed_trigger == 0 && !digitalRead(PIN_TRIGGER)){ //first time pressed down. (low when pressed)
timebuttonpressed_trigger=loopmillis; //set time of button press
timebuttonpressed_trigger_long=loopmillis; //set time of button press, for long hold timing
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(timebuttonpressed_trigger != 0 && digitalRead(PIN_TRIGGER)){ //button released (was pressed)
if (loopmillis-timebuttonpressed_trigger < BUTTONTIMEHOLD){ //short press
4 years ago
button_trigger=true;
}
timebuttonpressed_trigger=0; //re-enable after short press and release from hold
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(loopmillis-timebuttonpressed_trigger >= BUTTONTIMEHOLD && timebuttonpressed_trigger>0){ //held down long enough and not already hold triggered
button_hold_trigger=true;
timebuttonpressed_trigger=-1; //-1 as flag for hold triggered
}
if (timebuttonpressed_trigger_long>0 && loopmillis-timebuttonpressed_trigger_long >= BUTTONTIMEHOLDLONG && !digitalRead(PIN_TRIGGER)) { //button held down even longer, set hold long flag for as long as button is down
button_hold_long_trigger=true;
}else if(timebuttonpressed_trigger_long>0 && digitalRead(PIN_TRIGGER)){ //released
timebuttonpressed_trigger_long=0; //reset long hold timing
}
4 years ago
//Left
if (timebuttonpressed_left == 0 && !digitalRead(PIN_BTNLEFT)){ //first time pressed down. (low when pressed)
timebuttonpressed_left=loopmillis; //set time of button press
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(timebuttonpressed_left != 0 && digitalRead(PIN_BTNLEFT)){ //button released (was pressed)
if (loopmillis-timebuttonpressed_left < BUTTONTIMEHOLD){ //short press
4 years ago
button_left=true;
}
timebuttonpressed_left=0; //re-enable after short press and release from hold
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(loopmillis-timebuttonpressed_left >= BUTTONTIMEHOLD && timebuttonpressed_left>0){ //held down long enough and not already hold triggered
button_hold_left=true;
timebuttonpressed_left=-1; //-1 as flag for hold triggered
}
//Center
if (timebuttonpressed_center == 0 && !digitalRead(PIN_BTNCENTER)){ //first time pressed down. (low when pressed)
timebuttonpressed_center=loopmillis; //set time of button press
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(timebuttonpressed_center != 0 && digitalRead(PIN_BTNCENTER)){ //button released (was pressed)
if (loopmillis-timebuttonpressed_center < BUTTONTIMEHOLD){ //short press
4 years ago
button_center=true;
}
timebuttonpressed_center=0; //re-enable after short press and release from hold
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(loopmillis-timebuttonpressed_center >= BUTTONTIMEHOLD && timebuttonpressed_center>0){ //held down long enough and not already hold triggered
button_hold_center=true;
timebuttonpressed_center=-1; //-1 as flag for hold triggered
}
//Right
if (timebuttonpressed_right == 0 && !digitalRead(PIN_BTNRIGHT)){ //first time pressed down. (low when pressed)
timebuttonpressed_right=loopmillis; //set time of button press
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(timebuttonpressed_right != 0 && digitalRead(PIN_BTNRIGHT)){ //button released (was pressed)
if (loopmillis-timebuttonpressed_right < BUTTONTIMEHOLD){ //short press
4 years ago
button_right=true;
}
timebuttonpressed_right=0; //re-enable after short press and release from hold
millis_lastinput=millis(); //for debouncing
4 years ago
}else if(loopmillis-timebuttonpressed_right >= BUTTONTIMEHOLD && timebuttonpressed_right>0){ //held down long enough and not already hold triggered
button_hold_right=true;
timebuttonpressed_right=-1; //-1 as flag for hold triggered
}
}
/*
if (button_trigger || button_left || button_center || button_right){
Serial.println("Buttons short:");
Serial.print(button_trigger);
Serial.print(button_left);
Serial.print(button_center);
Serial.println(button_right);
}
if (button_hold_trigger || button_hold_left || button_hold_center || button_hold_right){
Serial.println("Buttons long:");
Serial.print(button_hold_trigger);
Serial.print(button_hold_left);
Serial.print(button_hold_center);
Serial.println(button_hold_right);
}
*/
//Voltage
float _vbat=map(analogRead(PIN_VBAT), 0,3560,0,8200)/1000.0; //180k and 300k voltage divider. 8,4V -> 3,15V=3910
if (_vbat<vbat){
vbat=_vbat; //voltage can only decrease
}
4 years ago
//LDR
if ( loopmillis-last_ldrReadingFilter>LDRFILTERDELAY && loopmillis-last_ldrReading>LDRSWITCHDELAY) //multiple successive reading for filtering. each LDRFILTERDELAY ms and wait LDRSWITCHDELAY for first reading
{
analog_reading_filtering+=analogRead(PIN_LDR);
analog_reading_count++;
last_ldrReadingFilter=loopmillis;
}
if ( loopmillis-last_ldrReading>LDRDELAY ) //time over for one reading (low or high)
4 years ago
{
if (!digitalRead(PIN_BRIGHTMODE)){
analog_low=analog_reading_filtering/analog_reading_count;
4 years ago
}else{
analog_high=analog_reading_filtering/analog_reading_count;
if (debug_printreadings){
Serial.print(analog_low);//for calibration output
Serial.print(";");
Serial.println(analog_high);
}
4 years ago
}
/*Serial.print(analog_reading_count);
Serial.print(" value=");
Serial.println(analog_reading_filtering);*/
analog_reading_count=0; //reset
analog_reading_filtering=0; //reset
4 years ago
digitalWrite(PIN_BRIGHTMODE, !digitalRead(PIN_BRIGHTMODE)); //switch modes
last_ldrReading=loopmillis;
}
//Lightsensor BH1750
if ( loopmillis-last_incidentReading>INCIDENTDELAY )
{
incident = lightMeter.readLightLevel(); //value in lux from sensor
last_incidentReading=loopmillis;
}
4 years ago
//Test asdf
/*
if ( !digitalRead(PIN_TRIGGER) ) {
Serial.println("roundAperature");
for (float i=0.1;i<30;i+=0.5){
Serial.print(i);
Serial.print(" -> ");
Serial.println(roundAperature(i,1));
}
Serial.println("roundShutter");
for (float i=1.0/8000;i<32;i*=2){
Serial.print(i,6);
Serial.print(" -> ");
Serial.print(roundShutter(i,2),6);
4 years ago
Serial.print(" -- ");
Serial.println(reciprocFloat(roundShutter(i,2)));
}
4 years ago
}
4 years ago
Serial.println("calculateShutter at iso 100 f2.8");
for (float i=-2;i<18;i+=0.25){
4 years ago
Serial.print(i);
Serial.print(" -> ");
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("");
}
4 years ago
}
Serial.println("calculateAperature at iso 100 1/250s");
for (float i=-2;i<18;i+=0.25){
4 years ago
Serial.print(i);
Serial.print(" -> ");
Serial.println(calculateAperature(i, (uint16_t)100, 1.0/250),6);
4 years ago
}
}*/
4 years ago
switch(displaymode){
case lightmeter:
handleInputs_Lightmeter();
break;
case settings:
handleInputs_Settings();
break;
4 years ago
case meteringmodeselection:
handleInputs_Meteringmodeselection();
break;
4 years ago
}
if (millis()-millis_lastchange>TIME_AUTOPOWEROFF){
poweroff();
4 years ago
}
if ( button_trigger || button_left || button_center || button_right ) {
4 years ago
millis_lastchange=millis(); //for auto poweroff and auto closes
4 years ago
millis_lastinput=millis(); //for debouncing
}
}
void poweroff(){
bool _eepromwritten=saveSettingsToEEPROM(false); //save only changes to eeprom
analogWrite(PIN_LED,255); //Blink led
delay(100);
analogWrite(PIN_LED,0);
if (_eepromwritten){
delay(100);
analogWrite(PIN_LED,255);
delay(100);
analogWrite(PIN_LED,0);
}
digitalWrite(PIN_ON, LOW); //Turn off hardware latch
}
4 years ago
void handleInputs_Lightmeter()
{
4 years ago
if ( button_center ) { //open meteringmode selection
displaymode=meteringmodeselection;
millis_opened_meteringmodeselection=loopmillis;
4 years ago
}
4 years ago
if ( button_hold_center ) { //Go to Settings
displaymode=settings;
}
4 years ago
4 years ago
if (manualev_mode){ //Manual Ev
4 years ago
//Value Change
if ( button_left ) {
ev-=1.0/userSettings.manualev_moveamount_frac;
4 years ago
}
if ( button_right ) {
ev+=1.0/userSettings.manualev_moveamount_frac;
4 years ago
}
//Change Mode
if ( button_hold_left ){ // Manual Ev -> Av
4 years ago
setAperature=showAperature;
setShutter=0;
manualev_mode=false;
}
if ( button_hold_right ){ // Manual Ev -> T
setShutter=showShutter;
setAperature=0;
manualev_mode=false;
4 years ago
}
}else if(setShutter==0){ //Aperature Priority
manualev_mode=false;
4 years ago
//Value Change
if ( button_left ) {
changeAperature(1); //Decrement Aperature
}
if ( button_right ) {
changeAperature(-1); //Increment Aperature
}
//Change Mode
if ( button_hold_left ){ //Av -> Manual Ev
manualev_mode=true;
4 years ago
}
if ( button_hold_right ){ //Av -> T
setShutter=showShutter;
setAperature=0;
}
}else if (setAperature==0){ //Shutter Priority
manualev_mode=false;
4 years ago
//Value Change
if ( button_left ) {
changeShutter(1); //Decrement Aperature
}
if ( button_right ) {
changeShutter(-1); //Increment Aperature
}
//Change Mode
if ( button_hold_left ){ //T -> Av
setAperature=showAperature;
setShutter=0;
}
if ( button_hold_right ){ //T -> Manual Ev
manualev_mode=true;
4 years ago
}
}
if (button_trigger || button_hold_long_trigger) { //Trigger or very long hold
ev_last=ev;
4 years ago
ev=getEV(); //set ev to current measurement by selected mode
if (ev<ev_min || ev_min<-254){ //new ev is smaller than last or ev_min wasn set
ev_min=ev;
}
if(ev>ev_max){ //new ev is greater
ev_max=ev;
}
debug_analog_high=analog_high;
debug_analog_low=analog_low;
//LED Brightness on trigger
uint8_t triggerblinkbrightness=255;
if (ev<4){ //dim led when dark
triggerblinkbrightness=map(ev,2,4,5,255);
}
if (ev<2){
triggerblinkbrightness=5;
}
if (button_hold_long_trigger){ //low brightness on long hold
triggerblinkbrightness=5;
}
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);
4 years ago
}
4 years ago
}
4 years ago
void handleInputs_Settings()
{
if ( button_hold_center ) { //Go to Lightmeter
settings_itemActive=false; //deselect item
4 years ago
displaymode=lightmeter;
}
if (!settings_itemActive){ //select items
if ( button_left ) {
if (settings_selectedItem>0){ //not first item
settings_selectedItem-=1;
}
}
if ( button_right ) {
if (settings_selectedItem<SETTINGS_SELECTEDITEM_MAX){ //not last item
settings_selectedItem+=1;
}
}
if ( button_center ){
settings_itemActive=true; //select item to change value
}
}else{ //item selected to change value
switch (settings_selectedItem)
{
case 0: //ISO
if ( button_left ) {
changeISO(-1);
}
if ( button_right ) {
changeISO(1);
}
break;
case 1: //Aperature Selection Mode
if ( button_left ) {
if(userSettings.aperatureSelectionMode>1){
userSettings.aperatureSelectionMode-=1;
}
}
if ( button_right ) {
if (userSettings.aperatureSelectionMode<MAXIMUM_APERATURESELECTIONMODES){
userSettings.aperatureSelectionMode+=1;
}
}
break;
case 2: //Shutter Selection Mode
if ( button_left ) {
if(userSettings.shutterSelectionMode>1){
userSettings.shutterSelectionMode-=1;
}
}
if ( button_right ) {
if (userSettings.shutterSelectionMode<MAXIMUM_SHUTTERSELECTIONMODES){
userSettings.shutterSelectionMode+=1;
}
}
break;
case 3: //manual ev moveamount
if ( button_left ) {
if(userSettings.manualev_moveamount_frac>1){
userSettings.manualev_moveamount_frac-=1;
}
}
if ( button_right ) {
if (userSettings.manualev_moveamount_frac<MAXIMUM_MANUAL_EV_MOVEAMOUNT_FRAC){
userSettings.manualev_moveamount_frac+=1;
}
}
break;
case 4: //Turn Off
poweroff();
4 years ago
break;
}
if ( button_center ){
settings_itemActive=false; //return to item selection
}
}
}
4 years ago
void handleInputs_Meteringmodeselection()
{
if ( button_center ) { //next or back to main screen
if (millis()-millis_lastchange<TIME_METERINGMODESELECTION_SHUTDOWN_SHORTCUT) { //double press select (center) to poweroff
poweroff(); //Turn off
}
4 years ago
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;
}
}
4 years ago
float reciprocFloat(float p){
if (p<1){
return (1.0f/( (int)(p*1000000) ) )*1000000 ;
}else{
return (1/p);
}
}
4 years ago
float getEV(){
float _ev=0;
if (meteringmode == METERINGMODE_REFLECTIVE){ //### SPOT