documentation icon indicating copy to clipboard operation
documentation copied to clipboard

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

Open emc02 opened this issue 10 months ago • 6 comments

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 avatar Feb 20 '25 12:02 emc02

ping @davidplowman and @naushir

lurch avatar Feb 20 '25 16:02 lurch

@njhollinghurst might be a good person to ask

davidplowman avatar Feb 20 '25 16:02 davidplowman

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

njhollinghurst avatar Feb 20 '25 17:02 njhollinghurst

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.

github-actions[bot] avatar Apr 27 '25 02:04 github-actions[bot]

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 avatar May 23 '25 14:05 njhollinghurst

@njhollinghurst Would this be more useful as a tutorial, perhaps?

katshann-raspberry avatar Nov 17 '25 11:11 katshann-raspberry