Electrooculograph
From Curuxa Community
| Application: Electrooculograph | |
|---|---|
| Type | Electronics, Medical instruments |
| Author | Adrián Bulnes, aka Urriellu |
| Status | Finished (proof of concept) |
| Date | January, 2010 |
An electrooculograph (EOG) is a device that measures the voltage between two electrodes placed on the face of a subject so it can detect eye movement.
This page describes a simple version of an EOG which can be used to detect whether the subject is looking to the left or to the right. More complex applications can be built by using more than two electrodes, improving the calibration...
Contents |
Description
The basic operation of this EOG is very simple:
Two electrodes are placed on each side of the face, very close to the subject eyes, that will measure a voltage differential between them at all times. The contraction and relaxation of the eye muscles change that voltage, so we can detect eye movement by measuring the change in voltage.
When the subject is looking to the right, the electrodes will measure, for example, 1.94mV, but when he's looking to the left we could get 1.82mV. Therefore, looking to one side or the other side will make the voltage change by around 120µV.
It's important to note that these voltages are examples. The voltage differential depends on multiple factors, not just muscle contractions: heartbeat rate, sweating, breathing, amount of light, electrodes movement and many more factors would change the measured voltage. Due to this, the measured voltage is very unstable and changes a lot over time, specially during the first minutes after sticking the electrodes to the face.
Hardware
This device has been built using one Main Board, a couple of standard Modules, and the EOG Module which has been designed and built specifically for this project using Curuxa standards, but it's not an official Module.
Used Main Boards and Modules
Main Board: MBP18
|
| 1x SISW-SPST
Simple push button or on-off switch. Two positions. Microcontroller can receive either 0 or 1. The EOG will enter calibration mode while it's pressed. Connect it to RB3 (pin 9). |
| 2x LTIND-A
Indicator LED. They will show in which direction the subject is looking to. Connect one LTIND-A to RA2 (pin 1), and the other one to RA3 (pin 2). |
| 1x AO-SPK
Simple, low-power speaker. It will play a diferent sound depending on which direction the subject is looking to. Connect it to RA1 (pin 18). |
| 1x InstruAmp
Amplifies a voltage differential. Amplifies the voltage accross the face. Connect it to AN0 (pin 17). |
You will also need:
- Lots of sticky electrodes for medical purposes (they can't be reused). I used big electrodes for electrocardiograms, but smaller ones would probably be a better choice.
- 2x Clips for connecting the amplifier module to the electrodes. You can build your own using two straight female headers, two long wires, two crocodile/test clips and some heat shrink tubing
The electrodes are connected to the AD620 inputs (see InstruAmp module), so the voltage across the subject's face is amplified by aproximately 1000 times (51Ω resistor). We get a voltage of around 1-3 volts at the amplifier's output. This voltage is fed into the microcontroller analog-to-digital converter through pin 17 (AN0). The microcontroller process this signal and turns on or off each LED (SISW-SPST) and the speaker (http://curuxa.org/en/AO-SPK AO-SPK]) depending on the received voltage.
Note: The 51Ω resistor provides an aproximate gain of 1000. Thanks to the software calibration and the wide range of supported input voltages, this resistor can be changed.
How the program works
The inputs, outputs, processor frequency, analog-to-digital converter (ADC), variables and interrupts are first setup. After that, the program waits doing nothing until the button is pressed, so the program begins. We do this so the circuit won't begin beeping and flashing before being calibrated.
The main program consists in an infinite loop and an interrupt. In the main loop, if the button is pressed the program will enter calibration mode. The subject must look to the front, and the ADC will make lots of measurements, calculating the aproximate voltage at which the electrodes are set when the eyes are centered.
After calibration, we take 200 measurements and calculate their average value. If the resulting average voltage is greater than the center voltage, we can say the subject is looking to the right. If it's lower than the center value, the subject is looking to the left. Both LEDs and the internal timer are set depending on the direction he is looking to.
All measurements must be done multiple times and we have to calculate some kind of average value because they are very noisy, so we can't simply use the last measured voltage.
While the main loop is running, every few milliseconds an interrupt will occur. When the interrupt function is called, if it's not in calibration mode the digital output where the speaker is plugged to will change its value, thus generating a square wave which will be transformed into sound. The frequency of this sound depends on the timer setup, which was set in the main loop after every iteration of 200 measurements.
Pictures
Video
Source Code
/*================================================================== * Electrooculograph application. Detect in which direction a person * is looking to and show it using two LEDs and a speaker. * * Connections: * EOG module: RA0/AN0 (pin 17) * SISW-SPST: RB3 (pin 9) * AO-SPK: RA1 (pin 18) * One LTIND-A: RA2 (pin 1) * Another LTIND-A: RA3 (pin 2) * * Each LED will light up and a different sound will be generated * based on which direction the subject is looking to. * * While the button is pressed, both LEDs will be off, the speaker * will be muted, and the EOG will enter calibration-mode. * * http://curuxa.org * *=================================================================*/ #include <MBP18.h> #define OSC_8MHz #include <Delays.h> ConfigBits1(_CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO); #define Button RB3 #define Pressed 0 #define Released 1 #define LED_R RA2 #define LED_L RA3 #define LedON 1 #define LedOFF 0 #define SquareOut RA1 bool calibrating; Interrupt { if(!calibrating) SquareOut=!SquareOut; TMR0IF=0; } //Looking to the right void LookR(){ LED_R=LedON; LED_L=LedOFF; //prescaler=16, 488Hz PS2=0; PS1=1; PS0=1; } //Looking to the left void LookL(){ LED_R=LedOFF; LED_L=LedON; //prescaler=32, 244Hz PS2=1; PS1=0; PS0=0; } void main() { //setup unsigned int8 i; float center=0; float val=0; calibrating=true; SetIntosc8MHz(); EnableAN0(); TRISA1=DigitalOutput; TRISA2=DigitalOutput; TRISA3=DigitalOutput; TRISB3=DigitalInput; PSA=0; T0CS=0; TMR0IF=0; GIE=1; TMR0IE=1; SquareOut=0; //wait for calibration while(Button==Released) { LED_R=LedON; LED_L=LedON; } while(1) { //calibrate center voltage while button is pressed while(Button==Pressed) { calibrating=true; center=(center*0.99+AdcMeasure()*0.01); } calibrating=false; //average of 200 measurements val=0; for(i=0; i<200; i++) { val+=AdcMeasure(); } val/=200; if(val>center) LookR(); else LookL(); } }
