Skip to content

Commit 4bccb54

Browse files
committed
Merge pull request #1 from zheng1i/master
Contact quality and battery level
2 parents 08ab3a2 + 67ed240 commit 4bccb54

File tree

5 files changed

+258
-16
lines changed

5 files changed

+258
-16
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ INCLUDE_DIRECTORIES(${HIDAPI_INCLUDE_DIR} ${Mcrypt_INCLUDE_DIR} ${CMAKE_SOURCE_D
2424

2525
ADD_SUBDIRECTORY(src)
2626
ADD_SUBDIRECTORY(examples/emokitd)
27+
ADD_SUBDIRECTORY(examples/contact)
2728
# ADD_SUBDIRECTORY(examples/emokit_osc)
2829

2930
##########################################

examples/contact/CMakeLists.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
##################################################
2+
# epoc contact #
3+
##################################################
4+
5+
add_executable (contact contact.c)
6+
ADD_DEPENDENCIES(contact emokit)
7+
target_link_libraries (contact emokit ${LIBS})
8+
9+
SET_TARGET_PROPERTIES(contact PROPERTIES
10+
INSTALL_RPATH_USE_LINK_PATH TRUE
11+
INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib
12+
BUILD_WITH_INSTALL_RPATH TRUE )
13+
14+
INSTALL (TARGETS contact
15+
RUNTIME DESTINATION bin
16+
)

examples/contact/contact.c

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
3+
Get real-time contact quality readings
4+
5+
*/
6+
7+
#include <stdio.h>
8+
#include <string.h>
9+
#include <signal.h>
10+
#include "emokit/emokit.h"
11+
12+
int quit;
13+
void cleanup(int i){
14+
fprintf(stdout,"Shutting down\n");
15+
quit=1;
16+
}
17+
18+
int main(int argc, char **argv)
19+
{
20+
struct emokit_device* d;
21+
signal(SIGINT, cleanup); //trap cntrl c
22+
23+
24+
quit=0;
25+
26+
d = emokit_create();
27+
int count=emokit_get_count(d, EMOKIT_VID, EMOKIT_PID);
28+
printf("Current epoc devices connected: %d\n", count );
29+
int r = emokit_open(d, EMOKIT_VID, EMOKIT_PID, 1);
30+
if(r != 0)
31+
{
32+
emokit_close(d);
33+
emokit_delete(d);
34+
d = emokit_create();
35+
r = emokit_open(d, EMOKIT_VID, EMOKIT_PID, 0);
36+
if (r!=0) {
37+
printf("CANNOT CONNECT: %d\n", r);
38+
return 1;
39+
}
40+
}
41+
printf("Connected to headset.\n");
42+
43+
if (emokit_read_data(d)<=0) {
44+
printf("Error reading from headset\n");
45+
emokit_close(d);
46+
emokit_delete(d);
47+
return 1;
48+
}
49+
50+
struct emokit_frame c;
51+
while (!quit) {
52+
if(emokit_read_data(d) > 0) {
53+
c = emokit_get_next_frame(d);
54+
fprintf(stdout,"\033[H\033[2JPress CTRL+C to exit\n\nContact quality:\nF3 %4d\nFC6 %4d\nP7 %4d\nT8 %4d\nF7 %4d\nF8 %4d\nT7 %4d\nP8 %4d\nAF4 %4d\nF4 %4d\nAF3 %4d\nO2 %4d\nO1 %4d\nFC5 %4d",c.cq.F3, c.cq.FC6, c.cq.P7, c.cq.T8,c.cq.F7, c.cq.F8, c.cq.T7, c.cq.P8, c.cq.AF4, c.cq.F4, c.cq.AF3, c.cq.O2, c.cq.O1, c.cq.FC5);
55+
fflush(stdout);
56+
}
57+
}
58+
emokit_close(d);
59+
emokit_delete(d);
60+
return 0;
61+
}
62+

include/emokit/emokit.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ const static uint32_t EMOKIT_OUT_ENDPT = 0x02;
3838
/// In endpoint for all emotiv devices
3939
const static uint32_t EMOKIT_IN_ENDPT = 0x82;
4040

41-
struct emokit_contact_quality {
42-
char F3, FC6, P7, T8, F7, F8, T7, P8, AF4, F4, AF3, O2, O1, FC5;
41+
struct emokit_contact_quality {//values > 4000 are good
42+
short F3, FC6, P7, T8, F7, F8, T7, P8, AF4, F4, AF3, O2, O1, FC5;
4343
};
4444

4545
struct emokit_frame {
46-
char counter;
47-
int F3, FC6, P7, T8, F7, F8, T7, P8, AF4, F4, AF3, O2, O1, FC5;
46+
unsigned char counter; //loops from 0 to 128 (129 values)
47+
int F3, FC6, P7, T8, F7, F8, T7, P8, AF4, F4, AF3, O2, O1, FC5; //raw data values
4848
struct emokit_contact_quality cq;
4949
char gyroX, gyroY;
50-
char battery;
50+
unsigned char battery; //percentage of full charge, read on counter=128
5151
};
5252

5353

src/emokit.c

+174-11
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const unsigned char AF3_MASK[14] = {46, 47, 32, 33, 34, 35, 36, 37, 38, 39, 24,
4848
const unsigned char O2_MASK[14] = {140, 141, 142, 143, 128, 129, 130, 131, 132, 133, 134, 135, 120, 121};
4949
const unsigned char O1_MASK[14] = {102, 103, 88, 89, 90, 91, 92, 93, 94, 95, 80, 81, 82, 83};
5050
const unsigned char FC5_MASK[14] = {28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23, 8, 9};
51-
51+
const unsigned char QUALITY_MASK[14]={99,100,101,102,103,104,105,106,107,108,109,110,111,112};
5252
struct emokit_device {
5353
hid_device* _dev;
5454
wchar_t serial[MAX_STR]; // USB Dongle serial number
@@ -61,11 +61,14 @@ struct emokit_device {
6161
struct emokit_frame current_frame; // Last information received from headset
6262
unsigned char raw_frame[32]; // Raw encrypted data received from headset
6363
unsigned char raw_unenc_frame[32]; // Raw unencrypted data received from headset
64+
unsigned char last_battery; //last reported battery value, in percentage of full
65+
struct emokit_contact_quality last_quality; //last reported contact quality
6466
};
6567

6668
struct emokit_device* emokit_create()
6769
{
6870
struct emokit_device* s = (struct emokit_device*)malloc(sizeof(struct emokit_device));
71+
memset(s,0,sizeof(struct emokit_device));
6972
s->_is_open = 0;
7073
s->_is_inited = 0;
7174
hid_init();
@@ -99,7 +102,7 @@ int emokit_identify_device(hid_device *dev) {
99102
/* currently we check to see if the feature report matches the consumer
100103
model and if not we assume it's a research model.*/
101104
int nbytes, i, dev_type = EMOKIT_CONSUMER;
102-
char buf[EMOKIT_REPORT_SIZE];
105+
unsigned char buf[EMOKIT_REPORT_SIZE];
103106
char report_consumer[] = {0x00, 0xa0, 0xff, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00};
104107
buf[0] = EMOKIT_REPORT_ID;
105108
nbytes = hid_get_feature_report(dev, buf, sizeof(buf));
@@ -123,7 +126,7 @@ EMOKIT_DECLSPEC int emokit_init_crypto(struct emokit_device* s, int dev_type) {
123126
s->td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, NULL, MCRYPT_ECB, NULL);
124127
s->blocksize = mcrypt_enc_get_block_size(s->td); //should return a 16bits blocksize
125128

126-
s->block_buffer = malloc(s->blocksize);
129+
s->block_buffer = (unsigned char *)malloc(s->blocksize);
127130

128131
mcrypt_generic_init(s->td, s->key, EMOKIT_KEYSIZE, NULL);
129132
return 0;
@@ -184,7 +187,7 @@ void emokit_get_crypto_key(struct emokit_device* s, int dev_type) {
184187
int i;
185188
unsigned int l = 16;
186189
type &= 0xF;
187-
type = (type != 0);
190+
type = (type == 0);
188191

189192
s->key[0] = (uint8_t)s->serial[l-1];
190193
s->key[1] = '\0';
@@ -230,7 +233,7 @@ int get_level(unsigned char frame[32], const unsigned char bits[14]) {
230233

231234
for (i = 13; i >= 0; --i) {
232235
level <<= 1;
233-
b = (bits[i] / 8) + 1;
236+
b = (bits[i] >> 3) + 1;
234237
o = bits[i] % 8;
235238

236239
level |= (frame[b] >> o) & 1;
@@ -240,33 +243,191 @@ int get_level(unsigned char frame[32], const unsigned char bits[14]) {
240243

241244
EMOKIT_DECLSPEC int emokit_get_next_raw(struct emokit_device* s) {
242245
//Two blocks of 16 bytes must be read.
243-
int i;
244246

245247
if (memcpy (s->block_buffer, s->raw_frame, s->blocksize)) {
246248
mdecrypt_generic (s->td, s->block_buffer, s->blocksize);
247-
memcpy(s->raw_unenc_frame, s->block_buffer, 16);
249+
memcpy(s->raw_unenc_frame, s->block_buffer, s->blocksize);
248250
}
249251
else {
250252
return -1;
251253
}
252254

253255
if (memcpy(s->block_buffer, s->raw_frame + s->blocksize, s->blocksize)) {
254256
mdecrypt_generic (s->td, s->block_buffer, s->blocksize);
255-
memcpy(s->raw_unenc_frame + 16, s->block_buffer, 16);
257+
memcpy(s->raw_unenc_frame + s->blocksize, s->block_buffer, s->blocksize);
256258
}
257259
else {
258260
return -1;
259261
}
260262
return 0;
261263
}
262264

265+
266+
//returns the percentage battery value given the unencrypted report value
267+
EMOKIT_DECLSPEC unsigned char battery_value(unsigned char in) {
268+
269+
if (in>=248) return 100;
270+
else {
271+
switch(in) {
272+
case 247:return 99; break;
273+
case 246:return 97; break;
274+
case 245:return 93; break;
275+
case 244:return 89; break;
276+
case 243:return 85; break;
277+
case 242:return 82; break;
278+
case 241:return 77; break;
279+
case 240:return 72; break;
280+
case 239:return 66; break;
281+
case 238:return 62; break;
282+
case 237:return 55; break;
283+
case 236:return 46; break;
284+
case 235:return 32; break;
285+
case 234:return 20; break;
286+
case 233:return 12; break;
287+
case 232:return 6; break;
288+
case 231:return 4 ; break;
289+
case 230:return 3; break;
290+
case 229:return 2; break;
291+
case 228:
292+
case 227:
293+
case 226:
294+
return 1;
295+
break;
296+
default:
297+
return 0;
298+
}
299+
}
300+
}
301+
302+
//decode and update the s->last_quality, return s->last_quality
303+
EMOKIT_DECLSPEC struct emokit_contact_quality handle_quality(struct emokit_device* s) {
304+
int current_contact_quality=get_level(s->raw_unenc_frame,QUALITY_MASK);
305+
switch(s->raw_unenc_frame[0]) {
306+
case 0:
307+
s->last_quality.F3=current_contact_quality;
308+
break;
309+
case 1:
310+
s->last_quality.FC5=current_contact_quality;
311+
break;
312+
case 2:
313+
s->last_quality.AF3=current_contact_quality;
314+
break;
315+
case 3:
316+
s->last_quality.F7=current_contact_quality;
317+
break;
318+
case 4:
319+
s->last_quality.T7=current_contact_quality;
320+
break;
321+
case 5:
322+
s->last_quality.P7=current_contact_quality;
323+
break;
324+
case 6:
325+
s->last_quality.O1=current_contact_quality;
326+
break;
327+
case 7:
328+
s->last_quality.O2=current_contact_quality;
329+
break;
330+
case 8:
331+
s->last_quality.P8=current_contact_quality;
332+
break;
333+
case 9:
334+
s->last_quality.T8=current_contact_quality;
335+
break;
336+
case 10:
337+
s->last_quality.F8=current_contact_quality;
338+
break;
339+
case 11:
340+
s->last_quality.AF4=current_contact_quality;
341+
break;
342+
case 12:
343+
s->last_quality.FC6=current_contact_quality;
344+
break;
345+
case 13:
346+
s->last_quality.F4=current_contact_quality;
347+
break;
348+
case 14:
349+
s->last_quality.F8=current_contact_quality;
350+
break;
351+
case 15:
352+
s->last_quality.AF4=current_contact_quality;
353+
break;
354+
case 64:
355+
s->last_quality.F3=current_contact_quality;
356+
break;
357+
case 65:
358+
s->last_quality.FC5=current_contact_quality;
359+
break;
360+
case 66:
361+
s->last_quality.AF3=current_contact_quality;
362+
break;
363+
case 67:
364+
s->last_quality.F7=current_contact_quality;
365+
break;
366+
case 68:
367+
s->last_quality.T7=current_contact_quality;
368+
break;
369+
case 69:
370+
s->last_quality.P7=current_contact_quality;
371+
break;
372+
case 70:
373+
s->last_quality.O1=current_contact_quality;
374+
break;
375+
case 71:
376+
s->last_quality.O2=current_contact_quality;
377+
break;
378+
case 72:
379+
s->last_quality.P8=current_contact_quality;
380+
break;
381+
case 73:
382+
s->last_quality.T8=current_contact_quality;
383+
break;
384+
case 74:
385+
s->last_quality.F8=current_contact_quality;
386+
break;
387+
case 75:
388+
s->last_quality.AF4=current_contact_quality;
389+
break;
390+
case 76:
391+
s->last_quality.FC6=current_contact_quality;
392+
break;
393+
case 77:
394+
s->last_quality.F4=current_contact_quality;
395+
break;
396+
case 78:
397+
s->last_quality.F8=current_contact_quality;
398+
break;
399+
case 79:
400+
s->last_quality.AF4=current_contact_quality;
401+
break;
402+
case 80:
403+
s->last_quality.FC6=current_contact_quality;
404+
break;
405+
default:
406+
break;
407+
}
408+
return (s->last_quality);
409+
}
410+
411+
263412
EMOKIT_DECLSPEC
264413
struct emokit_frame emokit_get_next_frame(struct emokit_device* s) {
265414
struct emokit_frame k;
266415
memset(s->raw_unenc_frame, 0, 32);
267-
emokit_get_next_raw(s);
268416

269-
k.counter = s->raw_unenc_frame[0];
417+
if (emokit_get_next_raw(s)<0) {
418+
k.counter=0;
419+
return k;
420+
}
421+
422+
memset(&k.cq,0,sizeof(struct emokit_contact_quality));
423+
if (s->raw_unenc_frame[0] & 128) {
424+
k.counter = 128;
425+
k.battery = battery_value( s->raw_unenc_frame[0] );
426+
s->last_battery=k.battery;
427+
} else {
428+
k.counter = s->raw_unenc_frame[0];
429+
k.battery = s->last_battery;
430+
}
270431
k.F3 = get_level(s->raw_unenc_frame, F3_MASK);
271432
k.FC6 = get_level(s->raw_unenc_frame, FC6_MASK);
272433
k.P7 = get_level(s->raw_unenc_frame, P7_MASK);
@@ -285,7 +446,9 @@ struct emokit_frame emokit_get_next_frame(struct emokit_device* s) {
285446
k.gyroX = s->raw_unenc_frame[29] - 102;
286447
k.gyroY = s->raw_unenc_frame[30] - 104;
287448

288-
k.battery = 0;
449+
k.cq=handle_quality(s);
450+
//memcpy(k.unenc,s->raw_unenc_frame,32);
451+
289452
return k;
290453
}
291454

0 commit comments

Comments
 (0)