BCIduino社区|基于python获取BCIduino脑电数据

基于python可以在Mac/linux/windows系统获取BCIduino脑电数据,基于android我们也提供了方案,联系下方管理员可以索取。此处贴出基于python获取BCIduino脑电数据的程序代码,有爱好者实测,可以在同一台电脑获取多个BCIduino模组的数据。

import sys
from pylsl import StreamInfo, StreamOutlet
import argparse
import os
import string
import atexit
import threading
import sys
import random
import serial
import struct
import numpy as np
import time
import timeit
import atexit
import logging
import pdb
import glob

header = {
     }
sample_count = 0
dict1 = dict(channal1= 0,channal2= 0,channal3= 0,channal4= 0,channal5= 0,channal6= 0,channal7= 0,ch8= 0,refer1 =0,refer2 = 0)          
data_ = []

SAMPLE_RATE = 500.0 # or 250 
START_BYTE = 0xA0  # start of data packet
END_BYTE = 0xC0  # end of data packet
ADS1299_Vref = 4.5  #reference voltage for ADC in ADS1299.  set by its hardware
ADS1299_gain = 24.0  #assumed gain setting for ADS1299.
scale_fac_uVolts_per_count = ADS1299_Vref/float((pow(2,23)-1))/ADS1299_gain*1000000.
scale_fac_accel_G_per_count = 0.002 /(pow(2,4)) #assume set to +/4G, so 2 mG 
c = ''
'''

command_stop = "s";
command_startText = "x";
command_startBinary = "b";
command_startBinary_wAux = "n";
command_startBinary_4chan = "v";
command_activateFilters = "F";
command_deactivateFilters = "g";
command_deactivate_channel = {
     "1", "2", "3", "4", "5", "6", "7", "8"};
command_activate_channel = {
     "q", "w", "e", "r", "t", "y", "u", "i"};
command_activate_leadoffP_channel = {
     "!", "@", "#", "$", "%", "^", "&", "*"};  //shift + 1-8
command_deactivate_leadoffP_channel = {
     "Q", "W", "E", "R", "T", "Y", "U", "I"};   //letters (plus shift) right below 1-8
command_activate_leadoffN_channel = {
     "A", "S", "D", "F", "G", "H", "J", "K"}; //letters (plus shift) below the letters below 1-8
command_deactivate_leadoffN_channel = {
     "Z", "X", "C", "V", "B", "N", "M", "<"};   //letters (plus shift) below the letters below the letters below 1-8
command_biasAuto = "`";
command_biasFixed = "~";
'''

class BCIduinoSample(object):
  """Object encapulsating a single sample from the BCIduino board."""
  def __init__(self, packet_id, channel_data, aux_data):
    self.id = packet_id
    self.channel_data = channel_data
    self.aux_data = aux_data

