Open ghost opened 7 years ago
hmmm, I just did that the hard way, I am going to upload a little more in a moment.
don't quote me on that, i may have done that wrong.. remembered having a heck of a time with big endian last time.
yeah, from the looks of it.... when it stores the Epoc CSV, it is storing it in the plain integer format.
but when it stores the Epoc+ data.... i'm pretty sure it stores it in the BIg-Endian format. When I created a version of Cykit to work with OpenVibe, to stream it to its TCP writer... i had to send it in a continuous stream in big-endian format.
i think its probably more data efficient, and thats probably their standard.
medical grade eeg probably has more sensitivity, so they probably uses floats as well.
its a pain in the butt understanding how python works with big endian, lol i think it took me like a week to grasp it, plus i was learning python 3 at the time.
in theory, my cykit should have a big endian setup.. at least for the conversion -to- big-endian.
https://github.com/CymatiCorp/CyKit/blob/master/Openvibe-Readme.md
perhaps that will help.... as you can see... openvibe lets you select settings on what type of format the raw data is in.
in my case.... i used Big-Endian 16-bit SIGNED integer.
so it was in big-endian format, but was an integer.
so i'm thinking for Epoc+ it will probably be... a Big-Endian 16-bit SIGNED float
The struct module has it builtin
Ok, I just made a file running the epoc+ along with the emokit running. I moved the headset around. Where do you want the data? The CSV is to big to post here.
pastebin?
cy = ""
values = [packet.sensors[name]['value'] for name in 'AF3 F7 F3 FC5 T7 P7 O1 O2 P8 T8 FC6 F4 F8 AF4'.split(' ')]
cy = struct.pack('>' + str(len(values)) + 'h',*values)
https://docs.python.org/2/library/struct.html
So > indicates the endianness, in this case, that would be for big.
It shows here though that... a float is 4 bytes long.... which might complicate things. we either have to convert the two groups, together..... or separately.
Well isnt this nice, the CSV seperates the motion from the EEG.
Ok, lets think about the data you have. Given the fact that the data is in 2 separate files, you would have 2 feeds. 1 feed at 256samples, and 1 feed at 128 samples. So 2 counters.
Makes sense.
Well at least I understand this output a little better. Now I am trying to figure out what the 2 of you are talking about.
These values in the emokit decrypted CSV, what's there base?
its base 10, but i believe in its big-endian format. you might have to do some reading up on that. its kind of a confusing format. lol basically binary in reverse.
Bill, i tried running it through OpenVibe, as it is capable of reading several different formats, didn't have much luck.
will have to try again later though...
<---- Started off learning Assembly. I am trying to dig into 20 year old memories of endian and conversions.
big endian can contain multiple bytes, it strings together, reversed binary data. think thats how it works. basically its all reversed binary and concatenated.
like bill said, python contains some methods for it built into struct. though it was confusing for me, with all the changes in unicode they did, for python 3.
got to use google on this one.
plus i think it will require a lot of python experimentation... i recommend using python from the command line on this one, and just typing in instructions... but we'll need some kind of guide... like we need to know what the values are supposed to be.
I am working on a script to take the results in the zip i posted and look for the hex equivalent of a number. Just to see if it is in there. No matter how the number is created, it will always have the same hex bytes.
The gyro is 2048 at 0 I believe.
All the available data is being collected right?
?
I believe so you can try increase the read size to see if there's more.
I think I just had a light blub moment though.
I am not looking at the data ... and i am not looking at it at this moment... but a float is 4 hex values. When you divide the column count by 4 you do not get 14 channels.
Also, there seems to be an internal clock that transmits with the data.
Maybe even 2 timers that start when the head set is powered on.
one of those characters is a byte, 8bits in a byte, two bytes per sensor=16bits, 32 bytes in the data stream.
But we may have to do the same shifting thing because of the counter.
The gyro data doesn't move very much either 2048-52 quickly glancing over the data.
The values we observe also only move one 104-110 when moving the gyro.
My point is we need to find the conversion for chr(104) -> 2048.00
and then artificially increment 104 and the conversion counts up 2049 and so on..
er 106 and 105 rather it should be noted that they are one byte position apart and the 0 value or 2048 is the same.
They are also at indexes 29(106) and 30(105).
maybe we need to use bit masks 8 * the byte index? 232,233,234,235,236,237,238,239
240,241,242,243,244,245,246,247
I was reading the half precision float standard.
The answer maybe in the wiki article.
I figured it out I'm pretty sure.
Where do I modify the python to check if there is more data
This version will attempt to read more automatically, I'm pretty sure it'll still return 32 bytes though.
Also, has all my scratch code I was using trying to find the values.
I'm pretty sure it turns out they store 4 sets of shorts, then you have to do math. Like @warrenarea said big endian.
They share the most significant bits which subtract to 256 * 8 to shift the byte and subtract the least significant bits then add them together.
Hmm maybe not.
ok
Looking at the bits in the sensor values is interesting though: ['0', '1', '1', '1', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1'] ['0', '1', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0', '0', '1'] ['0', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '0', '1', '0'] ['0', '1', '1', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '1'] ['0', '1', '1', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0'] ['0', '1', '1', '1', '1', '1', '0', '0', '0', '1', '1', '0', '0', '0'] ['0', '1', '1', '1', '1', '1', '0', '0', '1', '0', '0', '1', '1', '1'] ['0', '1', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1', '1'] ['0', '1', '1', '1', '1', '1', '0', '1', '1', '0', '0', '0', '0', '0'] ['0', '1', '1', '1', '1', '1', '1', '0', '0', '0', '0', '0', '0', '0'] ['1', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '0', '0', '1'] ['0', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '0'] ['0', '1', '1', '1', '1', '1', '1', '1', '0', '0', '1', '1', '1', '0'] ['0', '1', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0'] ['0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0']
And here I am trying to unplug from the matrix...
8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 '0', '1', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0'
8022 * 0.51
4091.22
and .13 for epoc+?
yeah with two bits added, the math works better if multiplied by .13
All headsets should return floating point sensor levels.