Software Control of IR Cut-Filter and Illumination

Published On: March 11, 2022Categories: build guide, Cameras, Raspberry Pi

The Raspberry Pi Foundation has 3 official cameras, but there are a lot of 3rd-party components for sale out there. The official camera boards are the 8MP Raspberry Pi Camera Module 2 (using a Sony IMX219 sensor) and the same thing but NoIR (no IR cut filter for ‘night vision’) and the 12.3MP High Quality Camera.

Most of the aftermarket cameras are based the OmniVision OV5647 5MP sensor used in the first generation of the official cameras, so you won’t have the pixels, but they can be found with lens adapters and other goodies, such as a mechanical IR cut filter.

But, why does this IR filter even matter? Well, it affects the quality of the images from the camera. Without the IR filter in place pictures come out pinkish. To solve this the ‘greyworld’ white balance was created* to help solve that. And it works, kind of.

The image quality is definitely best, during the daytime, with the IR filter in place. Without the filter you could still use the camera for detecting motion and recording events during the daytime, but it is not very photographic. Greyworld only makes it more observable. It is a shame to use such a capable device with such a limited camera.

So, what can you do?

Well, you can buy a 3rd party camera that has a mechanical device that moves/removes the IR filter from in front of the camera sensor. This allows you to use the same camera for day and night use. They also come with an upgraded lens mount, and a variety of lenses can be used. The images above are from a 170° field-of-view fish-eye lens. These camera boards also can supply power to attached illuminators; high power 850nm LEDs for near invisible night-time illumination when the IR cut filter is removed from the lens.

wide angle camera

Here you can see the aftermarket lens assembly, and that red+black wire assembly drives the IR filter. How, though? On the camera board, and on each illuminator, a light sensor is soldered to the board with a small piece of heat-shrink tubing creating a kind-of tunnel to that light will tend to enter the sensor from the front. If this were to be up-and-running holding our finger over the sensor would cause the IR filter to change, and we will hear it ‘click’ out of place, and we would see a difference in the picture from the camera, like shown above. Covering and uncovering the sensor will cause the filter to click back-and-forth.

This is great for improving our image quality and viewing, and can allow us to have good color representation during the day and IR illuminated night-vision at night. The problem with this system is that it is somewhat arbitrary. The camera device is itself selecting whether to engage the filter or not. This means that it could disengage the filter before it is really dark, or visa-versa. I have also discovered that when the light is at just the right level it can cause the sensor/filter/illuminators to flicker. A small variable resistor is on the camera board that allows some control over when the light sensor engages and disengages, but it is still pretty random, and completely out of my control.

And I don’t like that.

So, what can you do?

What I did is cut the light sensors off and use a transistor on a proto-board to control from the Raspberry Pi GPIO. This is the same circuit that I use to control the case fan, duplicated on the proto-board 2 more times to add control for the IR filter and illuminators separately. To make this work I had to do two things: modify the camera and illuminators, and assemble the circuits.

Once the GPIO was connected to a transistor, all that was left is a little code to make things work.

The first place I test is at the command line in Python. Import the gpiozero library, or at least OutputDevice. From the Python shell you can turn an OutputDevice on or off, or toggle the pin which will change the filter on and off. But, when you leave the shell, it probably won’t stay where you left it. And if you write some simple script that _looks_ like it will work at the command line; well, running it like an app is different.

So I figured I need to find some Python script that keeps running and running that I can send my IR filter commands to, and get the filter to stay where I left it.

That is where MQTT comes in.

I have been playing with it for a while now, and although each camera could decide when to turn an IR filter on and off, I could also centralize that and have the command sent out from a command-center.

Or, at least, this makes it easy for me right now.

I found a simple MQTT listener which runs in an infinite loop; a perfect place to keep state on this. Start it up as a systemd service and, voila, I have control over the IR filter, illuminator, or could extend this to any peripheral.

More on escapades with MQTT later.

Thanks for reading!

*At least I remember reading that somewhere. Maybe a release note???

Share This Story!

Subscribe to receive updates when new articles are published

    * Add notice about your Privacy Policy here.