Polarization Analyzer

With the help of two summer students (Jorge Ferreras and Thomas Bishop) and my lab mate (Matt Jones) we put together a polarization analyzer to help us set up polarization maintaining optical fibers. By having a real time feedback of what is the polarization coming out the fibre we can easily adjust the input polarisation so that the output is as stable as possible, thus, rendering a 20 minute chore into a 2 minute dance.

In the lab we only use very specific wavelengths of light so this polarimeter is only designed to work for one wavelength. The light goes into a motorized rotating waveplate, then passes through a linear polarizer and finally is measured with a photodiode.

Now, depending on the incoming polarization, the photodiode will detect different kinds of signals.
Modulated intensity signals

The form of these signals is given by

I(\theta) = \tfrac{1}{2}\left[A-B\sin 2\theta+C\cos 4\theta + D \sin 4 \theta\right],

where I(\theta) is the measured intensity as a function of the waveplate angle. The A,B,C,D coefficients are related to the Stokes parameters by
S0 = A-C
S1 = 2C
S2 = 2D
S3 = B

Once we capture an intensity reading I(\theta) after a revolution of the waveplate, we can extract the A,B,C,D coefficients using
A = \frac{1}{\pi}\int_0^{2\pi}I(\theta)\,d\theta
B = \frac{2}{\pi}\int_0^{2\pi}I(\theta)\sin 2\theta \,d\theta
C = \frac{2}{\pi}\int_0^{2\pi}I(\theta)\cos 4\theta \,d\theta
D = \frac{2}{\pi}\int_0^{2\pi}I(\theta)\sin 4\theta \,d\theta


The photodiode signal and rotation of the waveplate are measured using an Arduino. A python application was developed using pygame to display the result. The communication and plotting is discussed in detail on a previous post.

In our software we display the photodiode signal on the left so we can adjust the intensity of the incoming light such that the photodiode receives enough light but it’s not saturated. The measured polarization is displayed on the right as a red dot in the PoincarĂ© sphere. The blue dots on the sphere represent previous polarization measurements so we can observe the time evolution of the polarisation.


The drawing of the sphere is based on Peter Collingridge’s tutorial here.

All the code can be downloaded from github.




The design of the piece contains two main holes for allocating the ball bearing and the motor. Right below the ball bearing there is a small place to fix the photodetector used to count the turns of the waveplate. There is also a hole in the side just to pass the cables from one side to the other.

It would be a good idea to separate a little bit the two main holes from each other when manufacturing the metal piece to help the gears to work better.

The gear in the parts list is transparent for the IR light, it needs to be covered with an IR-opaque material only leaving the reference hole clear.

Base plate to hold motor, gears and photodiodes in place.

Base plate to hold motor, gears and photodiodes in place.

Mechanical drawing for base plate.

Mechanical drawing for base plate.

The built result is shown in these photographs:

frontsvg back


Our main reference was Sebastian Arnoldt’s Bachelor thesis.

Fast plotting of arduino data in python

For a long time I’ve been trying to plot serial data that comes from a USB device such as an arduino but I could never get to work as fast as I wanted. All of my previous attempts where based in matplotlib but this approach resulted to slow. I just couldn’t update the plot quick enough. By using pygame to take care of the plotting I can get a very responsive plot.

In this post I will show you how to plot the voltage measured from an analog input of the arduino and thus, make a poor man’s oscilloscope with python.

Sending data to the computer: arduino part

The arduino analog-to-digital converter has a 10 bit resolution which means we need at least two bytes to send each value. If we call our 10-bit variable a, then the bits of a are:

bits of a
a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
most significat least significant

To send a through serial protocol we put a9-a5 in one byte and a4-a0 in another and we also pad the bytes with different values so we can distinguish the first from the second byte. If we call b and c the first and second bytes respectively, the bit structure they have is:

bits of b
1 1 1 a9 a8 a7 a6 a5
bits of c
0 1 1 a4 a3 a2 a1 a0

In this way, legitimate values of b are between 224 and 255 and for c they are between 96 and 127, and this way, when we receive a byte we can tell whether is the first or second.

The arduino code to do this is

PC software

On the side of the PC the client software runs two separate threads. One is in charge of continuously reading data from the serial port and the other one updates the plot. The software is made such that this two tasks can be carried out asynchronously.

Communications Thread

This thread reads the serial data using pySerial and joins the two bytes back together to get the original number.

Plotting Thread

The action happens in the pygame main loop:



The full code can be downloaded here. With this setup I was able to get a sampling rate of about 6900 samples per second. In my laptop I get a framerate of about 300 fps and in an old computer I got about 30fps.

Some more fancy oscilloscope features like triggering should be straightforward to implement after this.


The arduino code is based on the one from lxardoscope.