Raspberry Pi based home made light meter for analogue camera

As soon as I bought my first medium format camera, Yashica MAT 124G I realized that there will have a problem with exposure meter. First of all, camera was released in 1970, so the light meter is not very accurate. Secondly, it uses mercury 1.35V batteries which are no longer available and only expensive and fast running out zinc-air batteries can be purchased. The last but not least, light meter is not backlit, thus it is almost impossible to guess the proper time and exposure settings in the dark environment. All this reasons convinced me to purchase an alternative light meter which would also calculate the exposure time and aperture number. However, besides commercially available light meters, which are rather expensive (>200$) there was nothing what would fill in the gap. 

Short research on popular shopping websites gave me an alternative solution – why not to use Raspberry with light intensity sensor, couple this with a display and wire it up. The problem was, that my programming skills are rather basic and I also had no idea about photometry. But what is life without trying 😉 The Internet is the biggest invention indeed, and everything can be found there. After short research (this time the proper one) I have learned some things which I will try to explain here. 

Sensor which I bought was GY-30 light intensity sensor for ~3$. It is connected through I2C bus to controller, which in this case is Raspberry Pi Zero W. There is publicly available python script which enables to measure the light intensity in lux. According to Wikipedia lux is  an SI derived unit of illuminance and luminous emittance, measuring luminous flux per unit area, which means that it is amount of light per area. If the area is a camera sensor and we would sum the light over time (exposure time) we will get a picture. However, lux itself is not telling anything about the exposure (EV) which is required to calculate the ratio of exposure time and aperture. The dependency of lux and exposure (EV) is described with following equation:

(eq. 1)     lux = 2^{EV}\cdot2.5

This tell us that exposure is in the exponent – which basically means  that every double intensity of the light would change the exposure only by 1. Plotting this dependency we would get:

Code to generate the graph:

This plot also shows nicely that change of light intensity in lux is drastic (over 10k!), when exposure changes only slightly (from ~ -8 to 12). Obtained exposure can be already used for time and aperture calculations. There is only one variable missing: ISO – the sensitivity of the photosensitive element (film, CCD or CMOS matrix). EV is usually calculated for the default ISO value of 100.  Exposure at various ISO can be calculated from the following equation:

(eq. 2)     EV_{ISO} = EV_{100} + log2(\frac{ISO}{100})

This means, that change of the ISO by one stop (from 100 to 200 for example) would increase the exposure measured at ISO 100 by 1 EV, for the visualization check the plot below.


Now, having the connection between the signal from sensor and exposure, as well as exposure dependence on ISO we can go further. It is not so obvious that for single EV we can describe multiple camera settings. This is because the dependence of N (aperture number) and t (exposure time) is given as follows:

(eq. 3)   EV = log2(\frac{N^{2}}{t})

(eq. 4)    \frac{N^{2}}{t}} = 2^{EV}}

This means that as long as ratio \frac{N^{2}}{t}} is constant, the exposure will stay the same. This dependency can be very nicely shown for most common apertures numbers and times as a 2D matrix:

When all equations are already here, we can relate sensor readout in lux with \frac{N^{2}}{t}} ratio. To do so, we couple equation 1, 2 and 4:

(eq. 5)   lux = 2^{EV}\cdot} 2^{log2(\frac{ISO}{100})} \cdot 2.5 \leftrightarrow lux = 2^{EV}\cdot} \frac{ISO}{100} \cdot 2.5

(eq. 6)   lux = 2^{log2(\frac{N^^{2}}{t})}\cdot} \frac{ISO}{100} \cdot 2.5 \leftrightarrow lux = \frac{N^^{2}}{t}\cdot} \frac{ISO}{100} \cdot 2.5

(eq. 7)   \frac{N^^{2}}{t} = \frac{lux }{\frac{ISO}{100} \cdot 2.5}

to calculate aperture with given time: (eq. 8)    t = \frac{N^{2} \cdot \frac{ISO}{100}}{lux}} \cdot 2.5

to calculate time with given aperture: (eq. 9)   N = \sqrt{\frac{t\cdot lux}{\frac{ISO}{100} \cdot 2.5}

Because old cameras usually have fixed available exposure times and f stops, calculations are much easier. For my light meter I have chosen to calculate exposure time for fixed f stops: 1.4, 2, 2.8 , 4, 5.6, 8, 11, 16. The dependence of time and f stops can be checked at the graphs below.



Having formula linking readout from Raspberry sensor and EV, I could put it all together. I used GY-30 light sensor python script and modified it to show exposure times for given f stops. Original script can be downloaded from here: www.raspberrypi-spy.co.uk/.

The simple readout from the sensor looks like this:

It looks like everything is working! The readout contains the light intensity in lux, EV value and also the ISO value for which it was calculated. Below you can see exposure times for given f stops. So what next? The problem with current script needs to be run from bash, and because Raspberry Pi Zero doesn’t have any input devices (mouse and keyboard), other computer or smartphone has to be involved to run the script and show measured values over ssh connection. Fortunately, there are small OLED displays compatible with Raspberry. Official ones from Adafruit are quite pricey (~19$) but there also available cheap Chinese copies which work with the same python libraries. I bought SSD1306 0.96″ OLED display 128×64 px for ~3$. To install the Adafruit library you should follow steps described on official Adafruit website: https://learn.adafruit.com/

This display renders desired content but before the next one is loaded it has to be cleared with the black rectangle. This makes things slightly more complicated but with the proper understanding it is easy to solve. I joined my previous script for the light metering with Adafruit’s SSD1306 example script for Raspberry Pi usage statistics. Because the display area is very limited I had to reduce number of information displayed on the screen. I have chosen only 4 f stops: f/1.4, 2.0, 5.6, and 11 with refreshing rate 1 s. This is how the final code looks like:

And the sample readout from the OLED display: 

I also changed the font to Minecraftia, because it uses much less space on the display. Unfortunately, when I was mounting the display to self-made holder it broke and first two rows are now showing all pixels. The prototype of the “case” for 3D printing can be downloaded from mine Thingverse profile: Light meter case prototype on Thingverse.

The only thing what still needs to be done is active change of ISO. Right now, ISO can be changed in the script by inserting the value to function measure (ISO). The perfect solution would be to have a knob which would change ISO value in the real time. The script should also auto-start with Raspberry and this can be easily done with crontab job:


With those easy steps I showed you that it is possible to build a light meter at almost marginal costs (Raspberry Pi Zero ~12$ + GY-30 ~3$ + OLED ~3$ = 20$). Of course professional ones offer much better measuring range, more features and also different working modes but the idea of the project was to build something simple which would measure exposure in most standard conditions.


error: Nope.