Solution: Sync Flash to GS Camera with use of the XVS PIN and an Pico or Arduino
I was working on that for 2 days and finally found a perfect solution that is not in the docs. I don't know how to make a Pull Request correctly, but maybe someone else will use my information.
I Used a BC547 transistor XVS--1k--BASE PicoPIN--1k--COLLECTOR GND--EMITTER
GND has to be connected between Pico and Camera.
I am collecting the picture with an C++ Code in StillCapure Mode and fixed FrameDurationTime to 1ms. If you change this, you should change the FLASH_TIMER_DURATION too. This could also be done with serial commands directly to the Pico to match the values (not in the code). I am always starting and stopping the camera in the code, because I don't want to flash all the time.
cam_device->start(); wait till captured... cam_device->stop();
The XVS Pin triggers twice for every pic. HIGH - 20us - LOW - 32384us - (takes picture for FrameDurationTime (e.g. 1000us)) - HIGH - 20us - LOW
The picture is taken before(!!!) the second HIGH signal. So the timing is important! I am triggering the flash 32384us after the first HIGH signal.
Arduino Code:
#define TriggerPIN 3 //D03 (Uno, Nano, Mini)
#define StatusLED 13 //D13
// to find the perfect timing window set FLASH_TIMER_DURATION=2 and then change the FLASH_TIMER_DELAY up and down to find the limits (point the camera on the Status LED and watch the brightness change)
// 502 off
// 503 weak
// 504 better
// 505 full
// .
// .
// .
// 518 full
// 519 better
// 520 weak
// 521 off
`
#define FLASH_TIMER_DELAY 505 // (16 MHz / 1024) * 0.032384 - 1 ≈ 505 für 32,384ms Interrupt
#define FLASH_TIMER_DURATION 15 // (16 MHz / 1024) * 0.001024 - 1 ≈ 15 für 1,024ms Interrupt
unsigned long starttime, endtime, duration, pause;
unsigned int triggered=0, status=0, i=0, FLASH_ON=0;
void setup() {
pinMode(StatusLED,OUTPUT); // set PIN to OUTPUT
digitalWrite(StatusLED,LOW); // set PIN to LOW (StatusLED OFF)
pinMode(TriggerPIN,INPUT_PULLUP); // set PIN to INPUT
attachInterrupt(digitalPinToInterrupt(TriggerPIN),TriggerISR,CHANGE); // SET InterruptPIN, ISR and Mode
// Timer
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // CTC Modus, Prescaler 1024
OCR1A = FLASH_TIMER_DELAY;
TIMSK1 = (1 << OCIE1A); // Timer1 Compare Match Interrupt aktivieren
interrupts(); // enable Interrupts
Serial.begin(115200); // initialize serial
}
void loop() {
if (triggered==0) {
TCNT1 = 0; // Timer reset
}
if (status==1) {
status=0;
Serial.println(i);
Serial.print("pause:");
Serial.print(pause/1000);
Serial.println("ms");
Serial.print("duration:");
Serial.print(duration);
Serial.println("us");
Serial.println("-------------------------");
i++;
}
}
void TriggerISR() { // ISR function excutes when PIN is triggered
if (digitalRead(TriggerPIN)==HIGH) { // check if PIN is high or low and set Flash PIN
if (triggered==0) {
triggered=1;
TCNT1 = 0; // Timer reset
}
starttime = micros();
pause=(starttime-endtime);
}
else {
endtime = micros();
duration=endtime-starttime;
status=1; // allow posting new Timings
}
}
ISR(TIMER1_COMPA_vect) { // Timer
if (FLASH_ON==0) {
digitalWrite(StatusLED,HIGH);
TCNT1 = FLASH_TIMER_DELAY - FLASH_TIMER_DURATION; // Timer reset to 1ms
FLASH_ON=1;
}
else {
digitalWrite(StatusLED,LOW);
FLASH_ON=0;
triggered=0;
}
}
ping @davidplowman and @naushir
@njhollinghurst might be a good person to ask
Thank you! It looks like an interesting use of XVS that we should test and document.
It might be a little while before we can do it. (Maybe as part of a bigger overhaul of the synchronized-camera stuff which still has some issues with pull-ups and back-powering).
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Looking at this, it's not obvious how to incorporate it into documentation...
- It would need a new section, which perhaps should also cover HQ Cam FSTROBE (@naushir if we still support it?)
- The code would want rewriting to use Pico SDK (or PIO?) rather than Arduino API.
- A lazier (for me) option might be: just to describe the XVS output and its relation to exposure time.
@njhollinghurst Would this be more useful as a tutorial, perhaps?