(Plus a few other bits and bobs.)
This project was not undertaken to find out the physical value of the speed of light, but to test whether such measurements are possible at home with a Raspberry Pi. This kind of thing would normally be attempted in state of the art optics labs, and then probably by inferring the speed from some other characteristic. I went for a simple solution, turn on a light and see how long until a light sensor detects it.
The Pi used was an old Model B. The CPU is clocked at 700MHz, so it's not quick by modern PC standards. The Raspberry Pi 2 and 3 are faster, but I had a spare mark 1 doing nothing. There are plenty of IO pins available to control and sense things. I just needed one output to turn on a light, and one input to detect the light.
I installed Raspbian on the Pi, enabled SSH so I can log in from a laptop and created my personal user account. The first real task for the experiment was to see how well the Pi can measure time. This piece of C code queries the timing system to see what the resolution is.
The answer surprised me. Here's a cut 'n' paste of my console window.
1 nanosecond resolution seemed too good to be true. At 700MHz clock rate, that's faster than the CPU. But I just thought it must be some oddity of the system clocks.
Now I wanted to know if the time delay between outputting a signal on one pin and receiving it on another was detectable. I wrote the following program to test this. The program takes the average of a million readings and waits between each one to allow other threads to act and to allow the IO to settle. I used the WiringPi library to do the IO as I've used it before and know it performs well. After all, I'm going to be measuring the fastest thing there is. The code comments describe what it's doing in more detail.
The result of running that with two 10cm Jumper wires attached to the Pi and joined together with a small wire to leave effectively no gap was as follows.
The result proves a few things. Firstly, the Pi was lying about the 1 nanosecond timer, it has three zeroes at the end of the total nanoseconds value. This indicates that the timer is really only measuring to a resolution of 1 microsecond, or 1000 nanoseconds. I thought 1 nanosecond was a bit optimistic. Secondly, it proved that the time taken for the pins to react was longer than the time the code took to measure it, otherwise all readings would be zero. And thirdly, it proved that the experiment may just work.
The next thing was to replace the join in the jumpers with 1m of wire and see if I can detect a difference. Here's the result from running that.
Something was wrong. The signal went down the long wire FASTER than the short one. With the complete lack of regard for signal condition, I believe that the wire had all sorts of ringing, resonance and other electronic nastiness going on, so I re-ran the experiments ten times the sleep, but only 100000 iterations to keep the speed up. This time the short wire gave this.
And the long wire gave this.
Success. The signal took longer to travel down a longer wire. The readings were also pretty consistent, so the lower sample count shouldn't be a problem.
Not it's time to design the light and receiver, then go shopping for parts. I don't want to have to move the Pi, the light, or the sensor as moving them would mean long wires could cause electrical effects to change the results. The simple solution was to bounce the light of a mirror and vary the length of the light path by moving the mirror. One potential problem is that the brightness of the light would decrease as the distance increases. To avoid this I needed a light that sends out a thin column, all in the same direction rather than have it fan out all around. The obvious choice is a laser, which also has the advantage of sounding really cool. The receiver I chose was a phototransistor as they are fast and tend to be optimized for switching on and off, rather than measuring varying light levels.
I found both of these components on Ebay for 99 pence each including delivery from China. The laser was describes as "650nm 5V red laser diode laser module diode modules laser dot diode module SP" The specification was given as follows.
Spot mode: dot facula, continuous output
Laser wavelength: 650nm (Red)
Copperhead Diameter is 6mm
Power lead length: 75 mm
Shell Material: Brass
Package included: 1 x Laser Dot
Working life: more than 2000 hours
Light power: Less than 5mW
Supply Voltage: 5V DC
Operating Current: Less than 40mA
Operating temperature: -36 ~ 65
The colour being visible, and the power requirements are all that really concerned me. I would be able to see this laser spot and could drive it from the Pi 5V pin.
The Phototransistor was described as "2Pcs 3Du5c Silicon Phototransistor Transistor/2-Feet Metal Package New Ic Q" which left me wondering what Q means and why both e-bay items had weird endings. I actually got 2 because I have another project planned, but together they cost me less than a pound.
NPN Silicon Phototransistor;Model : 3DU5C
Working Voltage(Max.) : 10V;
Reverse Breakdown Voltage : 15V;
Dark Current : 0.3uA
Photocurrent : 0.5-1mA;
Power Consumption : 30mW;
Peak Wavelength : 880nM
Body Size : 7 x 5mm/ 0.28" x 0.2"(L*D);
Total Length : 28mm/ 1.1";
External Material : Metal
Weight : 3g;
Again, most of the spec is unimportant, but the Pi uses 3.3V, so the 10V working voltage is plenty the peak wavelength isn;t perfectly matched to the laser, but it's good enough. I already had the rest of the materials so the total spent on the project was £1.98. Not bad for to measure the fastest speed there is. The full parts list is.
The circuitry is divided into two sections, laser and detector. The detector circuit uses the 22k resistor to pull a GPIO input up to 3.3v, then the phototransistor pulls it down to ground when it detects the laser light. The laser has it's positive terminal connected to +5V from the Pi and is controlled by the 2N3906 transistor between the ground and the negative laser terminal. The base of the transistor is fed via the 470 Ohm resistor from a GPIO output pin. The transistor switch is needed to make sure the laser has enough current to operate while no damaging the Pi.
The software needs changing slightly for this as the light detector gives a zero when light is present. All places where the input is checked need to be swapped from 1 to 0 or visa-versa.
For the first run of the experiment a small shaving mirror was used, but aligning this proved next to impossible over the longer distances. A better solution is shown here.
The picture on the left shows the new mirror setup in full. It consists of two L shaped pieces of wood, one screwed to a camera tripod, the other. The corner and ends of the back piece have a nut glued in place and a coach bolt passing through from the back to the front so it can be freely turned. The front piece of wood rests on these three bolts and is held in place with elastic bands. So if the bolt at the top of the L is turned, it pushes the front piece of wood at the top and silts the mirror slightly downwards. Left and right adjustment is made with the coach bolt at the end of the horizontal part of the L shape. The horizontal adjuster is shown in the picture on the right. The actual mirror is a platter from a hard disk drive. These are very shiny and very accurately made to be very flat. Exactly what is needed for the laser mirror.
The electronics parts were placed on a raised platform at one end of the patio. An ethernet cable from the Pi was passed through the window to the network switch, which was luckily nearby. The laser was switched on and carefully levelled so vertical adjustment of the mirror wouldn't been needed very much. The tripod with the mirror was placed so two feet were aligned to the edge of the paving slab facing the laser as shown below.
Because I had to align the laser from up to 6m away, I had to modify the software to give quicker feedback. The delay was set to 1ms and the loop count was set to 1000, this gave me a reading approximately once per second. The accuracy suffered, but many readings can be averaged to compensate there.
The experiment had to be performed outside as the wooden floor of the house would flex slightly when anyone moved. This altered the mirror alignment. Outside is concrete paving slabs which move very little. I had assumed they wouldn't move at all, but I found if I stood on the same slab as the tripod and mirror, it would move when I stepped off. The experiment was performed at night with no house lights on. I live in the city, so it wasn't completely dark, but as close as I can manage. The method involved placing the tripod and mirror as shown above, aligning the beam by adjusting the coach bolts, then taking a few readings. The laptop was positioned along side the tripod and mirror so it's screen light would be facing away from the sensor. After I had enough data, I moved to the next slab and repeated the procedure.
Over on the right is a table of the raw data, but it looks more interesting plotted on a graph. I used Libre Office Calc for this. The best fit straight line was calculated with the trend line tool. Ideally all points would lie right on that line, but in reality they never do in experiments.
The number 3.6882167654 is the slope of the graph. In this case it tells us the speed of light in ns per paving slab.
The size of each slab is 600mm, but the light goes both ways over each one so each slab adds 1.2m to the path of the light. Now we know the speed is 3.6882167654 ns per 1.2m. Speed is described as distance divided by time (for instance miles per hour) so we divide the distance by the time as follows.
1.2 / 3.6882167654 = 0.3253604862 m/ns.
Multiply by 1000000000 to convert from m/ns to m/s as this is the usual unit.
0.3253604862 * 1000000000 = 325360486.2 m/s
The speed of light measured with a Raspberry Pi is 325360486.2 m/sGoogle say the speed of light is 299792458 m/s
My result was only 8.5% different from the recognised value. Not too bad for a total expendature of under £2.