I am working on the implementation of the serial driver of the EEG (time-series acquisition device). The device encodes the data with 12bits x 26 total channels with a sampling rate of 200Hz
The serial data stream consists of signalling byte 0xA0 followed by 45 bytes that carry the data for 26 channels, each encoded with 12bits.
But here is the catch, these 12bits are not in fixed positions in the 45byte block. The first byes use only 4 LSB, whilst the rest 44 7 LSB.
To make this more illustrative I will try to represent it graphically below. Suppose that we have started the amplifier and it always gives us 4095 (max int value represented with 12bits) for all channels (so we have all "ones" for the data), then we have something like this:
a0 0f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f a0 next sample...
This has to be mapped to the int(1,...,26) with values 4095.
So, I made a python code, that first finds the beginning of the block, then it saves everything in one int/long, then I removed the bits on fixed positions, append 8 most significant 0 bits to make a 16bit representation and convert the byte array to a list of integers.
That works fine, but the problem is the speed. Seems that the code takes a considering amount of time for a single sample and it has to do it 200 times in one second. Let's include some other delays of the real serial read methods, everything has to stay much below 1sec for all 200 samples
#Python code
def readByte():
#mockup
return 0xA0
def read45bytes():
return int(0x0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f)
def remove_bit(num, i):
mask = num >> (i + 1)
mask = mask << i
right = ((1 << i) - 1) & num
return mask | right
def insert_mult_bits(num, bits, len, i):
mask = num >> i
mask = (mask << len) | bits
mask = mask << i
right = ((1 << i) - 1) & num
return right | mask
def main():
while(readByte()!=0xA0):
print("Searching for the beginning of the packet of 45 bytes...")
print("Beginning of the packet of 45 bytes found")
#read whole sample
sample=read45bytes()
#remove unused bits
corr=0;
for i in range(7, sample.bit_length(), 8):
sample=remove_bit(sample,i-corr);
corr=corr+1;
#add HSB to make 2byte representation
corr=0;
for i in range(12,sample.bit_length(),12):
sample=insert_mult_bits(sample,0,4,i+corr)
corr=corr+4;
#convert to bytes 26channels x 2 bytes, bigendian
bt=sample.to_bytes(26*2,'big');
#assign the result to int list
idx=0;
out=[];
for i in range(0,26*2-1,2):
out.append(int(int((bt[i]<<8 | bt[i+1]))))
idx=idx+1;
#print first sample of the channel 1
print(out.pop(0))