Author: Will McCoy
I appologize for my deficiency of posts this month. In my experience, the end of October is one of the busiest times of the fall semester, and I was preoccupied with other work. I hope to make up for this with a longer post today; I hope you enjoy.
Embedded cameras typically use MIPI CSI, which physically looks like a ribbon cable connecting the camera to the single board computer. My first exposure to this interface was several years ago, when I got my hands on the Raspberry Pi Compute Module 1. I plugged it into my Raspberry Pi (Model 2 B+ I think), an it worked like a charm. A few years later, I purchased an Arduino MKR Vidor 4000, an Arduino board which also features an Altera Cyclone V FPGA. This board also has a MIPI CSI connector, and an (micro) HDMI output. One of the demo projects for this board involved using a MIPI CSI camera and streaming the output to HDMI. I figured I would give it a shot, so I uploaded the code to my board and plugged in my Raspberry Pi Compute Module 1. I expected this to fail due to camera incompatibility; however, it surprisingly worked, and I saw an image on the monitor. This led me to believe that all MIPI CSI cameras, sort of like USB webcams, were generally compatible with each other, as I had plugged in a random camera and it just worked. What were the odds that I just happened to plug in the exact camera the sample code was designed for?
I specify my history with embedded cameras because I would like to contextualize my error within the scope of my previous experience. Because of this experience, I have gone through this project with the assumption that all MIPI CSI cameras are interoperable. Therefore, I have just been evaluating cameras by their performance specifications, without any consideration as to if they were compatible with the other hardware in the system. Therefore, I was alarmed to find out today that the Jetson Nano only natively supports MIPI CSI cameras based on the IMX219 or IMX477 image sensors; this is because NVIDIA has only officially released drivers for these sensors. Upon discovering this, I was immediately confused, so I looked into why the MKR Vidor camera code worked. Sure enough, the OV5647 image sensor that is in the Raspberry Pi Camera Module 1 just happens to be the exact image sensor required by the MKR Vidor code. What a coincidence! In reality this was probably a deliberate design choice by the Vidor programmers, because they probably assumed the Raspberry Pi Camera Module 1 is the most common MIPI CSI camera for hobbyists, and therefore chose to target it. Nonetheless, this frustrating circumstance has left me misinformed throughout my camera selection process, so its back to the drawing board for now.
With this in mind, there are several directions to go from here. First, I could just accep the IMX219 limitations, and just use the Raspberry Pi Camera Module 2. Unfortunately, this sensor has less resolution than does the IMX708 in the Raspberry Pi Camera Module 3, which is the camera we are currently considering; this translates directly into a shorter vehicle detection range. Another option is to write my own driver for the IMX708 sensor; I’m still a young and ambitions engineer, so I naively am up for the task. On one hand, NVIDIA’s source code for the IMX219 camera sensor is open source, so I wouldn’t have to start from scratch; I anticipate that the protocols for the two image sensors are sufficiently similar that I could just adapt one into the other. On the other hand, perhaps I should be more realistic, as writing Linux kernel drivers is no easy feat, and I am probably overestimating my abilities. The final option I’ve identified is one provided by ArduCam. They have a product, called JetVariety, which uses their custom hardware and driver, to allow pretty much any MIPI CSI image sensor to be used on the Jetson Nano. The only drawback with this is the added cost, which may prove unviable on our limited budget.
My current plan is to revisit the math on the range of the Raspberry Pi Camera Module 2. If it turns out that I can actually achieve a larger range, then we can get away with this camera. If not, I’m very tempted to try to adapt the driver for the Raspberry Pi Camera Module 3. If that also fails, we will just be left with the JetVariety solution, though I’d prefer that be a last resort.
The key takeaway of this experience is to always check your assumptions. I generally believe that “things don’t work,” because they often just don’t. However, I should be more cognisant that coincidences like this can still happen, which can give the illusion of things just working. In the future, I will make an effort to better validate my assumptions.