class BCIduinoBoard(object):
  """

  Handle a connection to an BCIduino board.

  Args:
    port: The port to connect to.
    baud: The baud of the serial connection.
    
  """

  def __init__(self, port=None, baud=256000, filter_data=True,
    scaled_output=True, daisy=False, log=True, timeout=None):
    self.log = log 
    self.streaming = False
    self.baudrate = baud
    self.timeout = timeout
    if not port:
      port = 'COM3'
    self.port = port
    print("Connecting to BCIduino at port %s" %(port))
    self.ser = serial.Serial(port= port, baudrate = baud, timeout=timeout)

    print("Serial established...")

    time.sleep(2)
    #Initialize 32-bit board, doesn't affect 8bit board
    self.ser.write(b'v')


    #wait for device to be ready
    time.sleep(1)
    self.print_incoming_text()

    self.streaming = False
    self.filtering_data = filter_data
    self.scaling_output = scaled_output
    self.eeg_channels_per_sample = 8 # number of EEG channels per sample *from the board*
    self.aux_channels_per_sample = 3 # number of AUX channels per sample *from the board*
    self.read_state = 0
    self.daisy = daisy
    self.last_odd_sample = BCIduinoSample(-1, [], []) # used for daisy
    self.log_packet_count = 0
    self.attempt_reconnect = False
    self.last_reconnect = 0
    self.reconnect_freq = 5
    self.packets_dropped = 0

    #Disconnects from board when terminated
    atexit.register(self.disconnect)
  
  def getSampleRate(self):
    if self.daisy:
      return SAMPLE_RATE/2
    else:
      return SAMPLE_RATE
  
  def getNbEEGChannels(self):
    if self.daisy:
      return self.eeg_channels_per_sample*2
    else:
      return self.eeg_channels_per_sample
  
  def getNbAUXChannels(self):
    return  self.aux_channels_per_sample

  def start_streaming(self, callback, lapse=-1):
    """
    Start handling streaming data from the board. Call a provided callback
    for every single sample that is processed (every two samples with daisy module).

    Args:
      callback: A callback function -- or a list of functions -- that will receive a single argument of the
          BCIduinoSample object captured.
    """
    if not self.streaming:
      self.ser.write(b'b')
      self.streaming = True

    start_time = timeit.default_timer()

    # Enclose callback funtion in a list if it comes alone
    if not isinstance(callback, list):
      callback = [callback]
    

    #Initialize check connection
    self.check_connection()

    while self.streaming:

      # read current sample
      sample = self._read_serial_binary()
      # if a daisy module is attached, wait to concatenate two samples (main board + daisy) before passing it to callback
      if self.daisy:
        # odd sample: daisy sample, save for later
        if ~sample.id % 2:
          self.last_odd_sample = sample
        # even sample: concatenate and send if last sample was the fist part, otherwise drop the packet
        elif sample.id - 1 == self.last_odd_sample.id:
          # the aux data will be the average between the two samples, as the channel samples themselves have been averaged by the board
          avg_aux_data = list((np.array(sample.aux_data) + np.array(self.last_odd_sample.aux_data))/2)
          whole_sample = BCIduinoSample(sample.id, sample.channel_data + self.last_odd_sample.channel_data, avg_aux_data)
          for call in callback:
            call(whole_sample)
      else:
        for call in callback:
          call(sample)
      
      if(lapse > 0 and timeit.default_timer() - start_time > lapse):
        self.stop()
      if self.log:
        self.log_packet_count = self.log_packet_count 
  
  
  """
    PARSER:
    Parses incoming data packet into BCIduinoSample.
    Incoming Packet Structure:
    Start Byte(1)|Sample ID(1)|Channel Data(24)|Aux Data(6)|End Byte(1)
    0xA0|0-255|8, 3-byte signed ints|3 2-byte signed ints|0xC0

    START_BYTE = 0xA0  # start of data packet
    END_BYTE = 0xC0  # end of data packet
    

  """
  def _read_serial_binary(self, max_bytes_to_skip=3000):
    def read(n):
      b = self.ser.read(n)
      if not b:
        self.warn('Device appears to be stalled. Quitting...')
        sys.exit()
        raise Exception('Device Stalled')
        sys.exit()
        return '\xFF'
      else:
        return b

    for rep in range(max_bytes_to_skip):

      #---------Start Byte & ID---------
      if self.read_state == 0:
        
        b = read(1)
        
        if struct.unpack('B', b)[0] == START_BYTE:
          if(rep != 0):
            self.warn('Skipped %d bytes before start found' %(rep))
            rep = 0
          packet_id = struct.unpack('B', read(1))[0] #packet id goes from 0-255
          log_bytes_in = str(packet_id)

          self.read_state = 1

      #---------Channel Data---------
      elif self.read_state == 1:
        channel_data = []
        for c in range(self.eeg_channels_per_sample):

          #3 byte ints
          literal_read = read(3)

          unpacked = struct.unpack('3B', literal_read)
          log_bytes_in = log_bytes_in + '|' + str(literal_read)

          #3byte int in 2s compliment
          if (unpacked[0] >= 127):
            pre_fix = bytes(bytearray.fromhex('FF')) 
          else:
            pre_fix = bytes(bytearray.fromhex('00'))


          literal_read = pre_fix + literal_read

          #unpack little endian(>) signed integer(i) (makes unpacking platform independent)
          myInt = struct.unpack('>i', literal_read)[0]

          if self.scaling_output:
            channel_data.append(myInt*scale_fac_uVolts_per_count)
          else:
            channel_data.append(myInt)

        self.read_state = 2

      #---------Accelerometer Data---------
      elif self.read_state == 2:
        aux_data = []
        for a in range(self.aux_channels_per_sample):

          #short = h
          acc = struct.unpack('>h', read(2))[0]
          log_bytes_in = log_bytes_in + '|' + str(acc)

          if self.scaling_output:
            aux_data.append(acc*scale_fac_accel_G_per_count)
          else:
              aux_data.append(acc)

        self.read_state = 3
      #---------End Byte---------
      elif self.read_state == 3:
        val = struct.unpack('B', read(1))[0]
        log_bytes_in = log_bytes_in + '|' + str(val)
        self.read_state = 0 #read next packet
        if (val == END_BYTE):
          sample = BCIduinoSample(packet_id, channel_data, aux_data)
          self.packets_dropped = 0
          return sample
        else:
          self.warn("ID:<%d>  instead of <%s>"      
            %(packet_id, val, END_BYTE))
          logging.debug(log_bytes_in)
          self.packets_dropped = self.packets_dropped
  
  """

  Clean Up (atexit)

  """
  def stop(self):
    print("Stopping streaming...\nWait for buffer to flush...")
    self.streaming = False
    self.ser.write(b's')
    if self.log:
      logging.warning('sent : stopped streaming')

  def disconnect(self):
    if(self.streaming == True):
      self.stop()
    if (self.ser.isOpen()):
      print("Closing Serial...")
      self.ser.close()
      logging.warning('serial closed')
       

  """

      SETTINGS AND HELPERS

  """
  def warn(self, text):
    if self.log:
      #log how many packets where sent succesfully in between warnings
      if self.log_packet_count:
        logging.info('Data packets received:'+str(self.log_packet_count))
        self.log_packet_count = 0
      logging.warning(text)
    print("Warning: %s" % text)


  def print_incoming_text(self):
    """

    When starting the connection, print all the debug data until
    we get to a line with the end sequence '$$$'.

    """
    line = ''
    #Wait for device to send data
    time.sleep(1)
    
    if self.ser.inWaiting():
      line = ''
      c = ''
     #Look for end sequence $$$
      while '$$$' not in line:
        c = self.ser.read().decode('utf-8')
        line += c
      print(line)
    else:
      self.warn("No Message")

  def BCIduino_id(self, serial):
    """

    When automatically detecting port, parse the serial
    return for the "BCIduino" ID.

    """
    line = ''
    #Wait for device to send data
    time.sleep(2)
    
    if serial.inWaiting():
      line = ''
      c = ''
     #Look for end sequence $$$
      while '$$$' not in line:
        c = serial.read().decode('utf-8')
        line += c
      if "BCIduino" in line:
        return True
    return False

  def print_register_settings(self):
    self.ser.write(b'?')
    time.sleep(0.5)
    self.print_incoming_text()
  #DEBBUGING: Prints individual incoming bytes
  def print_bytes_in(self):
    if not self.streaming:
      self.ser.write(b'b')
      self.streaming = True
    while self.streaming:
      self.c = struct.unpack('B',self.ser.read())[0]
      print(self.c)
      '''Incoming Packet Structure:
    Start Byte(1)|Sample ID(1)|Channel Data(24)|Aux Data(6)|End Byte(1)
    0xA0|0-255|8, 3-byte signed ints|3 2-byte signed ints|0xC0'''

  def print_packets_in(self):
    print ("csvdbjh")
    skipped_str = ''
    if not self.streaming:
      self.ser.write(b'b')
      self.streaming = True
      
    #while self.streaming:
    
    while self.streaming:
      #print "ing"
      data_ = []
      b = struct.unpack('B', self.ser.read())[0]
      data_.append(b)
      if b == START_BYTE:
        self.attempt_reconnect = False
        if skipped_str:
          logging.debug('SKIPPED\n' + skipped_str + '\nSKIPPED')
          skipped_str = ''

        packet_str = "%03d"%(b) + '|'
        b = struct.unpack('B', self.ser.read())[0]
        packet_str = packet_str + "%03d"%(b) + '|'
        data_.append(b)
        
        #data channels
        for i in range(24-1):
          b = struct.unpack('B', self.ser.read())[0]
          packet_str = packet_str + '.' + "%03d"%(b)
          data_.append(b)

        b = struct.unpack('B', self.ser.read())[0]
        packet_str = packet_str + '.' + "%03d"%(b) + '|'
        data_.append(b)
        
        #aux channels
        for i in range(6-1):
          b = struct.unpack('B', self.ser.read())[0]
          packet_str = packet_str + '.' + "%03d"%(b)
          data_.append(b)
          
        b = struct.unpack('B', self.ser.read())[0]
        packet_str = packet_str + '.' + "%03d"%(b) + '|'
        data_.append(b)

        #end byte
        b = struct.unpack('B', self.ser.read())[0]
        data_.append(b)
        #Valid Packet
        if b == END_BYTE:
          sample_count = data_[1]
          print('the',sample_count,'th sample')
          packet_str = packet_str + '.' + "%03d"%(b) + '|VAL'
          print("//packet///")
          print(packet_str)
          print("/channals//")
          #print("/channals//")
          dict1['channal1'] = data_[2]
          dict1['channal1'] <<= 8
          dict1['channal1'] |= data_[3]
          dict1['channal1'] <<= 8
          dict1['channal1'] |= data_[4]
          #dict1.get('ch1')

          dict1['channal2'] = data_[5]
          dict1['channal2'] <<= 8
          dict1['channal2'] |= data_[6]
          dict1['channal2'] <<= 8
          dict1['channal2'] |= data_[7]
          

          dict1['channal3'] = data_[8]
          dict1['channal3'] <<= 8
          dict1['channal3'] |= data_[9]
          dict1['channal3'] <<= 8
          dict1['channal3'] |= data_[10]
          
          dict1['channal4'] = data_[11]
          dict1['channal4'] <<= 8
          dict1['channal4'] |= data_[12]
          dict1['channal4'] <<= 8
          dict1['channal4'] |= data_[13]
          #channal1 <<= 8

          dict1['channal5'] = data_[14]
          dict1['channal5'] <<= 8
          dict1['channal5'] |= data_[15]
          dict1['channal5'] <<= 8
          dict1['channal5'] |= data_[16]
          #channal1 <<= 8

          dict1['channal6'] = data_[17]
          dict1['channal6'] <<= 8
          dict1['channal6'] |= data_[18]
          dict1['channal6'] <<= 8
          dict1['channal6'] |= data_[19]
          #channal1 <<= 8

          dict1['channal7'] = data_[20]
          dict1['channal7'] <<= 8
          dict1['channal7'] |= data_[21]
          dict1['channal7'] <<= 8
          dict1['channal7'] |= data_[22]
          #channal1 <<= 8

          dict1['channal8'] = data_[23]
          dict1['channal8'] <<= 8
          dict1['channal8'] |= data_[24]
          dict1['channal8'] <<= 8
          dict1['channal8'] |= data_[25]


          dict1['refer1'] = data_[26]
          dict1['refer1'] <<= 8
          dict1['refer1'] |= data_[27]
          dict1['refer1'] <<= 8
          dict1['refer1'] |= data_[28]

          dict1['refer2'] = data_[29]
          dict1['refer2'] <<= 8
          dict1['refer2'] |= data_[30]
          dict1['refer2'] <<= 8
          dict1['refer2'] |= data_[31]

          #for each in data_:
            #print each
            
          print('channal1 =',dict1.get('channal1'))
          print('channal2 =',dict1.get('channal2'))
          print('channal3 =',dict1.get('channal3'))
          print('channal4 =',dict1.get('channal4'))
          print('channal5 =',dict1.get('channal5'))
          print('channal6 =',dict1.get('channal6'))
          print('channal7 =',dict1.get('channal7'))
          print('channal8 =',dict1.get('channal8'))
          print('refer1 =',dict1.get('refer1'))
          print('refer2 =',dict1.get('refer2'))
         
        #Invalid Packet
        else:
          packet_str = packet_str + '.' + "%03d"%(b) + '|INV'
          #Reset
          self.attempt_reconnect = True
          
      
      else:
        print(b)
        if b == END_BYTE:
          skipped_str = skipped_str + '|END|'
        else:
          skipped_str = skipped_str + "%03d"%(b) + '.'

      
      
      if self.attempt_reconnect and (timeit.default_timer()-self.last_reconnect) > self.reconnect_freq:
        self.last_reconnect = timeit.default_timer()
        self.warn('Reconnecting')
        self.reconnect()
     
       
    print ("stop le") 


  def check_connection(self, interval = 2, max_packets_to_skip=10):
    #check number of dropped packages and establish connection problem if too large
    if self.packets_dropped > max_packets_to_skip:
      #if error, attempt to reconect
      self.reconnect()
    # check again again in 2 seconds
    threading.Timer(interval, self.check_connection).start()

  def reconnect(self):
    self.packets_dropped = 0
    self.warn('Reconnecting')
    self.stop()
    time.sleep(0.5)
    self.ser.write(b'v')
    time.sleep(0.5)
    self.ser.write(b'b')
    time.sleep(0.5)
    self.streaming = True
    #self.attempt_reconnect = False


  #Adds a filter at 60hz to cancel out ambient electrical noise
  def enable_filters(self):
    self.ser.write(b'f')
    self.filtering_data = True

  def disable_filters(self):
    self.ser.write(b'g')
    self.filtering_data = False

  def test_signal(self, signal):
    if signal == 0:
      self.ser.write(b'0')
      self.warn("Connecting all pins to ground")
    elif signal == 1:
      self.ser.write(b'p')
      self.warn("Connecting all pins to Vcc")
    elif signal == 2:
      self.ser.write(b'-')
      self.warn("Connecting pins to low frequency 1x amp signal")
    elif signal == 3:
      self.ser.write(b'=')
      self.warn("Connecting pins to high frequency 1x amp signal")
    elif signal == 4:
      self.ser.write(b'[')
      self.warn("Connecting pins to low frequency 2x amp signal")
    elif signal == 5:
      self.ser.write(b']')
      self.warn("Connecting pins to high frequency 2x amp signal")
    else:
      self.warn("%s is not a known test signal. Valid signals go from 0-5" %(signal))

  def set_channel(self, channel, toggle_position):
    #Commands to set toggle to on position
    if toggle_position == 1:
      if channel is 1:
        self.ser.write(b'!')
      if channel is 2:
        self.ser.write(b'@')
      if channel is 3:
        self.ser.write(b'#')
      if channel is 4:
        self.ser.write(b'$')
      if channel is 5:
        self.ser.write(b'%')
      if channel is 6:
        self.ser.write(b'^')
      if channel is 7:
        self.ser.write(b'&')
      if channel is 8:
        self.ser.write(b'*')
      if channel is 9 and self.daisy:
        self.ser.write(b'Q')
      if channel is 10 and self.daisy:
        self.ser.write(b'W')
      if channel is 11 and self.daisy:
        self.ser.write(b'E')
      if channel is 12 and self.daisy:
        self.ser.write(b'R')
      if channel is 13 and self.daisy:
        self.ser.write(b'T')
      if channel is 14 and self.daisy:
        self.ser.write(b'Y')
      if channel is 15 and self.daisy:
        self.ser.write(b'U')
      if channel is 16 and self.daisy:
        self.ser.write(b'I')
    #Commands to set toggle to off position
    elif toggle_position == 0:
      if channel is 1:
        self.ser.write(b'1')
      if channel is 2:
        self.ser.write(b'2')
      if channel is 3:
        self.ser.write(b'3')
      if channel is 4:
        self.ser.write(b'4')
      if channel is 5:
        self.ser.write(b'5')
      if channel is 6:
        self.ser.write(b'6')
      if channel is 7:
        self.ser.write(b'7')
      if channel is 8:
        self.ser.write(b'8')
      if channel is 9 and self.daisy:
        self.ser.write(b'q')
      if channel is 10 and self.daisy:
        self.ser.write(b'w')
      if channel is 11 and self.daisy:
        self.ser.write(b'e')
      if channel is 12 and self.daisy:
        self.ser.write(b'r')
      if channel is 13 and self.daisy:
        self.ser.write(b't')
      if channel is 14 and self.daisy:
        self.ser.write(b'y')
      if channel is 15 and self.daisy:
        self.ser.write(b'u')
      if channel is 16 and self.daisy:
        self.ser.write(b'i')
  
  def find_port(self):
    # Finds the serial port names
    if sys.platform.startswith('win'):
      ports = ['COM%s' % (i+1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
      ports = glob.glob('/dev/ttyUSB*')
    elif sys.platform.startswith('darwin'):
      ports = glob.glob('/dev/tty.usbserial*')
    else:
      raise EnvironmentError('Error finding ports on your operating system')
    BCIduino_port = ''
    for port in ports:
      try:
        s = serial.Serial(port= port, baudrate = self.baudrate, timeout=self.timeout)
        s.write(b'v')
        BCIduino_serial = self.BCIduino_id(s)
        s.close()
        if BCIduino_serial:
          BCIduino_port = port
      except (OSError, serial.SerialException):
        pass
    if BCIduino_port == '':
      raise OSError('Cannot find BCIduino port')
    else:
      return BCIduino_port

class StreamerLSL():
    
    def __init__(self,daisy=False):
        parser = argparse.ArgumentParser(description="BCIduino 'user'")
        parser.add_argument('-p', '--port',
                        help="Port to connect to BCIduino Dongle " +
                        "( ex /dev/ttyUSB0 or /dev/tty.usbserial-* )")
        parser.add_argument('-d', action="store_true",
                        help="Enable Daisy Module " +
                        "-d")
        args = parser.parse_args()
        port = args.port
        print ("\n-------INSTANTIATING BOARD-------")
        self.board = BCIduinoBoard(port, daisy=args.d)
        self.eeg_channels = self.board.getNbEEGChannels()
        self.sample_rate = self.board.getSampleRate()
        print('{} EEG channels at {} Hz'.format(self.eeg_channels,self.sample_rate))

    def send(self,sample):
        data = sample.channel_data
        #print ( data )
        self.outlet_eeg.push_sample(data)

    def create_lsl(self):
        info_eeg = StreamInfo("BCIduino", 'EEG', self.eeg_channels, self.sample_rate, 'float32', "BCIduino_EXG")
        self.outlet_eeg = StreamOutlet(info_eeg)

    def cleanUp():
        board.disconnect()
        print ("Disconnecting...")
        atexit.register(cleanUp)

    def begin(self):
        print ("--------------INFO---------------")
        print ("User serial interface enabled...\n" + \
            "View command map at http://docs.BCIduino.com.\n" + \
            "Type /start to run -- and /stop before issuing new commands afterwards.\n" + \
            "Type /exit to exit. \n" + \
            "Board outputs are automatically printed as: \n" +  \
            "%    message\n" + \
            "$$$ signals end of message")
        print("\n-------------BEGIN---------------")
        # Init board state
        # s: stop board streaming; v: soft reset of the 32-bit board (no effect with 8bit board)
        s = 'sv'
        # Tell the board to enable or not daisy module
        print(self.board.daisy)
        if self.board.daisy:
            s = s + 'C'
        else:
            s = s + 'c'
        # d: Channels settings back to default
        s = s + 'd'

        while(s != "/exit"):
            # Send char and wait for registers to set
            if (not s):
                pass
            elif("help" in s):
                print ("View command map at:" + \
                    "http://docs.BCIduino.com/software/01-BCIduino_SDK.\n" +\
                    "For user interface: read README or view" + \
                    "https://github.com/BCIduino/BCIduino_Python")

            elif self.board.streaming and s != "/stop":
                print ("Error: the board is currently streaming data, please type '/stop' before issuing new commands.")
            else:
                # read silently incoming packet if set (used when stream is stopped)
                flush = False

                #if('/' == s[0]):
                if(True):
                    s = s[1:]
                    rec = False  # current command is recognized or fot

                    if("T:" in s):
                        lapse = int(s[string.find(s, "T:")+2:])
                        rec = True
                    elif("t:" in s):
                        lapse = int(s[string.find(s, "t:")+2:])
                        rec = True
                    else:
                        lapse = -1

                    #if("start" in s):
                    if(True):
                        # start streaming in a separate thread so we could always send commands in here 
                        boardThread = threading.Thread(target=self.board.start_streaming,args=(self.send,-1))
                        boardThread.daemon = True # will stop on exit
                        try:
                            boardThread.start()
                            print("Streaming data...")
                        except:
                                raise
                        rec = True
                    elif('test' in s):
                        test = int(s[s.find("test")+4:])
                        self.board.test_signal(test)
                        rec = True
                    elif('stop' in s):
                        self.board.stop()
                        rec = True
                        flush = True
                    if rec == False:
                        print("Command not recognized...")

                elif s:
                    for c in s:
                        if sys.hexversion > 0x03000000:
                            self.board.ser.write(bytes(c, 'utf-8'))
                        else:
                            self.board.ser.write(bytes(c))
                        time.sleep(0.100)

                line = ''
                time.sleep(0.1) #Wait to see if the board has anything to report
                while self.board.ser.inWaiting():
                    c = self.board.ser.read().decode('utf-8', errors='replace')
                    line += c
                    time.sleep(0.001)
                    if (c == '\n') and not flush:
                        # print('%\t'+line[:-1])
                        line = ''

                if not flush:
                    print(line)

            # Take user input
            #s = input('--> ')
            if sys.hexversion > 0x03000000:
                s = input('--> ')
            else:
                s = raw_input('--> ')

def main():
    lsl = StreamerLSL()
    lsl.create_lsl()
    lsl.begin()

if __name__ == '__main__':
    main()

#本篇由BCIduino脑机接口开源社区原创/转载(公众号“BCIduino脑机接口社区”)。BCIduino脑机接口社区由来自北京航空航天大学、康奈尔大学、北京大学、首都医科大学等硕博发起成立,欢迎扫下面码加入社群,也欢迎采购BCIduino脑电模块和外骨骼等(某宝搜索即可或者扫码详询)。

BCIduino社区|基于python获取BCIduino脑电数据_第1张图片

你可能感兴趣的:(脑机接口,BCI,EEG)