Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ static const int SEND_HARDWARE_TRIGGER = 30;
static const int SET_STROBE_DELAY = 31;
static const int SET_AXIS_DISABLE_ENABLE = 32;
static const int SET_PIN_LEVEL = 41;
static const int SET_CONTINUOUS_HARDWARE_TRIGGERING = 42;
static const int CANCEL_CONTINUOUS_HARDWARE_TRIGGERING = 43;
static const int INITFILTERWHEEL = 253;
static const int INITIALIZE = 254;
static const int RESET = 255;
Expand All @@ -90,6 +92,7 @@ static const int AXES_XY = 4;
static const int AXIS_W = 5;

static const int BIT_POS_JOYSTICK_BUTTON = 0;
static const int BIT_POS_CONTINUOUS_TRIGGER_ENABLED = 1;

static const int LIM_CODE_X_POSITIVE = 0;
static const int LIM_CODE_X_NEGATIVE = 1;
Expand Down Expand Up @@ -572,38 +575,97 @@ void set_illumination_led_matrix(int source, uint8_t r, uint8_t g, uint8_t b)
turn_on_illumination(); //update the illumination
}

/*********************** Continuous hardware triggering (debug / test setup only!) *************************/
struct continuous_hardware_triggering_state {
bool enabled;
uint32_t triggered_us;
uint32_t not_triggered_us;
uint8_t trigger_channel;
uint16_t requested_frames;

elapsedMicros us_since_last_transition;
uint32_t frames_so_far;
};

static struct continuous_hardware_triggering_state DEFAULT_CONTINUOUS_TRIGGERING_STATE = {
.enabled = false,
.triggered_us = 50000,
.not_triggered_us = 50000,
.trigger_channel = 0,
.requested_frames = 0,

.us_since_last_transition = 0,
.frames_so_far = 0
};

static struct continuous_hardware_triggering_state cont_trig_state = DEFAULT_CONTINUOUS_TRIGGERING_STATE;

