TGAM1-EEGReader icon indicating copy to clipboard operation
TGAM1-EEGReader copied to clipboard

Missing SoftwareSerial.cpp file

Open ThomasDotCodes opened this issue 11 years ago • 8 comments

Thanks for posting -- I got it to compile on arduino nano after lots of messing around (the download on your github for some reason was missing the modified SoftwareSerial.cpp file). Unfortunately, even though it's compiled, I can't seem to get it to work. Once I figure out why I'll post another issue.

ThomasDotCodes avatar Sep 02 '14 16:09 ThomasDotCodes

Oups, I'll upload it today, sorry!

Just in case, check the wiring. TGAM R should go to arduino TX and TGAM T should go to arduino RX. Bluetooth goes to 9,10,11,12. Check your HC-05 module, as mine did not have the KEY pin wired to the pin out and I had to modify it. In case you can not power the Bluetooth module from an arduino PIN (which may happen if it is a pro mini 3.3v, as mine, you can power it from the batteries and wire the RESET pin to 12, where power should be, and it will perfectly work).

On the headset, I used an arduino pro mini 3.3v version, powered from the headset batteries directly.

To receive, I used a duemilanove, but that shouldn't matter, you could use none at all.

This code relies on using an unmodified headset (no hard wiring done at all). And it may not always work, due to noise on the TX/RX lines between arduino and TGAM, a packet (single byte) could not be correctly received, rendering TGAM useless until next power cycle. I did not include any check in case of errors.

I hope this helps, otherwise just post and we'll try something else ;)

gpascualg avatar Sep 02 '14 16:09 gpascualg

Thanks! I'm actually using a modified MindFlex headset. From what I understand, it's still the same TGAM1 board, just set to run at 57600bps. Details of mod at http://darrenmothersele.com/blog/2013/10/07/mindflex-raw-eeg-data/

And I'm not using BT at all--I just have the TGAM wired to an arduino, and monitoring the Serial output directly from there. I have a feeling that's what's tripping me up, I'm guessing I need to combine the Brain_Receiver and Brain_Transmitter sketches, and remove/replace all of the HC/BT references.

ThomasDotCodes avatar Sep 02 '14 16:09 ThomasDotCodes

That's exactly t'he modification I was talking about. I don't know if after applying it TGAM can still change it's mode or if it is forced to work in that mode/baudrate. I don't know an easy way to check it, I guess trial and error might be the only way.

TGAM and HC libraries are completely independent, there should be no issue at all. All you have to do is pass a valid HardwareSerial or SoftwareSerial to the Setup function.

Setup function sends data to the TGAM module to configure it, and unless you use one of the other provided functions, Setup does it at its factory and default baudrate. See TGAM.h for other functions which may work better for you.

Also check your TGAM version, 1.6 (16) should be for the original Mindflex and 1.7 (17) for Mindflex Duel.

I may have some other functions laying around at my PC, which weren't published at all as I used them to test. I'll be home in about 30 mins, let me upload them just in case you find them useful.

gpascualg avatar Sep 02 '14 17:09 gpascualg

I forgot to say, sending commands at a baudrate different than the one TGAM is working on, will most likely make TGAM receive something wrong, rendering it useless until power cycled.

And BrainTransmitter should be the most useful for you, simply ignore HC and transmit there over seria.

gpascualg avatar Sep 02 '14 17:09 gpascualg

EDIT: SoftwareSerial.cpp seems to be in the Modifications folder :s

Ok, using the last commit (that I just pushed), something like this should do the work for you:

// Define which HC and TGAM version we will be using
#define USING_TGAM17 // OR USING_TGAM16
#define USING_PARSER
#include <EEGReader.h>

// Variables and objects
// I am assuming TGAM is connected via SoftwareSerial on pins 10 (RX, TGAM T) and 11 (TX, TGAM R)
SoftwareSerial tgamSerial(10, 11);
ThinkGearStreamParser parser;

void dataHandler(unsigned char extendedCodeLevel, unsigned char code, unsigned char numBytes, const unsigned char *value, void *customData )
{
    // Raw data
    if (extendedCodeLevel == 0 && code == 0x80)
    {
        // Received a raw packed!       

        // Flag start (to avoid misparsing a packet on the PC side)
        Serial.write(0xFF);
        Serial.write(0xFF); 

        // Send the RAW value, 1 byte at a time
        // We will first send the MSB (most significant byte) and then LSB
        Serial.write(*value);
        Serial.write(*(value+1));

        // To fetch this value on the PC side we should first wait to receive FF FF and then:
        // (short) int raw = (Serial.read() << 8) | Serial.read()
        // Take into account, it won't work done like this, we should first check available() and then read(), never read if nothing is available
    }
}

void setup() 
{
    // Setup TGAM module
    // NOTE THAT WE ARE USING SetupEx, the last parameter stablished the INITIAL baudrate, not like Setup, which stablishes the final baudrate after configuration is done
    TGAM::SetupEx(&tgamSerial, TGAM::Config(TGAM::CONFIG_RAW, false, false, false, false), BAUD_FAST);

    // PC Serial connection
    Serial.begin(9600);

    // Initialize the parser
    THINKGEAR_initParser(&parser, PARSER_TYPE_PACKETS, dataHandler, NULL);
}

void loop()
{
    if (tgamSerial.available())
    {
        THINKGEAR_parseByte(&parser, tgamSerial.read());
    }
}

gpascualg avatar Sep 02 '14 18:09 gpascualg

Thanks so much for the help so far, the update and provided code seems to be a huge step in the right direction. I also didn't realize that the headsets had different versions, so I changed that to TGAM16 (I'm using the one from original MindFlex).

It is definitely responding, however since I'm trying to display the raw data on PC, I need to fill in the blanks where you put

// To fetch this value on the PC side we should first wait to receive FF FF and then:
// (short) int raw = (Serial.read() << 8) | Serial.read()
// Take into account, it won't work done like this, we should first check available() and then read(), never read if nothing is available

I'll post an update once I get more time to test. Thanks again.

ThomasDotCodes avatar Sep 02 '14 18:09 ThomasDotCodes

For the missing part, something like this would work: https://github.com/blipi/TGAM1-EEGReader/blob/master/Processing/Processing.pde#L33

You need to make the raw variable global and, with another global variable, keep track of which step of receiving are you. That code is exactly what you need, it simply does (in pseudocode):

if Serial.available() // Or in Processing, whenever serialEvent is called
    unsigned char b = Serial.read();

    if readingStep is 1 // Waiting for first FF
        if b == 0xFF
            readingStep = 2; // Ok, we received FF; lets go to step 2

    if readingStep is 2 // Waiting for second FF (sync)
        if b = 0xFF
            readingStep = 3;
        else
            readingStep = 1; // We somehow received something else, go back to step 1

    if readingStep is 3
        raw = b << 8; // Save MSB
       readingStep = 4

    if readingStep is 4
        raw |= b // Add LSB
        readingStep = 1 // Go back to step 1

gpascualg avatar Sep 03 '14 20:09 gpascualg

Please update to latest commit: https://github.com/blipi/TGAM1-EEGReader/commit/645f9e12ab83b0da201a4ad339780b3e1e86d19e

There were some potential issues with the 1.6 version. I can not test it, as I do not own an original Mindflex, your feedback is important.

gpascualg avatar Sep 17 '14 10:09 gpascualg