Wednesday, May 7, 2014

Measuring Video Blink Rate with an Arduino

In my previous post, I used blinking videos on my computer to entrain my brain waves.  A key question, though, was whether my computer could play those blinking videos steadily.  If the blinking isn't steady, it won't entrain brainwaves that are easily detected.  So, in this new post, I show how I hacked a photocell and my Arduino to measure the blink rate that my computer is actually producing.  It's a pretty simple (and cheap!) setup and, as you'll see below, its data explains some of the important findings in my EEG data!

Measuring the Blink Rate From the Movies Played Back by my Computer

Using a Photocell:  My approach to measuring the video blink rate is to quickly and continuously measure the light produced by my computer screen.  I chose to use a photocell, mostly because I had one that came with my very first Arduino.  To learn how to use a photocell, I followed the tutorial at Adafruit.  It explains what a photocell is and it explains exactly how to hook it up to an Arduino.  The key is that you connect a photocell and a 10K resistor in series.  Together, they form a voltage divider.  Then, you connect one end to +5V and the other end to ground.  In the middle, at the junction between the photocell and the 10K resistor, you connect that point to the Arduino's analog input pin.  Pretty easy!

Wiring It Up:  To connect all of the bits together, I needed to solder a few things.  First, I gathered my components -- the photocell, some wire, and some shrink tube (to keep the soldered wires from shorting to each other).

The Components: A Super-Cheap Photocell, some Wire,
and some Shrink Tube.  The 10K resistor is not shown.

Then, I soldered the wires to the legs of the photocell and insulated them with the shink tube.  The photo below shows the components after this assembly.  Looks decent enough.

Fully Assembled.  This is the first version that I tried.  Notice that the back
and sides of the photocell are exposed.  This turned out to be bad.

Unfortunately, when I hooked it up to my Arduino, I found that I was not seeing any change in the light level from my computer screen.  After some playing around, I found that the photocell is sensitive to light from the back and sides, in addition to being sensitive to light from the front.  So, as seen in the photo below, I added another layer of shrink tube to block out the light entering from the back and sides.

Modified Assembly.  I added more shrink tube to wrap around the sides
back of the photocell.  You have to keep out that light!

Mounting Everything:  Once I had my photocell on those long(ish) lead wires, I connected it to the Arduino as discussed on the Adafruit site.  I then needed a way to hold the photocell close to the computer screen so that I could measure its blink rate.  As shown in the photo below, I found that my adjustable soldering fixture (sometimes called a "3rd Hand" fixture) works really well.  It works best if you position the photocell to be VERY close to the computer screen.

I held the photocell to the computer screen using a"3rd Hand" soldering fixture.
To record the photocell signal, I used one of the Analog Inputs available on the
Arduino that is the host for m OpenBCI shield.

Position the photocell to be VERY close to the screen.

Arduino Software:  If I'm going to use my Arduino to read the photocell, I need to some software for the Arduino.  My first step was to use the built-in Arduino example called "AnalogInOutSerial".  I then extended this program to report the actual resistance of the photocell under different lighting conditions ("ReadPhotocellResistance").  While either of these programs works fine to read the photocell, neither is clocked to read the values a steady pace.  If the sampling isn't steady, there's no way to know if the video blinking istelf is steady.  To fix this, you need to setup an Arduino timer.  Or, you could...

Integrate with OpenBCI:  The OpenBCI shield generates data packets at a very precise rate (I usually configure mine to sample at 250 Hz).  It could act as the clock to drive the Arduino to sample the photocell steadily.  So, I modified the OpenBCI Arduino sketch to read one of the analog input pins every time that it receives data from the OpenBCI shield.  It then appends this extra data value to the OpenBCI data packet and sends it to the PC.  Finally, I modified my OpenBCI GUI to receive the extra data and to include it in its log file.

Results:  I used this system to record the blinking produced by the blinking movies from my previous post.  Each movie was about 20 seconds long and each movie blinked at a different rate.  The digitized Photocell values are shown in the figure below as raw counts from the Arduino.  Clearly, this graph is a bit too zoomed out to see much of interest (though you can see the non-steady amplitude when at the fastest speed on the right).  We need to zoom in to see more detail...

Sample values recorded from the photocell by the Arduino's analog input pin. I played
my 10 whole-screen-blinking movies.  Each movie is about 20 seconds long.  Each movie
has a different blink rate -- from a 1 Hz white-to-white blink rate up to a 10 Hz w-w rate.

Zooming-In:  Excerpts from three of the movies are shown below.  In these plots, you can see that the light pulses recorded during the  3 Hz and 10 Hz movies look to be steadily paced, whereas the pulses in the 7 Hz movie looks much more irregular.  Based on this qualitative view, I'd say that the irregularity of the 7Hz movie might cause complications when used for EEG experiments.

