|
1 | 1 | == Synchronous Captures
|
2 | 2 |
|
3 |
| -Both the HQ Camera and the Global Shutter Camera, have support for synchronous captures. |
4 |
| -Making use of the XVS pin (Vertical Sync) allows one camera to pulse when a frame capture is initiated. |
5 |
| -The other camera can then listen for this sync pulse, and capture a frame at the same time as the other camera. |
| 3 | +The High Quality (HQ) Camera supports synchronous captures. |
| 4 | +One camera (the "source") can be configured to generate a pulse on its XVS (Vertical Sync) pin when a frame capture is initiated. |
| 5 | +Other ("sink") cameras can listen for this pulse, and capture a frame at the same time as the source camera. |
6 | 6 |
|
7 |
| -=== Using the HQ Camera |
| 7 | +This method is largely superseded by xref:../computers/camera_software.adoc#software-camera-synchronisation[software camera synchronisation] which can operate over long distances without additional wires and has sub-millisecond accuracy. But when cameras are physically close, wired synchronisation may be used. |
8 | 8 |
|
9 |
| -For correct operation, both cameras require a 1.65V pull up voltage on the XVS line, which is created by a potential divider through the 3.3V and GND pins on the Raspberry Pi. |
| 9 | +NOTE: Global Shutter (GS) Cameras can also be operated in a synchronous mode. However, the source camera will record one extra frame. Instead, for GS Cameras we recommend using an xref:camera.adoc#external-trigger-on-the-gs-camera[external trigger source]. You cannot synchronise a GS Camera and an HQ Camera. |
10 | 10 |
|
11 |
| -image::images/synchronous_camera_wiring.jpg[alt="Image showing potential divider setup",width="50%"] |
| 11 | +=== Connecting the cameras |
12 | 12 |
|
13 |
| -Create a potential divider from two 10kΩ resistors to 3.3V and ground (to make 1.65V with an effective source impedance of 5kΩ). This can be connected to either Raspberry Pi. |
| 13 | +Solder a wire to the XVS test point of each camera, and connect them together. |
14 | 14 |
|
15 |
| -Solder the GND and XVS test points of each HQ Camera board to each other. |
| 15 | +Solder a wire to the GND test point of each camera, and connect them together. |
16 | 16 |
|
17 |
| -Connect the XVS wires to the 1.65V potential divider pull-up. |
| 17 | +*For GS Cameras only,* you will also need to connect the XHS (Horizontal Sync) test point of each camera together. On any GS Camera that you wish to act as a sink, bridge the two halves of the MAS pad with solder. |
18 | 18 |
|
19 |
| -==== Boot up both Raspberry Pis |
| 19 | +NOTE: An earlier version of this document recommended an external pull-up for XVS. This is no longer recommended. Instead, ensure you have the latest version of Raspberry Pi OS and set the `always-on` property for all connected cameras. |
20 | 20 |
|
21 |
| -The file `/sys/module/imx477/parameters/trigger_mode` determines which board outputs pulses, or waits to receive pulses (source and sink). |
22 |
| -This parameter can only be altered in superuser mode. |
| 21 | +=== Driver configuration |
23 | 22 |
|
24 |
| -Run the following commands to configure the sink: |
| 23 | +You will need to configure the camera drivers to keep their 1.8V power supplies on when not streaming, and optionally to select the source and sink roles. |
25 | 24 |
|
26 |
| -[source,console] |
| 25 | +==== For the HQ Camera |
| 26 | + |
| 27 | +Edit `/boot/firmware/config.txt`. Change `camera_auto_detect=1` to `camera_auto_detect=0`. |
| 28 | + |
| 29 | +Append this line for a source camera: |
| 30 | +[source] |
27 | 31 | ----
|
28 |
| -$ sudo su |
29 |
| -$ echo 2 > /sys/module/imx477/parameters/trigger_mode |
30 |
| -$ exit |
| 32 | +dtoverlay=imx477,always-on,sync-source |
31 | 33 | ----
|
32 | 34 |
|
33 |
| -Run the following commands to configure the source: |
34 |
| - |
35 |
| -[source,console] |
| 35 | +Or for a sink: |
| 36 | +[source] |
36 | 37 | ----
|
37 |
| -$ sudo su |
38 |
| -$ echo 1 > /sys/module/imx477/parameters/trigger_mode |
39 |
| -$ exit |
| 38 | +dtoverlay=imx477,always-on,sync-sink |
40 | 39 | ----
|
41 | 40 |
|
42 |
| -Run the following command to start the sink: |
| 41 | +When using the CAM0 port on a Raspberry Pi 5, CM4 or CM5, append `,cam0` to that line without a space. If two cameras are on the same Raspberry Pi you will need two dtoverlay lines, only one of them ending with `,cam0`. |
| 42 | + |
| 43 | +Alternatively, if you wish to swap the cameras' roles at runtime (and they are not both connected to the same Raspberry Pi), omit `,sync-source` or `,sync-sink` above. Instead you can set a module parameter before starting each camera: |
43 | 44 |
|
| 45 | +For the Raspbery Pi with the source camera: |
44 | 46 | [source,console]
|
45 | 47 | ----
|
46 |
| -$ rpicam-vid --frames 300 --qt-preview -o sink.h264 |
| 48 | +$ echo 1 | sudo tee /sys/module/imx477/parameters/trigger_mode |
47 | 49 | ----
|
48 | 50 |
|
49 |
| -Run the following command to start the source: |
50 |
| - |
| 51 | +For the Raspberry Pi with the sink camera: |
51 | 52 | [source,console]
|
52 | 53 | ----
|
53 |
| -$ rpicam-vid --frames 300 --qt-preview -o source.h264 |
| 54 | +$ echo 2 | sudo tee /sys/module/imx477/parameters/trigger_mode |
54 | 55 | ----
|
| 56 | +You will need to do this every time the system is booted. |
55 | 57 |
|
56 |
| -Frames should be synchronous. Use `--frames` to ensure the same number of frames are captured, and that the recordings are exactly the same length. |
57 |
| -Running the sink first ensures that no frames are missed. |
58 |
| - |
59 |
| -NOTE: The potential divider is needed to pull up the XVS pin to high whilst the source is in an idle state. This ensures that no frames are created or lost upon startup. The source whilst initialising goes from LOW to HIGH which can trigger a false frame. |
60 |
| - |
61 |
| -=== Use the GS Camera |
| 58 | +==== For the GS Camera |
62 | 59 |
|
63 |
| -NOTE: The Global Shutter (GS) camera can also be operated in a synchronous mode. However, the source camera will record one extra frame. A much better alternative method to ensure that both cameras capture the same amount of frames is to use the xref:camera.adoc#external-trigger-on-the-gs-camera[external trigger method]. |
| 60 | +Edit `/boot/firmware/config.txt`. Change `camera_auto_detect=1` to `camera_auto_detect=0`. |
64 | 61 |
|
65 |
| -To operate as source and sink together, the Global Shutter Cameras also require connection of the XHS (horizontal sync) pins together. However, these do not need connection to a pullup resistor. |
66 |
| - |
67 |
| -The wiring setup is identical to the xref:camera.adoc#using-the-hq-camera[HQ Camera method], except that you will also need to connect the XHS pins together. |
68 |
| - |
69 |
| -Create a potential divider from two 10kΩ resistors to 3.3V and ground (to make 1.65V with an effective source impedance of 5kΩ). This can be connected to either Raspberry Pi. |
70 |
| - |
71 |
| -Solder 2 wires to the XVS test points on each board and connect both of these wires together to the 1.65V potential divider. |
| 62 | +For either a source or a sink, append this line: |
| 63 | +[source] |
| 64 | +---- |
| 65 | +dtoverlay=imx296,always-on |
| 66 | +---- |
| 67 | +When using the CAM0 port on a Raspberry Pi 5, CM4 or CM5, append `,cam0` to that line without a space. If two cameras are on the same Raspberry Pi you will need two dtoverlay lines, only one of them ending with `,cam0`. |
72 | 68 |
|
73 |
| -Solder the GND of each Camera board to each other. Also solder 2 wires to the XHS test points on each board and connect these. No pullup is needed for XHS pin. |
| 69 | +On the GS Camera, the sink role is enabled by the MAS pin and cannot be configured by software ("trigger_mode" and "sync-sink" relate to the xref:camera.adoc#external-trigger-on-the-gs-camera[external trigger method], and should _not_ be set for this method). |
74 | 70 |
|
75 |
| -On the boards that you wish to act as sinks, solder the two halves of the MAS pad together. This tells the sensor to act as a sink, and will wait for a signal to capture a frame. |
| 71 | +=== Libcamera configuration |
76 | 72 |
|
77 |
| -==== Boot up source and sink |
| 73 | +If the cameras are not all started within 1 second, the `rpicam` applications can time out. To prevent this, you must edit a configuration file on any Raspberry Pi(s) with sink cameras. |
78 | 74 |
|
79 |
| -Run the following command to start the sink: |
| 75 | +On Raspberry Pi 5 or CM5: |
| 76 | +[source,console] |
| 77 | +---- |
| 78 | +$ cp /usr/share/libcamera/pipeline/rpi/pisp/example.yaml timeout.yaml |
| 79 | +---- |
80 | 80 |
|
| 81 | +On other Raspberry Pi models: |
81 | 82 | [source,console]
|
82 | 83 | ----
|
83 |
| -$ rpicam-vid --frames 300 -o sync.h264 |
| 84 | +$ cp /usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml timeout.yaml |
84 | 85 | ----
|
85 | 86 |
|
86 |
| -Due to the limitations of the IMX296 sensor, the sink cannot record exactly the same number of frames as the source. **The source records one extra frame before the sink starts recording**. Because of this, you need to specify that the sink records one less frame with the `--frames` option. |
| 87 | +Now edit the copy. In both cases, delete the `#` (comment) from the `"camera_timeout_value_ms":` line, and change the number to `60000` (60 seconds). |
87 | 88 |
|
88 |
| -Wait at least two seconds before you start the source. |
| 89 | +=== Starting the cameras |
89 | 90 |
|
90 |
| -After waiting two seconds, run the following command to start the source: |
| 91 | +Run the following commands to start the sink: |
91 | 92 |
|
92 | 93 | [source,console]
|
93 | 94 | ----
|
94 |
| -$ rpicam-vid --frames 299 -o sync.h264 |
| 95 | +$ export LIBCAMERA_RPI_CONFIG_FILE=timeout.yaml |
| 96 | +$ rpicam-vid --frames 300 --qt-preview -o sink.h264 |
95 | 97 | ----
|
96 | 98 |
|
97 |
| -Because the sink and source record a different number of frames, use `ffmpeg` to resync the videos. By dropping the first frame from the source, we then get two recordings with the same starting point and frame length: |
| 99 | +Wait a few seconds, then run the following command to start the source: |
98 | 100 |
|
99 | 101 | [source,console]
|
100 | 102 | ----
|
101 |
| -$ ffmpeg -i source.h264 -vf select="gte(n\, 1)" source.h264 |
| 103 | +$ rpicam-vid --frames 300 --qt-preview -o source.h264 |
102 | 104 | ----
|
| 105 | +Frames should be synchronised. Use `--frames` to ensure the same number of frames are captured, and that the recordings are exactly the same length. |
| 106 | +Running the sink first ensures that no frames are missed. |
| 107 | + |
| 108 | +NOTE: When using the GS camera in synchronous mode, the sink will not record exactly the same number of frames as the source. **The source records one extra frame before the sink starts recording**. Because of this, you need to specify that the sink records one less frame with the `--frames` option. |
0 commit comments