Skip to content

Solution: Sync Flash to GS Camera with use of the XVS PIN and an Pico or Arduino #4034

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
emc02 opened this issue Feb 20, 2025 · 5 comments
Labels
backlog We'll be getting to it eventually camera 📷

Comments

@emc02
Copy link

emc02 commented Feb 20, 2025

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;
  }
}
@emc02 emc02 changed the title Sync Flash to GS Camera with use of the XVS PIN and an Pico or Arduino Solution: Sync Flash to GS Camera with use of the XVS PIN and an Pico or Arduino Feb 20, 2025
@lurch
Copy link
Contributor

lurch commented Feb 20, 2025

ping @davidplowman and @naushir

@davidplowman
Copy link
Contributor

@njhollinghurst might be a good person to ask

@njhollinghurst
Copy link
Contributor

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).

Copy link

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.

@lurch lurch added backlog We'll be getting to it eventually and removed stale issue labels Apr 27, 2025
@njhollinghurst
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog We'll be getting to it eventually camera 📷
Projects
None yet
Development

No branches or pull requests

4 participants