Zoomed-In waveforms recorded from the photocell during my blinking movies.  Excerpts at three
different blink rates are shown.  The red and blue dots show features that I used to quantify each
movie's blink rate.  Note that the time scale is different for each of the movies so that you always
see 4 periods, despite their increasing speed.

Measuring the Blink Rate:  To better assess the steadiness of each movie, I setup a routine to quantify the blink rate on a blink-by-blink basis.  I did this by, first, computing the mean sensor value for the whole recording.  This is my threshold for deciding whether the screen is "white" or "black".  This threshold value is shown by the horizontal black line in the excerpts above.  Then, I detected when the signal crossed this threshold.  Each threshold crossing is shown as a blue dot in the figures above.  To compute the blink rate, I compute the difference between the dots.  The "white-to-white" blink rate is the difference between the red dots.  Alternatively, the rate at which the screen merely changed (either from white-to-black or black-to-white), I measured the difference between the blue dots.

Blink Rate Throughout the Test:  The plot below shows the results of quantifying the blink rate throughout the test.  In red, the plot shows the white-to-white blink rate.  In blue, I show the blink rate from both transitions.  As expected, the blink rate counting both transitions is twice as fast as the blink rate when counting just from white-to-white.

Blink Rate Measured for my 10 Movies.  The measured blink rate generally follows the expected blink
rate, though the measured blink rate exhibits unsteadiness at the faster speeds. The blink rate when
counting both transitions (whit-to-black and black-to-white) is especially unsteady at the higher speeds.

Unsteadiness:  As can be seen in the plot above, the blink rate is pretty steady for the first four movies (ie, speeds of 1-4 Hz W-W).  For the 5th movie (5 Hz W-W), the plot above starts to look messier, especially the blue line.  This means that the system is not playing back the blinking movie smoothly.  As we get into the faster movies (6-9) Hz, the blue line gets extremely messy.  Clearly, the system is unable to keep a steady pace of white-to-black and black-to-white transitions (the blue line), though the white-to-white period (the red line) isn't too as bad.  Funnily, at 10 Hz, note that the white-to-white blink rate gets very stable again.  It seems that at 10 Hz, the individual movie frames must be well-aligned with the natural update rate of the video system on my computer.

Relationship to EEG Data:  The whole purpose of this investigation was to see if my EEG results from my previous post (copied again below, for convenience) were reflecting properties of my brain, or if they were reflecting artifacts from imperfections in my computer's movie playback.  My main question with my EEG data is why I exhibited no video-entrained EEG signals above 10 Hz.  Well, looking at the graph of the computer's blink rate (above), we see that the video blink rate becomes extremely unstable for any frequency above 10 Hz.  My computer, in other words, was unable to generate steady visual stimulation above 10 Hz.  Without stable stimulation, my brain had nothing to entrain with.  Therefore, these limitations in my video system mean that I cannot declare either way whether my brain can entrain with visual stimuli at speeds greater than 10 Hz.  With a more stable video system, maybe I could entrain with the faster blinks.

EEG data shown in my previous post.  This is the signal recorded from the back of my head (reference
on left ear) when staring at my blinking movies.  The signals marked by the blue arrows seem to indicate
periods when my brain entrained with the video on every transition of white-to-black and black-to-white.
The periods marked by the red arrows seem to indicate periods when my brain entrained on just the
white-to-white blink rate.

Next Steps:  With this system, I have proven that I can assess the steadiness of my video playback system.  Steady playback is critical to inducing visual entrainment of brainwaves.  So, as I move forward with trying to create a BCI based on visual entrainment, I can use this synchronized photocell recording to confirm that the video stimulation is sufficient to (hopefully) induce EEG responses.  Let the development of the visual BCI begin!


  1. Chip, hi.

    I always enjoy reading your posts and the way you carefully investigate each aspect. Uncovering the mysterious interactions(!)

    Perhaps this might interest some: a way to get precise flash rates using LED glasses.

    Scroll down the page there until you reach the pvStim and hemiStim models. The hemiStim model has the unique feature where the left or right visual fields can be independently lit. Thus you would get different signals at left/right occiput.

    I think the pvStim's are wired in the conventional LED glasses style, where they use diagonal pairings of LEDs.

    Of course there are also tutorials on the web, you can make similar glasses yourself.

  2. Hello there!

    How did you the record of the data from photocell? I need to do this to make sure my LED is blinking on a certain frequency with the Arduino. Could you help me please?

    1. How did you record the data and how did see the data after too? thanks!