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:

  • headsetid (Integer) (defaults to: nil)

    it’s on the sticker in the battery-case

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

    tty-device

  • rate (Integer) (defaults to: 115200)

    baud-rate

  • log (Logger) (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:

  • (String)

    dongle device(like /dev/ttyUSB0)



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

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

#headsetidInteger

Returns headset id.

Returns:

  • (Integer)

    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)

    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:

  • (Integer)

    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 (Integer)

    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 (Integer)

    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:

  • headsetid (Integer) (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 (Integer)

    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 (Integer)

    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:

  • payload (Array)

    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 (Integer)

    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:

  • rawvalue (Integer)

    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:

  • hexbyte (Integer)

    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