Linux – Accessing serial data from Neurosky Mindset over bluetooth in linux

bluetoothlinuxserial-port

I am trying to access the serial data stream being transmitted from the Neurosky Mindset over bluetooth. It is a step in using ThinkGear Communications Protocol mentioned here:

http://developer.neurosky.com/docs/doku.php?id=which_api_is_right_for_me

There are a couple programs that should do this for me (Puzzlebox, Mindstream, etc.), I've either had apparently unsolvable dependency issues or they don't do exactly what I want.

I am able to pair the Mindset with my machine using blueman (specifically blueman-manager) I am able to connect the serial port to /dev/rfcomm0. What I am first wondering is: how do I read from this data stream. If I run sdptool records on the device, I get the following output:

Service Name: Dev B
Service RecHandle: 0x10005
Service Class ID List:
"Serial Port" (0x1101)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 3
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100

(I get more than that, but that is the service I'm trying to access.)

I guess my main questions are: If cat /dev/rfcomm0 displays nothing does that mean that there is no data being transmitted? Is the problem that it isn't being displayed because it is raw? Is there a command that will guarantee to give me any serial data if it is being transmitted? Is there a bluetooth standard command that starts SPP transmission (I've searched for documentation for bluez, but that hasn't been too fruitful)?

I have run everything as both root and regular so that doesn't seem to fix it.

Any help would be greatly appreciated.

Best Answer

OK, it took a bit of playing around to get the MindSet connected reliably.

The command-line bluetooth tools are more or less useless. The only repeatable way to read off the Mindset (once paired via BlueMan) was to do this:

  bash$ sudo /etc/init.d/bluetooth stop
  bash$ sudo /etc/init.d/bluetooth start
  bash$ sudo rfcomm connect /dev/rfcomm0 00:13:##:##:##:## 1
  bash$ ./mindset_capture.rb

...but this reaches EOF before a valid ThinkGear packet has been received.

Instead, pair using Blueman.

Setup:

  1. bash$ blueman-manager &
  2. enable pairing on MindSet
  3. Click Search in BlueMan
  4. Select MindSet device
  5. Click on Pair
  6. Enter PIN (0000)

Connect:

  1. bash$ blueman-manager &
  2. Right-click on MindSet and select "Connect To: Dev B" (serial connector icon)
  3. Run capture utility (e.g. bash$ ./mindset_capture.rb)
  4. Right-click on MindSet and select "Disconnect: Dev B"
  5. Quit Blueman
  6. Restart bluetooth to release rfcomm0 (thanks, BlueMan!)

    bash$ sudo /etc/init.d/bluetooth stop; sudo /etc/init.d/bluetooth start

Wouldn't it be better to have a completely command-line driven solution? Yes, yes it would. Unfortunately, the Bluetooth stack on Linux seems to be in a state where the GUI tools and the command line tools do not cooperate -- and the command-line tools do not support pairing (* UPDATE - see comments).

Reading from the device is straightforward. It continuously transmits bytes, so read from it until you encounter two SYNC bytes (0xAA), which mark the beginning of a packet. The structure of the packet is described in mindset_communications_protocol.pdf, which is supplied in the MDT.

Ruby code for reading from the MindSet:

  require 'rubygems'      # gem install serialport
  require 'serialport' 
  conn = SerialPort.new "/dev/rfcomm0", 57600
  while true
    next if conn.readbyte != 0xAA
    next if conn.readbyte != 0xAA
    while true
      c = conn.readbyte
      break if c == 0xAA
      puts "%02X" % c
    end
  end 

It's not perfect as it does no real parsing, but that's how bytes are read from the device.

Related Topic