Blino Logo

Tee-Naps

Installation

Step 1 - Arduino IDE

Download + Install Arduino IDE

Navigate to the the main download page at https://www.arduino.cc/en/Main/Software

Choose the supported version for your system. Once downloaded, run the installer.

Step 2 - Teensy Toolchain

Download + Install Teensyduino, the Teensy toolchain.

Go to https://www.pjrc.com/teensy/td_download.html and follow the link to relevant OS.

Download and run the installer for Teensyduino. During the installation the Arduino IDE directory must be identified.

If the installation fails, listing supported Arduino versions. Make sure a supported Arduino version is identified - Teensyduino should work with the latest version of Arduino found.

Step 3 - TeeNaps Library

Now the development environment for the Teensy is established, the TeeNaps library must be installed.

Locate libraries directory

Locate your system's Arduino "Libraries" directory. This will typically look something like:

C:\Program Files (x86)\Arduino\libraries

If you are having trouble finding this, go to your Arduino application icon on the desktop. Right click, properties. Then note the path in the properties window.

Install the TeeNaps library

Find the git repository here: https://bitbucket.org/synapsdev/teenaps

There are two ways of downloading the library.

  1. Download the zipped folder, then extract its contents into the Arduino library directory from the last step.

  2. Navigate into Arduino library directory on the command line, then git clone the repository. This will download the repository into the current directory.

git clone https://bitbucket.org/synapsdev/teenaps.git

The advantage of this method is when the library is updated in the future, the git pull command can be used to update it.

Additional Resources

For further resources, take a look at relevant links:

Library

Useage

There are two main classes that cover all required functionality. The TeeNapsController is for controlling the TeeNaps hardware. The BlinoParser is used for parsing/processing the data retrieved from the EEG sensor on the TeeNaps into meaningful information.

TeeNapsController

Use the TeeNapsController to setup how the TeeNaps operates. This includes functions for powering the EEG sensor and on-board LED, retrieving data from the EEG sensor over UART and configuring the EEG sensor operating modes.

The TeeNapsController is a static class. This means you do not have to create an object to work on. Instead, control of the TeeNaps can be made using calls to the static functions provided in the class.

1.Include the installed TeeNaps.h:

#include <TeeNaps.h>

This should provide all TeeNaps functionality provided you have installed the TeeNaps into the arduino libraries directory correctly.

2.The controller must be powered and configured into an operating mode correctly:

TeeNapsController::activateTGAT();

[Optional] Setup a serial connection over the USB UART interface to receive data from the Teensy to your computer - Useful for printing or logging:

USBSERIAL.begin(TeeNapsController::BUADRATE_57_6K);

3.The TeeNaps EEG chip will operate in a default baudrate and mode, however this function can be used to set the desired mode:

setMode(TeeNapsController::RAW_OUTPUT_57_6K);

4.Data from the EEG sensor can be detected using:

if(TeeNapsController::isWaiting())
{
...
}

And then when data is detected, it can be read using:

char data = TeeNapsController::readTGAT();

BlinoParser

Use the BlinoParser class to process bytes retrieved from the EEG sensor into meaningful information.

There are two methods of working with the parsed information:

1. Returning Packets

The parseByte function returns the latest packet. It is advisable to check with a conditional that the packet has been updated before using it. This is advised as not every iteration a byte is parsed is new information updated in the packet.

Check the object's "updated" member variable.

ParsedPacket packet = parser.parseByte(data);
if(packet.updated)
{
    ...
}
2. Callbacks

There are a set of callback functions which when defined are executed when the associated information is parsed. Define these to use the information as desired.

void eegSignalCallback(EEG eeg)
{
    ...
}

In the setup code block, set the callback function in the blinoParser object to function defined previously:

parser.eegSignalCallback = &eegSignalCallback;

Now when the parser processes a new set of eeg values, the callback previously defined will execute:

if(TeeNapsController::isWaiting())
{
    int data = TeeNapsController::readTGAT();
    parser.parseByte(data);
}

Examples

Blinky

This example demonstrates the use of the TeeNaps on board LED. An appropriate first example to run with the TeeNaps Teensy hat.

Logging

This example demonstrates the use of enabling the logging of data recieved from the EEG sensor over the USB serial interface to a specified file.

Returning Packets

This example demonstrates the use of returned packets of processed EEG data from the parser. Uses a conditional if statement to detect when the packet has been updated with new values.

Callbacks

This example demonstrates the use of defining callback functions which execute when certain data items are processed through the parser.

Command Bytes

This example demonstrates the use of command bytes sent to the EEG sensor over the UART to control what mode the sensor operates in.

Library Explanation

What follows is an explanation of the Python source code which is available for modification and extension.

Much of what is detaild here is covered in the code comments, however there may be further details found here.

TeeNaps Controller Class

The TeeNaps static class is used to control the TeeNaps from the Teensy. This includes getting data, configuring sensor EEG mode.

Constants

TGAT_POWER_PIN - This is the GPIO pin used to control power to the EEG sensor.

LED_POWER_PIN - This is the GPIO pin used to control the UART pin. Pull down to deactivate the UART line when finished with.

USB_SERIAL - Serial interface over the USB. Typically used to communicate with a computer the Teensy is connected to.

TGAT_SERIAL - Serial interface over one of the Teensy UART pins. Used to communicate with the EEG sensor.

