Class: Mindwave::Headset

Inherits:
Object
  • Object
show all
Defined in:
lib/mindwave.rb

Overview

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.

Constant Summary collapse

CONNECT =

Connection Requests

0xc0
DISCONNECT =

Disconnect Request

0xc1
AUTOCONNECT =

Autoconnect Request

0xc2
HEADSET_CONNECTED =

Headset connected

0xd0
HEADSET_NOTFOUND =

Headset not found

0xd1
HEADSET_DISCONNECTED =

Headset disconnected

0xd2
REQUEST_DENIED =

Request denied

0xd3
DONGLE_STANDBY =

Dongle is in standby mode

0xd4
SYNC =

Start of a new data-set(packet)

0xaa
EXCODE =

Extended codes

0x55
POOR_SIGNAL =

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

0x02
HEART_RATE =

Heartrate

0x03
ATTENTION =

See Also:

  • #eSenseStr
0x04
MEDITATION =

See Also:

  • #eSenseStr
0x05
BIT8_RAW =

Not available in Mindwave and Mindwave Mobile

0x06
RAW_MARKER =

Not available in Mindwave and Mindwave Mobile

0x07
RAW_WAVE =

Raw Wave output

0x80
EEG_POWER =

EEG-Power

0x81
ASIC_EEG_POWER =

ASIC-EEG-POWER-INT

0x83
RRINTERVAL =

RRinterval

0x86

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(headsetid = nil, device = '/dev/ttyUSB0', connectserial = true, rate = 115200, log = Logger.new(STDOUT)) ⇒ Headset

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

Parameters:

  • (defaults to: nil)

    it’s on the sticker in the battery-case

  • (defaults to: '/dev/ttyUSB0')

    tty-device

  • (defaults to: 115200)

    baud-rate

  • (defaults to: Logger.new(STDOUT))

    (logger-instance)



138
139
140
141
142
143
144
145
146
147
148
149
150
151
# 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

Instance Attribute Details

#asicObject (readonly)

stores the current asic-value



129
# File 'lib/mindwave.rb', line 129

attr_reader :attention, :meditation, :asic,:poor, :headsetstatus, :heart, :runner

#attentionObject (readonly)

stores the current attention-value



129
130
131
# File 'lib/mindwave.rb', line 129

def attention
  @attention
end

#deviceString

Returns dongle device(like /dev/ttyUSB0).

Returns:

  • dongle device(like /dev/ttyUSB0)



113
# File 'lib/mindwave.rb', line 113

attr_accessor :headsetid, :device, :rate, :log

#headsetidInteger

Returns headset id.

Returns:

  • headset id



113
114
115
# File 'lib/mindwave.rb', line 113

def headsetid
  @headsetid
end

#headsetstatusObject (readonly)

stores the current headsetstatus-value



129
# File 'lib/mindwave.rb', line 129

attr_reader :attention, :meditation, :asic,:poor, :headsetstatus, :heart, :runner

#heartObject (readonly)

stores the current heart-value



129
# File 'lib/mindwave.rb', line 129

attr_reader :attention, :meditation, :asic,:poor, :headsetstatus, :heart, :runner

#logLogger

Returns logger instance.

Returns:

  • logger instance



113
# File 'lib/mindwave.rb', line 113

attr_accessor :headsetid, :device, :rate, :log

#meditationObject (readonly)

stores the current meditation-value



129
# File 'lib/mindwave.rb', line 129

attr_reader :attention, :meditation, :asic,:poor, :headsetstatus, :heart, :runner

#poorObject (readonly)

stores the current poor-value



129
# File 'lib/mindwave.rb', line 129

attr_reader :attention, :meditation, :asic,:poor, :headsetstatus, :heart, :runner

#rateInteger

Returns baud-rate of the device.

Returns:

  • baud-rate of the device



113
# File 'lib/mindwave.rb', line 113

attr_accessor :headsetid, :device, :rate, :log

#runnerObject (readonly)

Returns the value of attribute runner.



129
# File 'lib/mindwave.rb', line 129

attr_reader :attention, :meditation, :asic,:poor, :headsetstatus, :heart, :runner

Instance Method Details

#asicCall(asic) ⇒ Object

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

Parameters:

  • asic-value



477
478
479
# File 'lib/mindwave.rb', line 477

def asicCall(asic)
  log.debug("ASIC Value: #{asic}")
end

#attentionCall(attention) ⇒ Object

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

Parameters:

  • attention-value



441
442
443
444
# File 'lib/mindwave.rb', line 441

def attentionCall(attention)
  str = eSenseStr(attention)
  log.info("ATTENTION #{attention} #{str}")
end

#autoconnectObject

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



390
391
392
393
# File 'lib/mindwave.rb', line 390

def autoconnect
        cmd = BinData::Uint8be.new(Mindwave::Headset::AUTOCONNECT)
        cmd.write(@conn)
end

#closeObject

this method disconnects the headset and closes the serial line



413
414
415
416
# File 'lib/mindwave.rb', line 413

def close
  disconnect
  serial_close
end

#connect(headsetid = nil) ⇒ Object

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

TODO: implement connection with headsetid

Parameters:

  • (defaults to: nil)

    it’s on the sticker in the battery-case



158
159
160
161
162
163
164
165
166
167
168
169
170
# 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

#disconnectObject

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



397
398
399
400
# File 'lib/mindwave.rb', line 397

def disconnect
        cmd = BinData::Uint8be.new(Mindwave::Headset::DISCONNECT)
        cmd.write(@conn)
end

#heartCall(heart) ⇒ Object

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

Parameters:

  • heart-value



459
460
461
# File 'lib/mindwave.rb', line 459

def heartCall(heart)
  log.info("HEART RATE #{heart}")
end

#meditationCall(meditation) ⇒ Object

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

Parameters:

  • meditation-value



450
451
452
453
# File 'lib/mindwave.rb', line 450

def meditationCall(meditation)
  str = eSenseStr(meditation)
  log.info("MEDITATION #{meditation} #{str}")
end

#parse_payload(payload) ⇒ Object

this method parses the payload of a data-row, parses the values and invokes the callback methods

Parameters:

  • Array with the payload



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# 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

#poorCall(poor) ⇒ Object

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

Parameters:

  • poor-value



431
432
433
434
435
# File 'lib/mindwave.rb', line 431

def poorCall(poor)
  if poor == 200 
    log.info("No skin-contact detected")
  end
end

#rawCall(rawvalue) ⇒ Object

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

Parameters:

  • raw-wave-value



467
468
469
# File 'lib/mindwave.rb', line 467

def rawCall(rawvalue)
  log.debug("Converted Raw-Value: #{rawvalue}")
end

#runObject

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



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# 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) ⇒ Object

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

Parameters:

  • byte to send



383
384
385
386
# File 'lib/mindwave.rb', line 383

def sendbyte(hexbyte)
  cmd = BinData::Uint8be.new(hexbyte)
  cmd.write(@conn)
end

#serial_closeObject

this method closes a serial connection to the device



408
409
410
# File 'lib/mindwave.rb', line 408

def serial_close
        @conn.close
end

#serial_openObject

this method opens a serial connection to the device



403
404
405
# File 'lib/mindwave.rb', line 403

def serial_open
        @conn = SerialPort.new(@device,@rate)
end

#stopObject

this method stops the run-method



419
420
421
# File 'lib/mindwave.rb', line 419

def stop
  @runner = false
end