void ISR_strobeTimer()
{
for (int camera_channel = 0; camera_channel < 6; camera_channel++)
{
// strobe pulse
if (control_strobe[camera_channel])
{
if (illumination_on_time[camera_channel] <= 30000)
{
// if the illumination on time is smaller than 30 ms, use delayMicroseconds to control the pulse length to avoid pulse length jitter
if ( ((micros() - timestamp_trigger_rising_edge[camera_channel]) >= strobe_delay[camera_channel]) && strobe_output_level[camera_channel] == LOW )
{
turn_on_illumination();
delayMicroseconds(illumination_on_time[camera_channel]);
turn_off_illumination();
control_strobe[camera_channel] = false;
// If we're in continuous triggering mode, ignore other strobing requests and control the illumination ourselves.
if (cont_trig_state.enabled) {
if (cont_trig_state.trigger_channel != camera_channel) {
continue;
}

uint8_t current_level = digitalRead(camera_trigger_pins[camera_channel]);
uint8_t next_level = current_level == HIGH ? LOW : HIGH;

unsigned long this_interval = current_level == HIGH ? cont_trig_state.not_triggered_us : cont_trig_state.triggered_us;
unsigned long elapsed_us = cont_trig_state.us_since_last_transition;
bool need_transition = elapsed_us >= this_interval;

if (need_transition) {
// If this is a transition to low, we also want to turn on illumination. Otherwise turn it off.
// NOTE(imo): LOW corresponds to 5V, HIGH to 0V
if (next_level == LOW) {
//turn_on_illumination();
cont_trig_state.frames_so_far++;
} else {
//turn_off_illumination();
}

digitalWrite(camera_trigger_pins[camera_channel], next_level);
trigger_output_level[camera_channel] = next_level;
cont_trig_state.us_since_last_transition = 0;

// We finished our last trigger if we just went down to 0V (HIGH), and we've seen as many frames as requested.
if (cont_trig_state.frames_so_far >= cont_trig_state.requested_frames && next_level == HIGH) {
cont_trig_state.enabled = false;
}
}
else
} else {
// strobe pulse
if (control_strobe[camera_channel])
{
// start the strobe
if ( ((micros() - timestamp_trigger_rising_edge[camera_channel]) >= strobe_delay[camera_channel]) && strobe_output_level[camera_channel] == LOW )
if (illumination_on_time[camera_channel] <= 30000)
{
turn_on_illumination();
strobe_output_level[camera_channel] = HIGH;
// if the illumination on time is smaller than 30 ms, use delayMicroseconds to control the pulse length to avoid pulse length jitter
if ( ((micros() - timestamp_trigger_rising_edge[camera_channel]) >= strobe_delay[camera_channel]) && strobe_output_level[camera_channel] == LOW )
{
turn_on_illumination();
delayMicroseconds(illumination_on_time[camera_channel]);
turn_off_illumination();
control_strobe[camera_channel] = false;
}
}
// end the strobe
if (((micros() - timestamp_trigger_rising_edge[camera_channel]) >= strobe_delay[camera_channel] + illumination_on_time[camera_channel]) && strobe_output_level[camera_channel] == HIGH)
else
{
turn_off_illumination();
strobe_output_level[camera_channel] = LOW;
control_strobe[camera_channel] = false;
// start the strobe
if ( ((micros() - timestamp_trigger_rising_edge[camera_channel]) >= strobe_delay[camera_channel]) && strobe_output_level[camera_channel] == LOW )
{
turn_on_illumination();
strobe_output_level[camera_channel] = HIGH;
}
// end the strobe
if (((micros() - timestamp_trigger_rising_edge[camera_channel]) >= strobe_delay[camera_channel] + illumination_on_time[camera_channel]) && strobe_output_level[camera_channel] == HIGH)
{
turn_off_illumination();
strobe_output_level[camera_channel] = LOW;
control_strobe[camera_channel] = false;
}
}
}
}
Expand Down Expand Up @@ -1602,6 +1664,37 @@ void loop() {
digitalWrite(pin, level);
break;
}
case SET_CONTINUOUS_HARDWARE_TRIGGERING:
{
uint8_t channel = buffer_rx[2] & 0x0f;
uint8_t triggered_ms = buffer_rx[3];
uint8_t not_triggered_ms = buffer_rx[4];
uint16_t frame_count = (uint32_t)(buffer_rx[5] << 8 | buffer_rx[6]);

noInterrupts();
cont_trig_state.enabled = true;
cont_trig_state.triggered_us = 1000 * (uint32_t)(triggered_ms);
cont_trig_state.not_triggered_us = 1000 * (uint32_t)(not_triggered_ms);
cont_trig_state.trigger_channel = channel;
cont_trig_state.requested_frames = frame_count;

// NOTE(imo): HIGH pulls the line down to 0V, LOW lets it float to 5V.
digitalWrite(camera_trigger_pins[channel], HIGH);
cont_trig_state.frames_so_far = 0;
trigger_output_level[channel] = HIGH;
cont_trig_state.us_since_last_transition = 0;
long cont_illum_time = cont_trig_state.triggered_us + cont_trig_state.not_triggered_us;
illumination_on_time[channel] = cont_illum_time;
interrupts();
break;
}
case CANCEL_CONTINUOUS_HARDWARE_TRIGGERING:
{
noInterrupts();
cont_trig_state.enabled = false;
interrupts();
break;
}
case CONFIGURE_STAGE_PID:
{
int axis = buffer_rx[2];
Expand Down Expand Up @@ -1741,6 +1834,7 @@ void loop() {
is_preparing_for_homing_Z = false;
is_preparing_for_homing_W = false;
cmd_id = 0;
cont_trig_state = DEFAULT_CONTINUOUS_TRIGGERING_STATE;
break;
}
default:
Expand All @@ -1754,45 +1848,16 @@ void loop() {
for (int camera_channel = 0; camera_channel < 6; camera_channel++)
{
// end the trigger pulse
if (trigger_output_level[camera_channel] == LOW && (micros() - timestamp_trigger_rising_edge[camera_channel]) >= TRIGGER_PULSE_LENGTH_us )
{
digitalWrite(camera_trigger_pins[camera_channel], HIGH);
trigger_output_level[camera_channel] = HIGH;
}

/*
// strobe pulse
if(control_strobe[camera_channel])
{
if(illumination_on_time[camera_channel] <= 30000)
noInterrupts();
bool continuous_triggering = cont_trig_state.enabled && cont_trig_state.trigger_channel == camera_channel;
interrupts();
if (!continuous_triggering) {
if (trigger_output_level[camera_channel] == LOW && (micros() - timestamp_trigger_rising_edge[camera_channel]) >= TRIGGER_PULSE_LENGTH_us )
{
// if the illumination on time is smaller than 30 ms, use delayMicroseconds to control the pulse length to avoid pulse length jitter (can be up to 20 us if using the code in the else branch)
if( ((micros()-timestamp_trigger_rising_edge[camera_channel])>=strobe_delay[camera_channel]) && strobe_output_level[camera_channel]==LOW )
{
turn_on_illumination();
delayMicroseconds(illumination_on_time[camera_channel]);
turn_off_illumination();
control_strobe[camera_channel] = false;
}
digitalWrite(camera_trigger_pins[camera_channel], HIGH);
trigger_output_level[camera_channel] = HIGH;
}
else
{
// start the strobe
if( ((micros()-timestamp_trigger_rising_edge[camera_channel])>=strobe_delay[camera_channel]) && strobe_output_level[camera_channel]==LOW )
{
turn_on_illumination();
strobe_output_level[camera_channel] = HIGH;
}
// end the strobe
if(((micros()-timestamp_trigger_rising_edge[camera_channel])>=strobe_delay[camera_channel]+illumination_on_time[camera_channel]) && strobe_output_level[camera_channel]==HIGH)
{
turn_off_illumination();
strobe_output_level[camera_channel] = LOW;
control_strobe[camera_channel] = false;
}
}
}
*/
}
}

// homing - preparing for homing
Expand Down Expand Up @@ -2178,8 +2243,11 @@ void loop() {
if (joystick_button_pressed && millis() - joystick_button_pressed_timestamp > 1000)
joystick_button_pressed = false;

buffer_tx[18] &= ~ (1 << BIT_POS_JOYSTICK_BUTTON); // clear the joystick button bit
buffer_tx[18] = buffer_tx[18] | joystick_button_pressed << BIT_POS_JOYSTICK_BUTTON;
// Entry 18 is a bunch of state bits. We reset them every time, so just clear to 0 here.
buffer_tx[18] = 0;
noInterrupts(); // Hold interrupts for the cont_trig_state check
buffer_tx[18] = (joystick_button_pressed << BIT_POS_JOYSTICK_BUTTON) | (cont_trig_state.enabled << BIT_POS_CONTINUOUS_TRIGGER_ENABLED);
interrupts();

// Calculate and fill out the checksum. NOTE: This must be after all other buffer_tx modifications are done!
uint8_t checksum = crc8ccitt(buffer_tx, MSG_LENGTH - 1);
Expand Down
4 changes: 3 additions & 1 deletion software/control/_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ class CMD_SET:
SET_STROBE_DELAY = 31
SET_AXIS_DISABLE_ENABLE = 32
SET_PIN_LEVEL = 41
SET_CONTINUOUS_HARDWARE_TRIGGERING = 42
CANCEL_CONTINUOUS_TRIGGERING = 43
INITFILTERWHEEL = 253
INITIALIZE = 254
RESET = 255
Expand All @@ -173,7 +175,7 @@ class CMD_SET2:


BIT_POS_JOYSTICK_BUTTON = 0
BIT_POS_SWITCH = 1
BIT_POS_CONTINUOUS_TRIGGERING = 1


class HOME_OR_ZERO:
Expand Down
Loading
Loading