Hi bob , sorry for the late reply here...
I tried both with latest depthai release at the moment (2.30.0.0) and with the above version as well (right on top of 2.29.0.0), I can see the issues (expected) when the sync input is left floating, but the external frame sync works well for me when I provide the signal, pulse/square generated by the Arbitrary Waveform Generator module on a Rigol oscilloscope, 10Hz, 1.8V level (1.8V amplitude with 900mV offset to get in 0V..1.8V range), duty-cycle 10% to 50% (but not important).
OV9282/OV9782 are very sensitive to the moment this signal is enabled, it's important to have the signal on by the time the streaming is started.
Jitter or other kind of fluctuations on this signal are generally not acceptable for OV9282, it breaks its internal operations. But up to half a row time should be acceptable the datasheet says, so up to 4us jitter.
Could you check very slightly changing +/- the frequency on the generator, is it improving?
I tested with python3 utilities/cam_test.py -fps 10
with this script:
luxonis/depthai-pythonmain → alex-luxonis
:depthai-python:fsync_external_ffc_4p
These are the relevant changes that also check and properly enable the GPIOs, you can check as well with your FFC-4P board revision:
cam[c].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
# FSYNC setup on OAK-FFC-4P
script = pipeline.create(dai.node.Script)
script.setProcessor(dai.ProcessorType.LEON_CSS)
script.setScript("""
import time
import GPIO
# Script static arguments
fps = %f
calib = Device.readCalibration2().getEepromData()
prodName = calib.productName
boardName = calib.boardName
boardRev = calib.boardRev
node.warn(f'Product name : {prodName}')
node.warn(f'Board name : {boardName}')
node.warn(f'Board revision: {boardRev}')
revision = -1
# Very basic parsing here, TODO improve
if len(boardRev) >= 2 and boardRev[0] == 'R':
revision = int(boardRev[1])
node.warn(f'Parsed revision number: {revision}')
# Defaults for OAK-FFC-4P older revisions (<= R5)
GPIO_FSIN_2LANE = 41 # COM_AUX_IO2
GPIO_FSIN_4LANE = 40
GPIO_FSIN_MODE_SELECT = 6 # Drive 1 to tie together FSIN_2LANE and FSIN_4LANE
if revision >= 6:
GPIO_FSIN_2LANE = 41 # still COM_AUX_IO2, no PWM capable
GPIO_FSIN_4LANE = 42 # also not PWM capable
GPIO_FSIN_MODE_SELECT = 38 # Drive 1 to tie together FSIN_2LANE and FSIN_4LANE
# Note: on R7 GPIO_FSIN_MODE_SELECT is pulled up, driving high isn't necessary (but fine to do)
# GPIO initialization
# IN not necessary, should be default
GPIO.setup(GPIO_FSIN_2LANE, GPIO.IN)
GPIO.setup(GPIO_FSIN_4LANE, GPIO.IN)
GPIO.setup(GPIO_FSIN_MODE_SELECT, GPIO.OUT)
GPIO.write(GPIO_FSIN_MODE_SELECT, 1)
period = 1 / fps
node.warn(f'FPS: {fps} Period: {period}')
""" % (args.fps))