class Mindwave::Headset

The Mindwave::Headset-class gives access to the Mindwave-Headset. It's written for the Mindwave-Headset only, but most of the code should work for Mindwave-Mobile too.

To use the callback-methods, just inherit from this class and override the Callback-Methods with your own code.

Callback Methods

↑ top

Public Instance Methods

asicCall(asic) click to toggle source

this method is called when the asic-value is parsed override this method to implement your own code

@param [Integer] asic asic-value

# File lib/mindwave.rb, line 508
def asicCall(asic)
        log.debug("ASIC Value: #{asic}")
end
attentionCall(attention) click to toggle source

this method is called when the attention-value is parsed override this method to implement your own code

@param [Integer] attention attention-value

# File lib/mindwave.rb, line 472
def attentionCall(attention)
        str = eSenseStr(attention)
        log.info("ATTENTION #{attention} #{str}")
end
heartCall(heart) click to toggle source

this method is called when the heart-rate-value is parsed override this method to implement your own code

@param [Integer] heart heart-value

# File lib/mindwave.rb, line 490
def heartCall(heart)
        log.info("HEART RATE #{heart}")
end
meditationCall(meditation) click to toggle source

this method is called when the meditation-value is parsed override this method to implement your own code

@param [Integer] meditation meditation-value

# File lib/mindwave.rb, line 481
def meditationCall(meditation)
        str = eSenseStr(meditation)
        log.info("MEDITATION #{meditation} #{str}")
end
poorCall(poor) click to toggle source

this method is called when the poor-value is parsed override this method to implement your own clode

@param [Integer] poor poor-value

# File lib/mindwave.rb, line 462
def poorCall(poor)
        if poor == 200 
                log.info("No skin-contact detected")
        end
end
rawCall(rawvalue) click to toggle source

this method is called when the raw-wave-value is parsed override this method to implement your own code

@param [Integer] rawvalue raw-wave-value

# File lib/mindwave.rb, line 498
def rawCall(rawvalue)
        log.debug("Converted Raw-Value: #{rawvalue}")
end

Private Instance Methods

convertRaw(rawval1,rawval2) click to toggle source

converts a raw-wave-data-packet of 2 bytes to a single value

@param [Integer] rawval1 first byte-packet of the raw-wave-code @param [Integer] rawval2 second byte-packet of the raw-wave-code

@return [Integer] single value generated from the 2 bytes

# File lib/mindwave.rb, line 559
def convertRaw(rawval1,rawval2)

        raw = rawval1*256 + rawval2
        if raw >= 32768
                raw = raw - 65536
        end

        return raw
end
convertToBigEndianInteger(threeBytes) click to toggle source

converts a raw ASIC power packet of three bytes to a single value

@param [Integer] threeBytes first byte-packet of the ASIC wave code @param [Integer] threeBytes second byte-packet of the ASIC wave code @param [Integer] threeBytes third byte-packet of the ASIC wave code

@return [Integer] single value generated from the 3 bytes

# File lib/mindwave.rb, line 576
def convertToBigEndianInteger(threeBytes)
  # see MindwaveDataPoints.py at
  # https://github.com/robintibor/python-mindwave-mobile
  #
  bigEndianInteger = (threeBytes[0] << 16) |\
   (((1 << 16) - 1) & (threeBytes[1] << 8)) |\
    ((1 << 8) -1) & threeBytes[2]
  return bigEndianInteger
end
eSenseStr(value) click to toggle source

this method converts the numeric eSense-value of attention or meditation to a string

@param [Integer] value eSense-value @returns [String] string-value

eSense Values(Attention and Meditation)

* 1-20 = strongly lowered
* 20-40 = reduced
* 40-60 = neutral
* 60-80 = slightly elevated
* 80-100 = elevated
# File lib/mindwave.rb, line 539
def eSenseStr(value)
        result = case value
                when 0..20   then "Strongly lowered"
                when 21..40  then "Reduced"
                when 41..60  then "Neutral"
                when 61..80  then "Slightly elevated"
                when 81..100 then "Elevated"
                else
                        "Unknown"
                end

        return result
end
logreadbyte() click to toggle source

reads out a byte from the serial-line and logs the byte using “debug”

# File lib/mindwave.rb, line 516
def logreadbyte
        begin
        ret = @conn.readbyte
        rescue EOFError
                log.fatal("EOFError")
                # But Ignore it with FF
                ret = 0x00
        end
        log.debug(sprintf("HEX: %x DEC: %d",ret,ret))
        return ret
