Log === 2011-11-26 we started designing the board. Design ideas included: * focus on through-hole components with adequate space between components to make it easier to fabricate for those without SMT experience * start with an off-the-shelf arduino for the controller logic to to simplify design/fabrication * use an off-board level-shifter to simplify design/fabrication * reducing our board needs to little more than a break-out board for the ads1298 * used unipolar (0 to 5V) analog supply rather than bipolar (-2.5V to 2.5V) to simplify design/fabrication * choose sintered silver electrodes and shielded cables to reduce chances that poor hardware choices would cause problems * choose ADS1298 as an existed integrated solution to reduce chances that poor hardware choices would cause problems * decoupling capacitors were placed as close as possible to the chip, with smaller capacitors places closer than larger when needed to reduce inductance of the traces connecting to the chip. * the two wires in an analog differential signal were routed as closely together as possible to reduce asymmetrical noise * each pair of signal wires were placed as far apart as feasible to reduce crosstalk between channels * analog signals were separated from digital signals to reduce crosstalk large ground and power planes were used to reduce ground/power inductance and provide some shielding 2012-01-09 Design completed and sent to Gold Phoenix PCB for fabrication http://www.goldphoenixpcb.com/ 2012-02-19 Transitioned from Arduino IDE to Makefile based build because authors were more comfortable with command line tools 2012-03-04 Success reading data (test signals) from ADS1298. Test signals created by setting INT_TEST bit of CONFIG2 register and the mux bits of each of the CHxSET registers to 101. 2012-03-28 Started STM32F407 port as a potential long-term platform capable of on-board signal processing and to replicate results on a different platform to verify that the Arduino was not a source of sampling problems. 2012-05-12 First electroencephalogram (EEG) samples and Fourier transforms. Tested beta wave activity with eyes open and eyes closed. 2012-05-19 Noted that electro-occulogram (EOG) and electro-myogram (EMG) are larger in magnitude than the EEG signals. 2012-05-26 Created a window showing cursor location that could be controlled. Noticed gradual drift in signal over time, so used difference from moving average as a signal. 2012-06-16 To get two independent channels for X and Y movement, we considered using the same frequency band in two different pairs of electrodes, using the same frequency band with two pairs with one shared electrode, and using a single pair of electrodes with two different frequency bands. When choosing frequency bands, we tried to choose frequencies that were separated in frequency space, not multiples of each other, and showed resting activity. On the basis of this we choose a band around 11 Hz (alpha) and 23 Hz (beta). Set up infinite impulse response (IIR) filters for the two frequency bands. Used scipy signal design routines to generate coefficient. 2012-06-23 More careful choice of filters. Looked at Elliptical and Butterworth filters, choose filter by inspecting graphs. 2012-06-? Switched from F0 electrode as ground to sitting on a penny/5 euro cent as ground. 2012-07-07 Discovered error in datasheet for STM32F4Discovery board - docs say PE2 for the chip select of LIS302, but should be PE3; the schematic is correct. 2012-08-04 Discovered that crosstalk between SPI clock and signal wires was corrupting our communications with the ADS1298; tried adding resistors to signal lines, moving signals, and shielding to reduce crosstalk, with some success. 2012-08-11 Returned focus to the Arduino; STM32F4 was working, but temperamental due to crosstalk. Changed ardunio SPI clock to 2 MHz instead of 4 MHz for clearer communication. 2012-09-15 Increased pass-band width and decreased stop band to reduce latency below 1/2 second. 2012-09-22 Added color to cursor to show velocity, and added dead-zone to reduce unwanted movements. 2012-11-08 To verify that our perception of control was grounded in reality, we designed an obstacle course, scoring system, and bootstrapped significance testing. 2012-12-01 Created a baseline frequency as an alternative to a running average. 2012-12-08 Created log file, filling in previous history based on git log and shared memory. 2012-12-15 used two sets of signal inputs connected to KMS. Initially: * INP1 located approximately at location F7 * INP2 located approximately at location F8 * INN1 and INN2 shared connector located at "G" or "Fp" * GROUND was wired to a penny being sat upon. Looked at raw amplitude, however the 60Hz was dominant. Next, we added a broad lowpass filter for signals less than 30Hz. This resulted in an obvious EKG pattern. Next, we moved the penny from GROUND to RLDOUT. Eye movement was very obvious, as was teeth clenching. Moved electrodes: * INP1 moved to approximately at location FT7 * INP2 moved to approximately at location FT8 This did not eliminate nor greatly reduce the eye movement effect. Next, changed filter to 15-35 bandpass to remove EOG. EOG effect now no longer obvious. Ran trial with: * Vertical Sensitivity of 0.05 * Horizontal Sensitivity of 0.10 * Horizontal and Vertical Baselines of 0.00005 Trial scored a mean distance of 44! 2012-12-22 Practiced a bit with EMG based control, started rebuilding and diagnosing/repairing board after move. Combinations tried: Target Common IN1P IN2P --------------------------------------------- Temporalis F0 FT7 FT8 Frontalis F0 Fp1 Fp2 Orbicularis oculi F0 2 to 3 o' clock (lateral) margin of orbit of skull Board diagnosis notes: Unable to get signals from board (i.e. all 0s or 1s for a given sample with strange alternation between samples) Wiggling the south header changed the signal (producing some samples which were valid); we suspect that this header needs resoldering. 2013-01-12 Found and fixed problem with nl board. (CS was mistakenly jumped to HIGH) Tried changing SPI.setClockDivider(SPI_CLOCK_DIV8) to DIV4 and DIV2. Both worked for US board connected through the digital isolator however, with the NL board, connected through simple level-shifters, the "magic" was consistently a "4" rather than a "C", so we left it at DIV8. 2013-01-19 Tried another trial of EMG control US board: * RLDOUT was wired to a penny * INP1 approximately at location FT7 * INP2 approximately at location FT8 * INN1 and INN2 shared connector located at "G" or "Fp" * ./broad-wired.sh * Horizontal sensitivity: 0.1 * Vertical sensitivity to 0.25 * Baseline: Manual * Vert baseline: 0.00005 * Horz baseline: 0.00005 results: * 49 pixels Not usable results with NL board. To verify that the level-shifter was not the root cause, the US setup was changed from using the digital isolator to the level-shifter. US Board with level-shifter and SPI_CLOCK_DIV16 gave consistently good magic, however the resuts of two trials were 75 and 62 pixels. We concluded that using the level-shifter is fine and thus not the core problem with NL board control. 2013-02-02 * Try porting to Arduino Due. -- in progress Connected ADS1298 breakout board to Adruino Due (both with digital isolator and directly) with some success. * Data was collected via the programming port. * The DUE requires using the SPI pins, rather than pins 50,51,52. * The baud rate had to be dropped to 115200 otherwise we just saw all FF from the board. * We still saw approximately one frame per second which had an unusual value in the first 24 bytes. * We were not able to communicate with the DUE via the SerialUSB port. In order to get the project to build with the Arduino IDE, we had to remove dashes from the source file names. Replacing dashes with underscores worked. 2013-02-16 control mouse with Arduino Due. * still saw bad magic from time-to-time * still saw some data with big spikes * still saw unusual values in first 24 bits even with good magic * we suspect spikes are result of data corruption * after filtering bad-magic at on the Arduino, we no longer saw bad magic at the desktop computer, thus the data does not seem to get corrupted between the arduino and the computer. * control with Due seemed not as good as with the Mega. 2013-03-02 tested sense of instantaneous response with battery Connected the ADS1298 breakout board to Arduino Due Connected a battery ground to RLDOUT and IN1N Connected IN1P via a resistor and a jumper to battery Observed "seemingly instantaneous" cursor jumps when changed whether jumpers connected to battery 2013-05-05 Continued work on Rev1 schematic An open question is how to drive the clock of the ADS129x from the SAM3X chip. The SAM3X presumably provides 84MHz and ways to divide that. The ADS129x needs 2MHz. We should be able to use the Timer Counters, but we want to make sure that we do not use counters which would conflict with the Arduino libraries. 2013-05-12 Incorporate suggestions from Chris Rorden. Also, test the Adruino Due with powering down unused channels on the ADS1298. Arduino software on the (ustable) 1.5 branch was broken: showing drawing errors which made the tool extremely difficult to use, and it seemed very flaky when uploading code to the Arduino. We worked around this by using commit 8eadd48 which was from about a month prior. As we do not have a commandline build process yet for the Due, we also ran into the existing issue where dashes in names must be replaced by underscores, and the project layout requires the main firmware file to be named the same as the directory and have the ".ino" extension instead of ".cpp". For the Due, the "SPI.setClockDivider" needs to be changed from the SPI_CLOCK_DIV8 to a two argument pin number and 42 to get a 2MHz clock. We used pin number 14. Also, we had problems with the baudrate of 230400; these problems went away when using 115200. 2013-05-18 rev1 schematic essential connections complete We are not 100% certain that we will be able to drive the ADS 2MHz clock from the SAM3X without conflicting with the Arduino libraries. In the SAM3X "Series Complete" pdf, section 37.6.11.2, there is an explanation of how the timer-counter peripheral can be used to generate a square wave of a given frequency. By setting the counter clock to the master clock (84 MHz) divided by 2, and then setting the timer register C to reset the timer every 21 clocks, we can derive our 2 MHz clock. We can then use either timer register A or B to toggle one of the pins approximately half-way through the cycle (e.g. switch to high after 10 cycles). Our choice of output pins from the timers are limited, however, to those listed in section 37.5.1. Timer-counter 1 does not have any output pins available on the 144 pin package we are using; thus we are limited to timer-counter 0 or 2. We chose TC0 signal TIOA1 somewhat arbitrarily, as it was close to some of the other signal lines to the ADS129x. It was labeled as AD7 in the arduino schematic, which we do not think we will need for other purposes. 2013-05-25 elected to create a separate schematic and board for EEG connectors. Decided to have the BIASOUT vs. VIRTGND selected in software to avoid need for more physical space and to consistently record settings with data. This would be doable with a physical switch, but no real need to change this mid-operation. Page 48 of the ADS1299 datasheet shows that we can use switching internal to the ADS for driving a VIRTGND. Added LEDs to daughter board controlled by four 74HC595 chips. At 560 Ohms, we probably do not want to light up all of the LEDs at once, because that will draw a lot of current. We will only light either a yellow or a green per wire, depending on whether the wire is intended for use and disconnected (yellow) or connected (green) ... channels which are set to SHORTED will not have either LED lit. 2013-10-26 looked at options for antialiasing filters. The ADS1298 has a filter with a frequency corner of: 1/(2 * pi * sqrt(22100Ω * 47pf * 10000Ω * 47pf)) = 227785.5 And noise of: sqrt( 4 * (1.38 * 10^-23)J/K * 290K * 2 * (10000Ω + 22100Ω) ) * sqrt(131Hz) = 367nV RMS The ADS1298 datasheet lists the noise of the chip at 500nV, thus 367nV noise from the filter, is less that the noise of the chip, and result in a combined noise of about 620nV. The ADS1299 example filter has a frequency corner of: 1/(2 * 3.14159 * 4990 * 4.7*10^-9) = 6786 and noise of: sqrt( 4 * 1.38 * 10^-23 * 290 * 2 * 4990 ) * sqrt(131) = 144nV The ADS129 datasheet lists the noise of the chip at only 200nV We are considering setting one pair of inputs to have a layout like: 1/(2 * pi * sqrt(2610 * 0.00000000027 * 2610 * 0.00000000027)) = 225847.8 And a noise of: sqrt( 4 * 1.38 * 10^-23 * 290 * 2 * (2610 + 2610) ) * sqrt(131) = 147nV With a combined noise of about 248nV. 2013-11-09 played with simulating the filters in ngspice. We did not see the frequency corners which we expected. We may go with these components anyway: 754-RG1608P-2611-BT5 thin film 2.61kOhm 0.1% 80-C0603C271J5G capacitors 270pF 5% 2013-12-21 re-programming the SAM3X seems to require resetting the chip which can be done by connecting pin 130 to +3.3v. We did not include a switch to make this easy in the rev 1.0 version of the board, so we added this for the rev 1.2 version. 2014-01-11 We used openocd to connect to the SAM3X via JTAG. https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ Kendrick's board responds, Eric's first "rev 1.0" board seems to have a non-responsive chip. 2014-01-18 Tried a trial using US board rev1-K0: * BIAS OUT was wired to a SelveRest electrode over right margin of trapezius at ~C5 level * INP1 approximately at location FT7 * INN1 connector located at "Fp" * ./wired.sh * Horizontal sensitivity: 20 * Vertical sensitivity to 20 * Baseline: Manual * Vert baseline: 0.000001? (did not record, but tested later) * Horz baseline: 0.0000015? (idem) results: * 75 pixels Sensitivity seemed very high; it was relatively easy to get the cursor to go to one edge or the other of the square, but more difficult to get it to stay in the middle region. Control may have been via EMG; left temporalis muscle seemed to give vertical control and frontalis muscle or corrugator supercilii. This is not as good as our previous best results, but subjectively feels like this could easily be improved with practice and tuning of sensitivity and baseline. We also noted that our best previous run (done by Ace in November of 2012 right after a shower with the rev0-K0 board with the digital isolator) does not appear to be recorded in this log; our memory was that this was somewhere in the 40 pixel mean distance. 2014-01-25 Ace's board now works, now that we have fixed the polarity of Zener diode D1 which on the rev 1.0 version of the board had the dot on the annode side rather than the cathode side. We fixed this for the "rev 1.2" of the board. 2014-02-01 Ace's board was showing strange behavior. The GPIO pins were all reporting as 1, until we shorted the GPIO pins the non-isolated side to ground. The signals reported did not appear to change as expected when we connected IN1P and/or IN1N to either ground or +5v. We altered the firmware to send test signals, but the signals received looked like noise, not the test signals. We tested the continuity between the ADS and the isolator chips, as well as the continuity between the SAM3X and the isolator chips. We used a variation on the "Blink" example to not only set the LED HIGH and LOW but also the pins which send data from the SAM3X to the ADS and checked the signals with a multi-meter. Everything looked fine. We altered the firmware to read and report the chip ID and write and then read various values in the GPIO register. All of this worked fine, and (surprisingly) the test signals now looked fine, too. Our best guess is that a pin was not making good contact and that pressing on it with the multi-meter may have fixed it for now. Given the multiple email requests about the status of the project, we discussed creating something like a blog. We may start with the "gh-pages" branch of the eeg-mouse project. 2014-05-10 Laser cut case based on scad-files received by KMS and is good. The piece opposite of USB connector is difficult to orient; adding ventilation holes or other clues to orientation may be a good idea. When exporting the .dxf file from OpenSCAD, the circles and other shapes are generated as large series of anchors and small vectors, rather than single circles, or curves. This creates very large output files and overwhelm some lasercutters. This appears to be a problem with OpenSCAD, and requires further investigation. 2014-05-17 Discussion breaking the "eeg-mouse" project into multiple separate projects. The "rev 0" hardware could be extracted as an ADS129x-breakout-board project. The "rev 1" hardware could become and Open-ExG project. The "eeg-mouse" project would then become a software project which depends upon Open-ExG. Things we would like to do include: * adding some "when project began" info to the HTML pages * use git-filter-branch to split the projects for git-hub (we'd keep the main eeg-mouse master history intact for now, perhaps eventually move that to an old-master branch) * document our success with the hardware platforms * record graphical display of EEG, EOG, EMG, ECG * explain the safety features * measure and explain differences between through-hole hardware and integrated hardware * find manufacturers and price-out small-run assemblies (failure rate?) 2014-05-24 Trouble with LEDs, turned out that PIN13 on the SAM3X was not well soldered to the board. Examined number of pins which are easy to examine continuity from a via, most are, it turns out. The USB pins, the JTAG pins, the crystals, and some of the capacitors are exceptions. A few of the pins go through a resistor before hitting a via. We discussed "bed of nails" testing, and what changes to the under-side of the board that would require. * https://en.wikipedia.org/wiki/Boundary_scan#JTAG_Test_Operations * http://www.atmel.com/tools/BSDL_files_SAM3X.aspx For the Sam3X, "Test" mode requires that JTAGSEL be pulled high, however we seem to have tied it to ground. While we might be able to cut a trace and get the rev 1.2 board into JTAG Boundary Scan mode, it would not be straight-forward. Use of the Open Bench Logic Sniffer from DangerousPrototypes.com with ols-0.9.7 indicated that there was a problem with the SERIAL line to the LEDs. Using a microscope and poking at Pin13 on SAM3X with fine tweezers, some movement could be seen with the foot, even though it passed the continuity test. Careful cleaning and re-soldering fixed it. 2014-06-08 Discussed splitting out basic hardware and signal capture code into a separate ExG project, as a number of people seem to be interested in using our hardware as a biopotential amplifier/DAQ for purposes other than controlling the mouse cursor. Discussed using GDAQRec project as an initial GUI that would be friendlier than the current command line scripts. 2014-06-29 Modified GDAQRec to capture data from a command line script, and verified that we could use this to capture data in soft real time from the rev1 hardware using our existing command line scripts. 2014-07-12 Reviewed some of the math behind bilinear filter design with the goal of adding live filtering to GDAQRec to provide a reasonable preview of an ECG or EEG. 2014-09-27 Noted that seeedstudio.com has a much lower price for four layer boards than goldphoenixpcb.com; we may want to consider this for the shield. We continued to work on the schematic for the OpenHardwareExG shield. Our Plan is for the boards to autodetect whether multiple boards are stacked. When there is nothing in pin 2 of the underside connector, the signal on the Master wire will be high. This will also be used to drive CLSEL high when the board is Master and low when it is Slave. 2015-01-01 OpenHardwareExG_Shield is starting to take shape. We are looking at how small we can make a 4 layer Arduino shield. Each 1/4" lengthwise strip of board will cost about 3 USD per board. We are sacrificing some clarity in routing in order to reduce board size to minimize costs. 2015-10-31 Continued to work on active electrode. Did initial component selection and placement. Experiemented with 0.1 inch pitch conenctor, but a shrouded connector is larger than all of the other components on the board combined. Found a promising 1 mm pitch connector (DF50A-3P-1H, mates with DF50A-3S-1C with DF50-2830SCFA or DF50K-2830SCFA pins); we will try adding this conenctor next time. 2016-07-17 OpenHardwareExG_Shield project was updated to KiCAD v4 ... it seems that multi-line text items were misaligned in the process. Firmware improvements ============ * cleanup the ads1298.h, split out 1298 and 1299 and look at 129x * verify firmware still works with conditional compilation * rev0 hardware not tested yet * add listener to both serial ports, * send on whichever port pings in * make speed configurable * make shared_negative_electrode configurable * verify top SPS of text format * make output format configurable * make a 16k SPS binary format (1298 can do 32k; support that on rev0?) * make timestamp a float, or otherwise avoid wrap-around * move timestamp into regular frame, adjust frame-parser * "There exists a Modular EEG serial packet data format that is typically used to transmit EEG data over serial;" make this format a mode? Quote from: http://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/s2012/cwm55/cwm55_mj294/index.html#design Ideas to try ============ * More literature review * Make HTML for ExG board and ADS129x-Breakout * Try recording samples from both the rev0 and rev1 boards to compare signal quality. * Add real time spectrogram * Investigate correlating signals from different electrodes, rather than simply getting signals in the target band(s) from a single pair. * Try controlling with big muscles, e.g. biceps brachialis, adductor pollicis. * Allow sensitivity and baseline to be specified on command line. * Practice. * Try narrower bands; may need better/faster bandpass filters. * Consider machine learning? At any point in the process, we could curate a set of training data (e.g. "moving left", "moving right", and "not moving" examples). We could then pre-process the data in various ways (e.g. FFT or pulling out a few frequencies with filters) and then use this data to train a neural network or similar system (e.g. a SVM). This may identify features in the data that we are not currently using, but it may be difficult to reverse engineer what features the neural network is using. During the "obstacle course" runs, we can make fairly strong inferences about what the subject is attempting to accomplish. * Create a square-wave, sine-wave generator for test signals at ExG levels * perhaps try to make /wider/ ranges, rather than more narrow ranges * Record EEGs from all three of us from a series of tasks (Penny et al 1999 and 2000) and look for tasks which can be reliably distinguished for all three of us. * Try to different electrodes to compare signal quality. Question: how to define a "gold standard" signal for comparison (silver-silver chloride? Add a signal with a second set of electrodes?) * Consider BMJ xmas edition article: A comparison of the EEG response to various songs (NIN compared to christmas music, for example... or xmas music when heard in the time period from Halloween to Xmas). Problem list ============ * Upgrading to KiCAD v4 might mess up multi-line text items on PCB Silk. * Improve control of cursor. * separate out view and model logic in window.pl. * seek and destroy dash-in-filename bug in Arduino IDE. * Set up the arduino to work as a mouse, perhaps initially with synthetic input rather than EEG/EMG. * Revisit filter design for RLD/BIAS circuit * Gain settings are different between the ADS1298 and ADS1299, with the same register setting corresponding to different gains. Eventually the firmware should detect which chip is in use and report the gain (possibly scaling the output appropriately). * The rev1 version of the board has male serial headers. * Replace the BoM part-numbers to have shrouded headers to avoid accidental shorting of 3.3v. * Consider adding a limiter of around 200mA. (We already have 500mA resettable fuses so maybe this is not needed if shrouding reduces chance of shorting.) Eventually ========== * JTag, openocd demo * Logic Sniffer, ols-0.9.7 demo * replace pins with jumpers in rev1 schematic * replace L with FB (device - filter) for ferrite beads in rev1 sch * review calculating capacitance delay * discuss firmware merging with Chris Rorden * Firmware: support ADS demo boards connected to Arduinos or something * http://nl.mouser.com/search/ProductDetail.aspx?R=0virtualkey0virtualkeyADS1292RECG-FE