CNI widgets

From CNI Wiki
Revision as of 22:08, 14 February 2012 by imported>Bobd (Serial port scan trigger device)
Jump to navigation Jump to search

The firmware code for the devices is publicly available on GitHub. If you'd like to contribute to the code, please send us a note so that we can coordinate efforts.

Serial port scan trigger device

CNI trigger box that contains the serial port trigger device described here.
CNI serial port trigger device circuit diagram.

We use a Teensy board programmed using a simple teensyduino sketch. The device generates TTL pulses through a serial port command ("[t]"). The trigger output is electronically ORed with any other trigger devices that might be connected on the same line through a signal diode (1N4148).

This device will also listen for input pulses and send out a serial port character ("p") whenever one is detected. It uses an external interrupt, so it can reliably detect very brief pulses. We use this to detect the GE 3.3v scope trigger pulses (~4 usec pulse duration).

Finally, the trigger device can stream data out through its serial port. This is useful for sending commands to a third machine. E.g., to start or stop recording digital video or to send stimulus tags to the EEG system. To allow the microcontroller to be connected to real RS232 serial ports you would need a level shifter (like the Sipex SP3232E) to convert the 5v signal lines to +/-12v RS232 signals. But we wanted to connect to the third machine via USB, so we just used a FTDI cable, which interfaces directly to the Teensy pins (just connect FTDI Rx to Teensy Tx and FTDI Tx to Teensy Rx).

See the CNI trigger code for serial port.

GE physiological data monitor

CNI PPG pulse detector device.

We also built a device to read serial data from the GE MR750 physiological monitoring port in the PGR cabinet. We need to detect the pulses in real-time for EEG balistocardiogram artifact removal. Unfortunately, the pulses are not available in the GE system, but they do provide the raw PPG data (along with respiration belt and ECG data).

The data come in 12-byte (96-bit) packets delivered at 115200 bps. A packet comes every 5ms, with silence between packets. This produces data bursts of 96bits / 115.2bits/ms = .8333ms with 5 - .8333 = 4.1667ms of silence. (This timing pattern was confirmed with a scope.) So we can detect the start of a data packet by waiting for the silent period before the data arrives. Here we only care about the PPG value. But the code could be easily modified to do something with the other physiological readings.

To detect a pulse, we compute a running mean and standard deviation and compute a z-score for each new data point. When several consecutive data point z-scores are above threshold, we signal that a pulse was detected. With a Teensy 2++ (which has 8k SRAM), we can maintain a buffer size of 1024, which is 1024 * 0.005 = 5.12 seconds. This seems to be enough to give a very stable pulse detection.

Circuit tidbits

  • Outputs are protected from reverse voltages with a diode
  • We used a little monochrome OLED display to show what is happening. To drive the 3.3v OLED from the 5v Teensy, we needed a 5v/3.3v logic-level converter. We used the HEF4050BP hex buffer that Adafruit provides with the OLED. It was wired following their tutorial. The Teensy has no 3.3v source, so we also needed a 3.3v linear voltage regulator.
  • We need a little circuit to take the scanner data stream (-12v to +12v) and allow it to be safely ready by our 5v microprocessor. We just took the Tx part of this simple RS232 level converter. We used a 2N3904 transistor with emitter to ground, collector to the UART Rx pin on the microcontroller with a 10k pull-up resistor to the 5v line, and the base connected to the Tx line coming from the scanner via a 4.7K resistor, with a 4.7k pull-down to ground.
  • For the firmware, we started with the Adafruit example code for driving the OLED, but their bit-banged SPI turned out to be too slow for our purposes (~40ms per screen refresh), so we modified it to use hardware SPI. This, as well as some other minor optimizations, got our screen refresh time down to ~2ms, which allowed our pulse detector to run at the native data physio rate of 200 Hertz. (We've been too lazy to put our code into github, but will do so if anyone expresses interest.)