During the last days, I’ve been reading a lot about Lucid Dreaming and the several alternatives of accomplishing it. If you google the subject you’l find dozens of tiny gadgets promising the do it, but very few will really help in that because one of the key actions consists in detecting REM (Rapid Eye Movement) which only seem to be possible either by using some EEG equipment to monitor your brain or by analyzing the eye movement during sleep. The second option seems to be too complex for me because I couldn’t find any similar gadget that could be hacked.
And that’s where the Mindflex comes into play. The Mindflex is a toy developed by Mattel which uses a headband to read brainwaves and control games. It uses a processor from Neurosky very similar to the one on their official Development Kit.
Searching for the available options I’ve stumbled upon an awesome post ( http://frontiernerds.com/brain-hack ) describing in detail this little gadget and how to hook it to an arduino. This was almost perfect except that I wanted that this could remain portable and could be connected to any bluetooth enabled device directly.
HC-06 Bluetooth module ( http://www.ebay.com/sch/i.html?_trksid=p2050601.m570.l1313.TR0.TRC0.H0.Xhc-06+module&_nkw=hc-06+module&_sacat=0&_from=R40 )
Bluetooth enabled device.
The hardware hack is fairly simple. Just connect the Pin1 of the BT dongle to the T pin on the headband, Pin2 to the R pin, Pin3 to GND and Pin4 to VCC. Just two quick side notes:
* I was lazy enough to solder the BT dongle directly to the battery header. To do a perfect job you should remove the pcb and solder the BT dongle to the power switch (so that it can be turned on/off without removing the batteries).
* Connecting the Pin2 to the R pin is not necessary because we’re just listening but it doesn’t hurt doing so. We never know when someone might be able to find a new feature that could require it. 🙂
To parse the data I had to come up with a python script to do it since I couldn’t find anything ready for use other than the arduino lib:
#!/usr/bin/python import serial import sys latestByte = ('c') lastByte = ('c') inPacket = False myPacket =  PLENGTH = 0 EEGVALUES =  EEGRAWVALUES =  def parsePacket(): if checksum(): i=1 while i < len(myPacket) - 1: if ord(myPacket[i]) == 0x02: POOR_SIGNAL = ord(myPacket[i+1]) i += 2 elif ord(myPacket[i]) == 0x04: ATTENTION = ord(myPacket[i+1]) i += 2 elif ord(myPacket[i]) == 0x05: MEDITATION = ord(myPacket[i+1]) i += 2 elif ord(myPacket[i]) == 0x16: BLINK_STRENGTH = ord(myPacket[i+1]) i += 2 elif ord(myPacket[i]) == 0x83: for c in xrange(i+1, i+25, 3): EEGVALUES.append(ord(myPacket[c]) << 16 | ord(myPacket[c+1]) << 8 | ord(myPacket[c+2])) i += 26 elif ord(myPacket[i]) == 0x80: EEGRAWVALUES = ord(myPacket[i+1]) << 8 | ord(myPacket[i+2]) i += 4 print "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d" % (POOR_SIGNAL,ATTENTION,MEDITATION,EEGVALUES,EEGVALUES,EEGVALUES,EEGVALUES,EEGVALUES,EEGVALUES,EEGVALUES,EEGVALUES) else: print "Invalid Checksum!" def checksum(): x = 0 for i in range(1, len(myPacket) -1): x += ord(myPacket[i]) return ~(x&255) & 0b11111111 == ord(myPacket[len(myPacket)-1]) def readCSV(): global myPacket, lastByte, LatestByte, inPacket, PLENGTH ser = serial.Serial( port=sys.argv, baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.SEVENBITS ) ser.isOpen() try: while 1 : while ser.inWaiting() > 0: latestByte = ser.read(1) if ord(lastByte) == 170 and ord(latestByte) == 170 and inPacket == False: inPacket = True elif len(myPacket) == 1: myPacket.append(latestByte) PLENGTH = ord(myPacket) elif inPacket == True: myPacket.append(latestByte) if len(myPacket) > 169: print "Error: Data Error too long!" del myPacket[:] inPacket = False del EEGVALUES[:] elif len(myPacket) == PLENGTH + 2: parsePacket() del myPacket[:] inPacket = False del EEGVALUES[:] lastByte = latestByte except KeyboardInterrupt: print('Exiting...') if ser.isOpen(): ser.close(); sys.exit(0) if len(sys.argv) < 2: print "Mindflex datalogger by David gouveia <david.gouveia[at]gmail[dot]com>" print "Usage: %s " % sys.argv sys.exit(1) readCSV()
This will be the result (tested on OSX):
PS: I know that this script probably looks like crap. Feel free to improve it or check github for an updated version 🙂
You can also extract raw data from the EEG by putting your HC-06 in 57600 baud mode (send ATBAUD+7 quickly to it over the serial input, while the Bluetooth is disconnected), connecting its TX pin to the R pin on the EEG daughterboard, and then sending 0x00, 0xF8, 0x00, 0x00, 0x00, 0xE0 to the EEG unit at 57600. (These numbers simulate sending 0x02 at 9600 baud, and that switches on the raw mode.) In raw mode, you have access to all the same power spectrum data, but you also get 512 raw samples per second.
Shouldn’t bytesize=serial.SEVENBITS be bytesize=serial.EIGHTBITS?
The Mindflex sends 8-bit binary data.
You’re probably right, I need to test this… Unfortunately to do so I need to find it first because I have no idea where I put it 😐
David, there are two more steps that you need to perform to get raw EEG from the mindflex. First, you need to solder a wire from the B1 test post on the neurosky TGAM to VCC. This puts the device in 57600 baud raw data mode. You should also cut the VCC line to the internal radio to conserve power. Second, you need to set the baud rate on the HC-06 module to 57600 using the serial AT command.
Email me at [email protected] and I’ll send you detailed instructions with pictures.