#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1 //USE -1 FOR FASTER REFRESH?
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int RELEASEBUTTON = 7; // SHUTTER RELEASE BUTTON PIN
const int MOSFETGATE = 8; //MOSFET Gate to fire shutter solenoid
const int SSCHANGETEMP = 4; // temp button to change speedConv value
const int REDPIN = 6;
const int GREENPIN = 5;
const int BLUEPIN = 9;
int shutterSpeed[10] = {2, 4, 8, 16, 33, 66, 125, 250, 500, 1000};
//String speedRead = "1/60"; //HOLDS TEXT FOR OLED DISPLAY
// convert speedRead to an array of text to reduce processing IF's
int speedCount = 0;
int speedConv = 0; // HOLDS ADJUSTED VALUE FROM ROTARY ENCODER
int shutterGate = LOW; // Define shutter button digital state
// FOR ROTARY ENCODER
//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
//setup RGB button
int redValue = 115;
int greenValue = 225;
int blueValue = 255;
void setup() {
Serial.begin(9600);
//Set up OLED Display
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // INITIALIZE OLED DISPLAY
// set up buttons
pinMode(MOSFETGATE, OUTPUT);// set MOSFET shutter gate pin to output mode
pinMode(RELEASEBUTTON, INPUT); // set shutter release button to input
pinMode(SSCHANGETEMP, INPUT); // set temp shutterspeed change button to input
pinMode(REDPIN, OUTPUT);
pinMode(BLUEPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
digitalWrite(RELEASEBUTTON, HIGH); //start shutter release button on HIGH
digitalWrite(SSCHANGETEMP, HIGH); // start shutterspeed change button on HIGH
digitalWrite(MOSFETGATE, shutterGate); // start mosfet gate on LOW
// start write to RGB
analogWrite(REDPIN, (255 - redValue));
analogWrite(GREENPIN, (255 - greenValue));
analogWrite(BLUEPIN, (255 - blueValue));
// set up Rotary Encoder
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
// FOR ROTARY ENCODER
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
for (int thisSpeed = 0; thisSpeed < speedCount; thisSpeed++) { //INITIALIZE ARRAY
pinMode(shutterSpeed[thisSpeed], OUTPUT);
}
}
void loop() {
if (digitalRead(RELEASEBUTTON) == LOW) {
shutterGate = HIGH; //ARM FIRST CURTAIN TO RELEASE
digitalWrite(MOSFETGATE, shutterGate); //RELEASE FIRST CURTAIN
//Serial.println("shutter is open");
// button led changes to red during exposure, switch to off in the future?
analogWrite(REDPIN, -255);
analogWrite(GREENPIN, -0);
analogWrite(BLUEPIN, -0);
// millis?
delay(shutterSpeed[speedConv]);// KEEP OPEN FOR X AMOUNT OF TIME
shutterGate = LOW; // close shutter
digitalWrite(MOSFETGATE, shutterGate);
//Serial.println("shutter is closed");
// return rgb button to default color
analogWrite(REDPIN, (255 - redValue));
analogWrite(GREENPIN, (255 - greenValue));
analogWrite(BLUEPIN, (255 - blueValue));
// pause before activating shutter again
delay(500);
}
if (encoderValue < 0){ //DO NOT ALLOW encoder BELOW 1
encoderValue = 0;
}
if (encoderValue > 36){ // DO NOT ALLOW encoder ABOVE 36
encoderValue = 36;
}
speedConv = encoderValue / 4; //DIVIDE BY 4 THEN save to be referenced by shutterspeed array
// if temp shutterspeed button is pressed, increment shutter speed
if (digitalRead(SSCHANGETEMP) == LOW) {
if (speedConv < 10){speedConv += 1;}
if (speedConv > 10){speedConv == 0;}
delay(250);
}
//define shutterdspeed text to display based on encoder position "speedConv"
// should this get moved to its own function to save space?
/*
if (speedConv == 0){ speedRead = "1/500"; }
if (speedConv == 1){ speedRead = "1/250"; }
if (speedConv == 2){ speedRead = "1/125"; }
if (speedConv == 3){ speedRead = "1/60"; }
if (speedConv == 4){ speedRead = "1/30"; }
if (speedConv == 5){ speedRead = "1/15"; }
if (speedConv == 6){ speedRead = "1/8"; }
if (speedConv == 7){ speedRead = "1/4"; }
if (speedConv == 8){ speedRead = "1/2"; }
if (speedConv == 9){ speedRead = "1\""; }
*/
//Serial.print("encoderValue = ");
//Serial.println(encoderValue);
//Serial.print("speedConv = ");
//Serial.println(speedConv);
//Serial.println();
// update OLED Display
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0,0);
display.print(shutterSpeed[speedConv]);
display.display();
} // end loop
/*
void longExptimer(){
//if longExp = true
analogWrite(REDPIN, -255);
analogWrite(GREENPIN, 0);
analogWrite(BLUEPIN, 0);
millis(){250};
analogWrite(REDPIN, 0);
analogWrite(GREENPIN, 0);
analogWrite(BLUEPIN, 0);
millis(){750};
//add oled timer countdown / countup
//else
// return to default rgb color
analogWrite(REDPIN, (255 - redValue));
analogWrite(GREENPIN, (255 - greenValue));
analogWrite(BLUEPIN, (255 - blueValue));
}
// RGB
//CANNOT RUN IN PARALLEL BEHIND CODE? revise for ESP32 version or try millis
void rgbFade(){
#define delayTime 10 // fading time between colors
redValue = 255; // choose a value between 1 and 255 to change the color.
greenValue = 0;
blueValue = 0;
for(int i = 0; i < 255; i += 1) // fades out red bring green full when i=255
{
redValue -= 1;
greenValue += 1;
// write values to rgb
analogWrite(REDPIN, (255 - redValue));
analogWrite(GREENPIN, (255 - greenValue));
delay(delayTime);
}
redValue = 0;
greenValue = 255;
blueValue = 0;
for(int i = 0; i < 255; i += 1) // fades out green bring blue full when i=255
{
greenValue -= 1;
blueValue += 1;
//write values to rgb
analogWrite(GREENPIN, (255 - greenValue));
analogWrite(BLUEPIN, (255 - blueValue));
delay(delayTime);
}
redValue = 0;
greenValue = 0;
blueValue = 255;
for(int i = 0; i < 255; i += 1) // fades out blue bring red full when i=255
{
blueValue -= 1;
redValue += 1;
//write values to rgb
analogWrite(BLUEPIN, (255 - blueValue));
analogWrite(REDPIN, (255 - redValue));
delay(delayTime);
}
} //end rgbFade
*/
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}