BAUDRATE.(BUADRATE_1_2K = 1200, BUADRATE_9_6K = 9600, BUADRATE_57_6K = 57600) - Enum of different baudrate values,

OUTPUT_MODE.(NORMAL_OUTPUT_1_2K, NORMAL_OUTPUT_9_6K, RAW_OUTPUT_57_6K, FFT_OUTPUT_57_6K) - Enum of the different modes the EEG sensor can be set in. These are passed into the set mode function to configure the EEG sensor.

Variables

_interface - Indicates which interface is being used to communicate with EEG sensor.

_UART - The UART object created for control of UART interface.

_I2C - The I2C object created for control of the SC16IS750 I2C chip.

Functions

activateLED(self, selectedLED) - Activate the desired LED using the LED constants.

deactivateLED(self, selectedLED) - Deactivate the desired LED using the LED constants.

deactivateAllLED(self) - Deactivate all LEDs currently active.

activateTGAT(self) - Power the EEG sensor on the PiNaps. It is important the EEG sensor is powered before receiving data and controlling the sensor.

deactivateTGAT(self) - Powers down the EEG sensor. Desirable if not in use for an extended time to save battery.

setupUART(self) - Sets up the UART interface for communication with the EEG sensor in the default operating mode, 57.6k baudrate with normal and raw wave data.

deactivateUART(self) - Unconfigures use of UART interface for communication with EEG sensor. Making available the alternative I2C interface.

setupI2C(self) - Sets up the I2C interface for communication with the EEG sensor in the default operating mode, 57.6k baudrate with normal and raw wave data.

isWaiting(self) - Returns boolean indicating if there is data waiting to be received from the EEG sensor.

dataWaiting(self) - Returns a number indicating the number of bytes waiting to be received from the EEG sensor.

readTGAT(self) - Returns the next byte waiting to be received from the EEG sensor.

setMode(self, output_mode) - Set the operating mode of the EEG sensor using output modes class.

_decodeByte(self, byte) - Private class used to decode bytes received over UART.

Blino Parser Class

The BlinoParser class is used to parse the data received from the EEG sensor which comes as a stream structured in a defined protocol. The parser then processes it to extract useful information.

This works by inputting the constant stream of bytes being received from the EEG sensor as they come. The parser records it all and once enough parts are received to process some EEG information, it becomes available in the parser object.

Constants

State.(PARSER_STATE_NULL, PARSER_STATE_SYNC, PARSER_STATE_SYNC_CHECK, PARSER_STATE_PAYLOAD_LENGTH, PARSER_STATE_PAYLOAD, PARSER_STATE_CHKSUM, PARSER_STATE_WAIT_HIGH, PARSER_STATE_WAIT_LOW, PARSER_SYNC_BYTE, PARSER_EXCODE_BYTE) - Class of constants that identify the states the BlinoParser can be in. As bytes are received, the parser keeps track of what state it is in from what was last received.

DataDefinitions.(PARSER_CODE_BATTERY, PARSER_CODE_POOR_QUALITY, PARSER_CODE_ATTENTION, PARSER_CODE_MEDITATION, PARSER_CODE_8BITRAW_SIGNAL, PARSER_CODE_RAW_MARKER, PARSER_CODE_RAW_SIGNAL, PARSER_CODE_EEG_POWERS, PARSER_CODE_ASIC_EEG_POWER_INT) - Class of constants that identify the types of information the parser processes from the EEG sensor data.

Variables

PacketStructure.(updated, code, battery, quality, attention, meditation, raw, EEG.(delta, theta, lAlpha, hAlpha, lBeta, hBeta, lGamma, mGamma)) - Class which defines the structure of the packets received from the EEG sensor. The parsed data can be stored in objects of this class to give structured values.

lastByte = 0 - Keeps track of the previous byte for a future verion where the EEG sensor may provide more data and the protocol extended.

payloadLength = 0 - The expected length of the payload being receieved. Read from a byte as part of the payload describing the length of the payload to come.

payloadBytesReceived = 0 - The number of bytes receieved from the payload so far. Used to track how much of the payload receieved, so it can move to next state when it has reached the expected payload length.

dataPayload - The payload bytes buffer. This is processed through the parsePayload function.

dataPayload - The sum of all bytes retrieved. Used as part of the checksum calculation to check packet integrity.

dataPayload - The checksum value expected. Compared to the calculated checksum at end.

logging - A boolean value which indicates if debugging information should be printed to standard console.

[Data]Callback - All callback functions which can be defined using setters. When the associated data is processed by the parser, the related callback function executes.

Functions

activateLogging(int baudrate) - Activates logging EEG information to USB serial interface. Therefore if serial stream monitored over it will see debug information. Sets logging = true.

deactivateLogging() - Dectivates logging EEG information to USB serial interface. Sets logging = false.

handleDataValue(unsigned char extendedCodeLevel, unsigned char code, unsigned char numBytes, unsigned char* value,) - Identifies the code of the current byte. It then processes it according to the protocol and extracts EEG information.

ParsedPacket parseByte(unsigned char byte) - Depending on current state, processes received byte accordingly and transtions to new state if needed.

int parsePacketPayload(unsigned char byte) - When the payload buffer is filled, processes the payload contents into meaningful data the parser packet is updated with.

[Getters for latest full packet and individual EEG information.]

Additional Notes