Code for timed exposure almost completed. Still needs physical testing

This commit is contained in:
Matt McWilliams 2025-11-28 16:54:32 -08:00
parent 91bd002074
commit 1f8fb60fc1
3 changed files with 330 additions and 170 deletions

View File

@ -3,9 +3,9 @@
void Intval2::begin () {
PinsInit();
ButtonsInit();
//timed_open = OpenTiming();
PinsInit();
ButtonsInit();
//timed_open = OpenTiming();
}
void Intval2::loop () {
@ -22,201 +22,309 @@ void Intval2::loop () {
if (running) {
if (timed_exposure) {
TimedExposureReadMicroswitch();
TimedExposureWatch();
} else {
ReadMicroswitch();
}
}
if (opening) {
OpeningWatchDelay();
}
if (closing) {
ReadMicroswitch();
}
if (!running && !timelapse && !delaying){
delay(LOOP_DELAY);
}
}
void Intval2::PinsInit () {
pinMode(PIN_MOTOR_FORWARD, OUTPUT);
pinMode(PIN_MOTOR_BACKWARD, OUTPUT);
pinMode(PIN_MICROSWITCH, INPUT_PULLUP);
pinMode(PIN_INDICATOR, OUTPUT);
pinMode(PIN_MOTOR_FORWARD, OUTPUT);
pinMode(PIN_MOTOR_BACKWARD, OUTPUT);
pinMode(PIN_MICROSWITCH, INPUT_PULLUP);
pinMode(PIN_INDICATOR, OUTPUT);
}
void Intval2::ButtonsInit () {
for (int i = 0; i < 4; i++) {
pinMode(BUTTONS[i], INPUT_PULLUP);
}
for (int i = 0; i < 4; i++) {
pinMode(BUTTONS[i], INPUT_PULLUP);
}
}
void Intval2::TimelapseWatchDelay () {
if (timer - delay_start >= timelapse_delay) {
delaying = false;
Camera();
}
}
boolean Intval2::WatchMicroswitchDelay () {
if (timer - frame_start >= MICROSWITCH_DELAY) {
return true;
}
return false;
if (timer - delay_start >= timelapse_delay) {
delaying = false;
Camera();
}
}
void Intval2::ReadMicroswitch () {
if (WatchMicroswitchDelay()) {
microswitch_position = digitalRead(PIN_MICROSWITCH);
if (microswitch_position == LOW
&& microswitch_primed == false) {
microswitch_primed = true;
} else if (microswitch_position == HIGH
&& microswitch_primed == true) {
Stop();
}
delay(2);//smooths out signal
}
if (timer - frame_start >= MICROSWITCH_DELAY) {
microswitch_position = digitalRead(PIN_MICROSWITCH);
if (microswitch_position == LOW && !microswitch_primed) {
microswitch_primed = true;
} else if (microswitch_position == HIGH && microswitch_primed) {
if (running) {
Stop();
} else if (closing) {
ClosingStop();
}
}
delay(2); //smooths out signal
}
}
void Intval2::TimedExposureReadMicroswitch () {
//TODO: FIX
if (!timed_exposure_open) {
if (timer - frame_start > timed_open
&& timer - frame_start < timed_open + timed_delay) {
TimedExposurePause();
} else if (timer - frame_start > timed_open + timed_delay) {
microswitch_position = digitalRead(PIN_MICROSWITCH);
if (microswitch_position == HIGH) {
Stop();
}
delay(2);//smooths out signal
}
}
//TODO: FIX
if (timed_exposure_open && timer - frame_start > timed_open + timed_delay) {
TimedExposureStart();
}
void Intval2::OpeningWatchDelay () {
if (opening && timer - open_start >= open_stop) {
OpeningStop();
}
}
void Intval2::Direction (boolean state) {
direction = state;
}
void Intval2::Exposure (unsigned long ms) {
if (ms < 600) {
timed_exposure_ms = 0;
timed_exposure = false;
//timed_open = OpenTiming();
} else {
//timed_delay = timed_exposure_val - BOLEX_C;
timed_exposure_ms = ms;
timed_exposure = true;
}
}
void Intval2::Camera () {
frame_start = millis();
if (timed_exposure) {
timed_exposure_opening = true;
open_start = millis();
if (direction) {
open_stop = round((float) avg * MOTOR_OPEN_FORWARD);
timed_exposure_delay = 0;
} else {
open_stop = round((float) avg * MOTOR_OPEN_BACKWARD);
timed_exposure_delay = 0;//
}
}
MotorStart();
running = true;
microswitch_primed = false;
}
void Intval2::Stop () {
delay(10); //examine
analogWrite(PIN_MOTOR_FORWARD, 0);
analogWrite(PIN_MOTOR_BACKWARD, 0);
running = false;
microswitch_primed = false;
delay(10); //examine
MotorStop();
if (direction) {
counter += 1;
} else {
counter -= 1;
}
exposure = timer - frame_start;
running = false;
closed = true;
open = false;
exposure = timer - frame_start;
if (timed_exposure) {
timed_exposure_avg = round((timed_exposure_avg + exposure) / 2);
} else {
avg = round((avg + exposure) / 2);
}
if (direction) {
counter += 1;
} else {
counter -= 1;
}
if (timelapse) {
delaying = true;
delay_start = millis();
}
if (timed_exposure) {
timed_exposure_avg = round((timed_exposure_avg + exposure) / 2);
close_avg = round((close_avg + (timer - close_start)) / 2);
timed_exposure_closing = false;
timed_exposure_opening = false;
timed_exposure_open = false;
} else {
avg = round((avg + exposure) / 2);
}
if (timelapse) {
delaying = true;
delay_start = millis();
}
}
void Intval2::TimedExposureStart () {
timed_exposure_open = false;
if (direction) {
analogWrite(PIN_MOTOR_FORWARD, MOTOR_PWM);
analogWrite(PIN_MOTOR_BACKWARD, 0);
} else {
analogWrite(PIN_MOTOR_BACKWARD, MOTOR_PWM);
analogWrite(PIN_MOTOR_FORWARD, 0);
}
void Intval2::Open () {
opening = true;
closing = false;
open = false;
closed = false;
open_start = millis();
frame_start = millis();
if (direction) {
open_stop = round((float) avg * MOTOR_OPEN_FORWARD);
} else {
open_stop = round((float) avg * MOTOR_OPEN_BACKWARD);
}
if (!open) {
MotorStart();
} else {
opening = false;
}
}
void Intval2::OpeningStop () {
MotorStop();
opening = false;
open = true;
open_avg = round(((timer - open_start) + open_avg) / 2);
}
void Intval2::Close () {
closing = true;
opening = false;
open = false;
closed = false;
close_start = millis();
frame_start = millis();
if (!closed) {
MotorStart();
} else {
closing = false;
}
}
void Intval2::ClosingStop () {
MotorStop();
closing = false;
closed = true;
close_avg = round(((timer - close_start) + close_avg) / 2);
}
void Intval2::MotorStart () {
if (direction) {
analogWrite(PIN_MOTOR_FORWARD, MOTOR_PWM);
analogWrite(PIN_MOTOR_BACKWARD, 0);
} else {
analogWrite(PIN_MOTOR_BACKWARD, MOTOR_PWM);
analogWrite(PIN_MOTOR_FORWARD, 0);
}
}
void Intval2::MotorStop () {
analogWrite(PIN_MOTOR_FORWARD, 0);
analogWrite(PIN_MOTOR_BACKWARD, 0);
}
void Intval2::TimedExposureClose () {
MotorStart();
open = false;
timed_exposure_open = false;
timed_exposure_closing = true;
close_start = millis();
}
void Intval2::TimedExposurePause () {
timed_exposure_open = true;
analogWrite(PIN_MOTOR_FORWARD, 0);
analogWrite(PIN_MOTOR_BACKWARD, 0);
timed_exposure_open = true;
timed_exposure_opening = false;
open = true;
MotorStop();
open_avg = round(((timer - open_start) + open_avg) / 2);
}
void Intval2::TimedExposureWatch () {
if (timed_exposure_opening) {
if (timer - frame_start >= open_stop) {
TimedExposurePause();
}
} else if (timed_exposure_open) {
if (timer - frame_start >= open_stop + timed_exposure_delay) {
TimedExposureClose();
}
} else if (timed_exposure_closing) {
ReadMicroswitch();
}
}
void Intval2::Button (uint8_t index) {
int val = digitalRead(BUTTONS[index]); // ;)
if (val != button_states[index]) {
if (val == LOW) { // pressed
button_times[index] = millis();
} else if (val == HIGH) { // not pressed
button_time = millis() - button_times[index]; //time?
ButtonEnd(index, button_time);
}
}
button_states[index] = val;
int val = digitalRead(BUTTONS[index]); // ;)
if (val != button_states[index]) {
if (val == LOW) {
// pressed
button_times[index] = millis();
} else if (val == HIGH) {
// not pressed
button_time = millis() - button_times[index]; //time?
ButtonEnd(index, button_time);
}
}
button_states[index] = val;
}
void Intval2::ButtonEnd (uint8_t index, long time) {
if (index == 0) {
if (time > 1000) {
if (!timelapse && !running) {
timelapse = true;
Output(2, 75);
Camera();
}
} else {
if (timelapse) {
timelapse = false;
//Output(2, 75);
} else {
Camera();
}
}
} else if (index == 1) { //set delay
if (time < 42) {
timelapse_delay = 42;
Output(1, 500);
} else {
timelapse_delay = time;
Output(2, 250);
}
} else if (index == 2) { // set speed
if (time >= 1000) {
//timed_delay = time - BOLEX_C;
timed_exposure = true;
Output(2, 250);
} else if (time < 1000) {
//timed_delay = 0;
timed_exposure = false;
Output(1, 500);
}
} else if (index == 3) { //set direction
if (time < 1000) {
direction = true;
Output(1, 500);
} else if (time > 1000) {
direction = false;
Output(2, 250);
}
}
time = 0;
if (index == 0) {
if (time > 1000) {
if (!timelapse && !running) {
timelapse = true;
Output(2, 75);
Camera();
}
} else {
if (timelapse) {
timelapse = false;
//Output(2, 75);
} else {
Camera();
}
}
} else if (index == 1) { //set delay
if (time < 42) {
timelapse_delay = 42;
Output(1, 500);
} else {
timelapse_delay = time;
Output(2, 250);
}
} else if (index == 2) { // set speed
if (time >= 1000) {
//timed_delay = time - BOLEX_C;
timed_exposure = true;
Output(2, 250);
} else if (time < 1000) {
//timed_delay = 0;
timed_exposure = false;
Output(1, 500);
}
} else if (index == 3) { //set direction
if (time < 1000) {
direction = true;
Output(1, 500);
} else if (time > 1000) {
direction = false;
Output(2, 250);
}
}
//time = 0;
}
void Intval2::Output (uint8_t number, uint16_t len) {
for (int i = 0; i < number; i++) {
Indicator(true);
delay(len);
Indicator(false);
delay(42);
}
for (int i = 0; i < number; i++) {
Indicator(true);
delay(len);
Indicator(false);
delay(42);
}
}
void Intval2::Indicator (boolean state) {
if (state) {
digitalWrite(PIN_INDICATOR, HIGH);
} else {
digitalWrite(PIN_INDICATOR, LOW);
}
if (state) {
digitalWrite(PIN_INDICATOR, HIGH);
} else {
digitalWrite(PIN_INDICATOR, LOW);
}
}
String Intval2::State () {
if (timed_exposure) {
return String(timed_exposure_avg);
}
return String(avg);
if (timed_exposure) {
return String(timed_exposure_avg);
}
return String(avg);
}

View File

@ -29,9 +29,14 @@ class Intval2 {
volatile boolean running = false;
volatile boolean timelapse = false;
volatile boolean timed_exposure = false;
volatile boolean opening = false;
volatile boolean closing = false;
volatile boolean delaying = false;
volatile boolean open = false; //is the shutter open
volatile boolean open = false;
volatile boolean closed = true;
volatile boolean timed_exposure_open = false; //is the shutter open only during a timed exposure
volatile boolean timed_exposure_opening = false;
volatile boolean timed_exposure_closing = false;
volatile uint8_t microswitch_position = 0;
volatile boolean microswitch_primed = false;
@ -44,37 +49,53 @@ class Intval2 {
volatile unsigned long timer;
volatile unsigned long frame_start = 0;
volatile unsigned long delay_start = 0;
volatile unsigned long open_start = 0;
volatile unsigned long close_start = 0;
volatile unsigned long timelapse_delay = 42; //time between frames during timelapse
volatile String timed_exposure_str = "600";
volatile unsigned long timed_exposure_val = 600;
volatile unsigned long timed_open = 100; //ms after start_frame to pause
volatile unsigned long timed_delay = 0;
volatile unsigned long timed_exposure_ms = 0;
volatile unsigned long open_stop = 100; //ms to stop when camera is opened
volatile unsigned long timed_exposure_delay = 0; //ms to delay once camera is open
volatile unsigned long exposure = 0;
volatile unsigned long avg = 600;
volatile unsigned long timed_exposure_avg = 600;
volatile unsigned long open_avg = 300;
volatile unsigned long close_avg = 300;
void PinsInit();
void ButtonsInit();
void Button (uint8_t index);
void ButtonEnd (uint8_t index, long time);
boolean WatchMicroswitchDelay();
void TimelapseWatchDelay();
void OpeningWatchDelay();
void ReadMicroswitch();
void TimedExposureReadMicroswitch();
void TimedExposureStart();
void TimedExposureWatch();
void TimedExposurePause();
void TimedExposureClose();
void Stop();
void OpeningStop();
void ClosingStop();
void Output(uint8_t number, uint16_t len);
void Indicator(boolean state);
void MotorStart();
void MotorStop();
public:
void begin();
void loop();
void Camera();
void Open();
void Close();
void Direction(boolean state);
void Exposure(unsigned long ms);
String State();
};

View File

@ -2,43 +2,74 @@
#include "Intval2.h"
McopySerial mc;
Intval2 intval;
Intval2 intval2;
volatile char cmd_char = 'z';
volatile boolean camera_running;
volatile boolean open_running;
volatile boolean close_running;
String timed_exposure_str = "0";
volatile unsigned long timed_exposure_ms = 0;
void setup() {
mc.begin(mc.CAMERA_IDENTIFIER);
intval.begin();
intval2.begin();
}
void loop () {
cmd_char = mc.loop();
cmd(cmd_char);
intval.loop();
intval2.loop();
}
void cmd (char val) {
if (val == mc.CAMERA) {
//intval::Camera();
camera_running = true;
intval2.Camera();
} else if (val == mc.CAMERA_FORWARD) {
//CameraDirection(true);
SetDirection(true);
} else if (val == mc.CAMERA_BACKWARD) {
//CameraDirection(false);
SetDirection(false);
} else if (val == mc.CAMERA_OPEN) {
open_running = true;
//CameraOpen();
} else if (val == mc.CAMERA_CLOSE) {
close_running = true;
//CameraClose();
} else if (val == mc.CAMERA_EXPOSURE) {
//CameraExposure();
SetExposure();
} else if (val == mc.STATE) {
//State();
State();
}
}
void State () {
String stateString = String(mc.STATE);
stateString += String(mc.CAMERA_EXPOSURE);
//stateString += intval2.State();
stateString += intval2.State();
stateString += String(mc.STATE);
mc.sendString(stateString);
}
void SetDirection (boolean state) {
intval2.Direction(state);
if (state) {
mc.confirm(mc.CAMERA_FORWARD);
mc.log("camera_direction(true)");
} else {
mc.confirm(mc.CAMERA_FORWARD);
mc.log("camera_direction(false)");
}
}
//sending "0" will reset to default exposure time
void SetExposure () {
timed_exposure_str = mc.getString();
timed_exposure_ms = timed_exposure_str.toInt();
intval2.Exposure(timed_exposure_ms);
mc.confirm(mc.CAMERA_EXPOSURE);
mc.log("Set exposure time to: ");
mc.log(timed_exposure_str);
}