end

Control Codes

↑ top

Constants

EXCODE

Extended codes

SYNC

Start of a new data-set(packet)

Headset Status Codes

↑ top

Constants

DONGLE_STANDBY

Dongle is in standby mode

HEADSET_CONNECTED

Headset connected

HEADSET_DISCONNECTED

Headset disconnected

HEADSET_NOTFOUND

Headset not found

REQUEST_DENIED

Request denied

Multi-Byte-Codes

↑ top

Constants

ASIC_EEG_POWER

ASIC-EEG-POWER-INT

EEG_POWER

EEG-Power

RAW_WAVE

Raw Wave output

RRINTERVAL

RRinterval

Attributes

asic[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop
attention[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop
device[RW]

@!attribute headsetid

@return [Integer] headset id

@!attribute device

@return [String] dongle device(like /dev/ttyUSB0)

@!attribute rate

@return [Integer] baud-rate of the device

@!attribute log

@return [Logger] logger instance
headsetid[RW]

@!attribute headsetid

@return [Integer] headset id

@!attribute device

@return [String] dongle device(like /dev/ttyUSB0)

@!attribute rate

@return [Integer] baud-rate of the device

@!attribute log

@return [Logger] logger instance
headsetstatus[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop
heart[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop
log[RW]

@!attribute headsetid

@return [Integer] headset id

@!attribute device

@return [String] dongle device(like /dev/ttyUSB0)

@!attribute rate

@return [Integer] baud-rate of the device

@!attribute log

@return [Logger] logger instance
meditation[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop
poor[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop
rate[RW]

@!attribute headsetid

@return [Integer] headset id

@!attribute device

@return [String] dongle device(like /dev/ttyUSB0)

@!attribute rate

@return [Integer] baud-rate of the device

@!attribute log

@return [Logger] logger instance
runner[R]

@!attribute [r] attention

stores the current attention-value

@!attribute [r] meditation

stores the current meditation-value

@!attribute [r] asic

stores the current asic-value

@!attribute [r] poor

stores the current poor-value

@!attribute [r] headsetstatus

stores the current headsetstatus-value

@!attribute [r] heart

stores the current heart-value

@!attribute [r] runner

@see #stop

Public Class Methods

new(headsetid=nil,device='/dev/ttyUSB0', connectserial=true,rate=115200, log=Logger.new(STDOUT)) click to toggle source

If connectserial is true, then this constructor opens a serial connection and automatically connects to the headset

@param [Integer] headsetid it's on the sticker in the battery-case @param [String] device tty-device @param [Integer] rate baud-rate @param [Logger] log (logger-instance)

# File lib/mindwave.rb, line 138
def initialize(headsetid=nil,device='/dev/ttyUSB0', connectserial=true,rate=115200, log=Logger.new(STDOUT))
        @headsetid=headsetid
        @device=device
        @rate=rate
        @log=log
        @log.level = Logger::FATAL
        @headsetstatus = 0
        @runner = true

        if connectserial
                serial_open
                connect(@headsetid)
        end
end

Public Instance Methods

autoconnect() click to toggle source

This method connects to the headset automatically without knowing the device-id (Mindwave only)

# File lib/mindwave.rb, line 421
def autoconnect
        cmd = BinData::Uint8be.new(Mindwave::Headset::AUTOCONNECT)
        cmd.write(@conn)
end
close() click to toggle source

this method disconnects the headset and closes the serial line

# File lib/mindwave.rb, line 444
def close
        disconnect
        serial_close
end
connect(headsetid=nil) click to toggle source

connects the Mindwave-headset(not needed with Mindwave-Mobile) (Mindwave only)

@param [Integer] headsetid it's on the sticker in the battery-case TODO: implement connection with headsetid

# File lib/mindwave.rb, line 158
def connect(headsetid=nil)
        if not headsetid.nil?
                @headsetid = headsetid
        end

        if @headsetid.nil?
                autoconnect()
                return
        end

        cmd = BinData::Uint8be.new(Mindwave::Headset::CONNECT)
        cmd.write(@conn)
end
disconnect() click to toggle source

this method disconnects a connection between headset and dongle (Mindwave only)

# File lib/mindwave.rb, line 428
def disconnect
        cmd = BinData::Uint8be.new(Mindwave::Headset::DISCONNECT)
        cmd.write(@conn)
end
parseASIC(asic) click to toggle source

this method parses the raw ASIC values and returns the values of each of the wave types

@param [Integer] asic value

@returns [Array<Integer>] Array of: delta,theta,lowAlpha,highAlpha,lowBeta,highBeta,lowGamma,midGamma

# File lib/mindwave.rb, line 385
def parseASIC(asic)
    # assign #{asic} to the array 'a'
    a = "#{asic}"
    # strip off square brackets
    a = a.delete! '[]'
    # convert to array of integers
    a = a.split(",").map(&:to_i)

    # define wave values
    delta     = convertToBigEndianInteger(a[0..3])
    theta     = convertToBigEndianInteger(a[3..6])
    lowAlpha  = convertToBigEndianInteger(a[6..9])
    highAlpha = convertToBigEndianInteger(a[9..12])
    lowBeta   = convertToBigEndianInteger(a[12..15])
    highBeta  = convertToBigEndianInteger(a[15..18])
    lowGamma  = convertToBigEndianInteger(a[18..21])
    midGamma  = convertToBigEndianInteger(a[21..24])

    # stuff wave values in array
    asicArray = [delta,theta,lowAlpha,highAlpha,lowBeta,highBeta,lowGamma,midGamma]
    
    # return array of wave values
    return asicArray
end
parse_payload(payload) click to toggle source

this method parses the payload of a data-row, parses the values and invokes the callback methods @param [Array] payload Array with the payload

# File lib/mindwave.rb, line 241
def parse_payload(payload)
        if not payload.instance_of?Array or payload.nil? or payload.length < 2
                raise "Invalid Argument"
        end

        log.info("####### PARSE PAYLOAD #########")

        extcodelevel = 0

        # parse the first code and it's payload
        code = payload[0]
        pl = payload[1,payload.length-1]
        
        if code == Mindwave::Headset::EXCODE
                extcodelevel += 1
                
                # iterate through the payload-array
                (1..payload.length).each do |n|
                        # if there is an excode, increment the level
                        if payload[n] == Mindwave::Headset::EXCODE
                                extcodelevel += 1
                        else
                                # ..otherwise parse the next code and it's payload
                                code = payload[n]
                                pl = payload[n+1,payload.length-(n+1)]
                                break
                        end
                end
        end

        # some debugging output
        log.info(sprintf("extcodelevel: %x",extcodelevel))
        log.info(sprintf("Code: %x",code))
        log.debug(sprintf("Length: %d",pl.length))
        pl.each do |n|
                log.debug(sprintf("payload: Hex: %x Dec: %d",n,n))
        end


        # SINGLE-BYTE-CODES
        if code < Mindwave::Headset::RAW_WAVE or code >= Mindwave::Headset::HEADSET_CONNECTED

                sbpayload = pl[0]
                codestr = ""

                case code
                when Mindwave::Headset::HEADSET_CONNECTED
                        codestr = "Headset connected"
                        @headsetstatus = code
                when Mindwave::Headset::HEADSET_NOTFOUND
                        codestr = "Headset not found"
                        @headsetstatus = code
                when Mindwave::Headset::HEADSET_DISCONNECTED
                        codestr = "Headset disconnected"
                        @headsetstatus = code
                when Mindwave::Headset::REQUEST_DENIED
                        codestr = "Request denied"
                        @headsetstatus = code
                when Mindwave::Headset::DONGLE_STANDBY
                        codestr = "Dongle standby"
                        @headsetstatus = code
                when Mindwave::Headset::POOR_SIGNAL
                        codestr = "Poor Signal"
                        @poor = sbpayload
                        poorCall(@poor)
                when Mindwave::Headset::HEART_RATE
                        codestr = "Heart Rate"
                        @heart = sbpayload
                        heartCall(@heart)
                when Mindwave::Headset::ATTENTION
                        codestr = "Attention"
                        @attention = sbpayload
                        attentionCall(@attention)
                when Mindwave::Headset::MEDITATION
                        codestr = "Meditation"
                        @meditation = sbpayload
                        meditationCall(@meditation)
                ## THIS METHODS ARE NOT AVAILABLE FOR MINDWAVE(MOBILE)
                when Mindwave::Headset::BIT8_RAW 
                        codestr = "8Bit Raw"
                when Mindwave::Headset::RAW_MARKER 
                        codestr = "Raw Marker"
                # EOF NOT AVAILABLE
                else
                        codestr = "Unknown"
                end

                log.debug(sprintf("SINGLEBYTE-PAYLOAD: Code: %s Hex: %x - Dec: %d",codestr,sbpayload,sbpayload))

                # Re-Parse the rest of the payload
                if pl.length > 2
                        payload = pl[1,pl.length-1]
                        # recursive call of parse_payload for the next data-rows
                        parse_payload(payload)
                end

        # MULTI-BYTE-CODES
        else
                codestr = ""
                plength = pl[0]
                mpl = pl[1,plength]

                case code

                when Mindwave::Headset::RAW_WAVE
                        codestr = "RAW_WAVE Code detected"
                        rawCall(convertRaw(mpl[0],mpl[1]))
                when Mindwave::Headset::EEG_POWER
                        codestr = "EEG Power"
                when Mindwave::Headset::ASIC_EEG_POWER
                        codestr = "ASIC EEG POWER"
                        @asic = mpl
                        asicCall(@asic)
                when Mindwave::Headset::RRINTERVAL
                        codestr = "RRINTERVAL"
                else
                        codestr = "Unknown"
                end

                # Fetch the Multi-Payload
                log.info(sprintf("Multibyte-Code: %s",codestr))
                log.info(sprintf("Multibyte-Payload-Length: %d",pl[0]))
                
                mpl.each() do |n|
                        log.debug(sprintf("MULTIBYTE-PAYLOAD: Hex: %x - Dec: %d",n,n))
                end

                # Re-Parse the rest of the payload
                if pl.length-1 > plength
                        payload = pl[mpl.length+1,pl.length-mpl.length]
                        # recursive call of parse_payload for the next data-rows
                        parse_payload(payload)
                end
        end


end
run() click to toggle source

This method creates an infinite loop and reads out all data from the headset using the open serial-line.

# File lib/mindwave.rb, line 175
def run

        tmpbyte = 0;
        @runner = true

        while @runner
                log.debug("<<< START RECORD >>>")
                tmpbyte = logreadbyte

                # 0xaa indicates the first start of a packet
                if tmpbyte != Mindwave::Headset::SYNC
                        log.info(sprintf("LOST: %x\n",tmpbyte))
                        next
                else
                        tmpbyte = logreadbyte()
                        # a second 0xaa verifies the start of a packet
                        if tmpbyte != Mindwave::Headset::SYNC
                                log.info(sprintf("LOST: %x\n",tmpbyte))
                                next
                        end

                end
        
                while true
                        # read out the length of the packet
                        plength = logreadbyte()
                        if(plength != 170)
                                break
                        end
                end

                if(plength > 170)
                        next
                end

                log.info(sprintf("Header-Length: %d",plength))
                payload = Array.new(plength)
                checksum = 0
                # read out payload
                (0..plength-1).each do |n|
                        payload[n] = logreadbyte()
                        # ..and add it to the checksum
                        checksum += payload[n]
                end

                # weird checksum calculations
                checksum &= 0xff
                checksum = ~checksum & 0xff
        
                # read checksum-packet
                c = logreadbyte()

                # compare checksum-packet with the calculated checksum
                if( c != checksum)
                        log.info(sprintf("Checksum Error: %x - %x\n",c,checksum))
                else
                        # so finally parse the payload of our packet
                        parse_payload(payload)
                end   
        
        end

end
sendbyte(hexbyte) click to toggle source

this method sends a byte to the serial connection (Mindwave only)

@param [Integer] hexbyte byte to send

# File lib/mindwave.rb, line 414
def sendbyte(hexbyte)
        cmd = BinData::Uint8be.new(hexbyte)
        cmd.write(@conn)
end
serial_close() click to toggle source

this method closes a serial connection to the device

# File lib/mindwave.rb, line 439
def serial_close
        @conn.close
end
serial_open() click to toggle source

this method opens a serial connection to the device

# File lib/mindwave.rb, line 434
def serial_open
        @conn = SerialPort.new(@device,@rate)
end
stop() click to toggle source

this method stops the run-method

# File lib/mindwave.rb, line 450
def stop
        @runner = false
end

Request Codes

↑ top

Constants

AUTOCONNECT

Autoconnect Request

CONNECT

Connection Requests

DISCONNECT

Disconnect Request

Single-Byte-Codes

↑ top

Constants

ATTENTION

Attention @see eSenseStr

BIT8_RAW

Not available in Mindwave and Mindwave Mobile

HEART_RATE

Heartrate

MEDITATION

Meditation @see eSenseStr

POOR_SIGNAL

0-255(zero is good). 200 means no-skin-contact

RAW_MARKER

Not available in Mindwave and Mindwave Mobile