オムロンのOKAO Vision HVC-C1BとBLE通信します。

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_ButtonSense by Bluetooth Low Energy

オムロン OKAO Vision(ヒューマンビジョンコンポ)HVC-C1BとRedBearLab nRF51822 mbedでBLE通信を行うサンプルです。

HVC-C1Bは、人、手、顔、性別、年齢、表情、顔の向き、視線、目の閉じを推定し、値を返してくれます。 http://plus-sensing.omron.co.jp/egg-project/

main.cppの最初の定義の部分(IDや欲しい項目)を変更すると使えます。 欲しい項目を1に要らない項目は0にしてください。

タイムアウトの処理が入っていませんが、もし入れたい場合は、LEDのHartBeatの処理に追加すれば簡単に出来ると思います。

下記のような感じでメッセージが帰ってきます。

#Look at HVC-C1B peerAddr[d5 32 26 3b 47 3d] rssi -76, isScanResponse 0, AdvertisementType 0
# St#HVC-C1B Connect
#SCAN Stop
ate 1 Wait for Caracteristic Found
#short:
#  C UUID-2a00 valueAttr[3] props[0]
#short:
#  C UUID-2a01 valueAttr[5] props[0]
#short:
#  C UUID-2a04 valueAttr[7] props[0]
#short:
#  C UUID-2a05 valueAttr[10] props[0]
#long:
#  C UUID-35100003d13a4f398ab3bf64d4fbb4b4 valueAttr[14] props[0]
#HVCNotifyCharacteristic Found
#long:
#  C UUID-35100002d13a4f398ab3bf64d4fbb4b4 valueAttr[17] props[0]
#HVCWriteCharacteristic Found
#long:
#  C UUID-35100004d13a4f398ab3bf64d4fbb4b4 valueAttr[19] props[0]
#HVCDeviceCharacteristic Found
# discovery terminated CallBack 0
# State 2 Notify Enable
#send data 1
#State=2 Wited
# State3 kidoukakunin
#send data 1
#received HVX callback for handle 14; type notification
#received HVX callback for handle 14; type notification
# State3 HVC-C1B      1 1 0 96090000
# State4 DataSending
#send data 1
#received HVX callback for handle 14; type notification
#received HVX callback for handle 14; type notification
#received HVX callback for handle 14; type notification
HumanDetect:1
Human(0):x=199,y=251,size=330,depend=774
HandDetect:0
FaceDetect:1
Face(0):x=227,y=230,size=158,depend=670
FaceDirection(0):holizon=20,vertical=0,angle=15,depend=120
FaceOld(0):old=64,depend=333
FaceSex(0):Sex=0,depend=111
FaceLook(0):holizon=-2,vertical=-2
FaceEyeClose(0):xleft=229,right=326
FaceExpression(0):TopExpression=5,TopScore=46,look=-74
# State4 DataSending
#send data 1

Revision:
1:e4ee755844de
Parent:
0:2dec89c76f68
Child:
2:b94ca9b44b80
--- a/main.cpp	Mon Jul 06 09:30:41 2015 +0000
+++ b/main.cpp	Sun Jul 19 13:20:06 2015 +0000
@@ -21,100 +21,221 @@
 
 #include "ble_gatt.h"
 
+char HVC_ADDRESS[]= {0xd5,0x32,0x26,0x3b,0x47,0x3d};
 BLE ble;
+Serial pc(USBTX, USBRX);
 
 Gap::Handle_t connectionHandle = 0xFFFF;
 
 DigitalOut alivenessLED(LED1, 1);
-bool foundButtonCharacteristic = false;
-DiscoveredCharacteristic buttonCharacteristic;
+bool foundHVCWriteCharacteristic = false;
+bool foundHVCNotifyCharacteristic = false;
+bool foundHVCDeviceCharacteristic = false;
+bool WaitSend;
+DiscoveredCharacteristic HVCWriteCharacteristic;
+DiscoveredCharacteristic HVCNotifyCharacteristic;
+DiscoveredCharacteristic HVCDeviceCharacteristic;
 
-void periodicCallback(void) {
+void periodicCallback(void)
+{
     alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */
 }
 
-void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
-    if (params->peerAddr[0] != 0x29) { /* !ALERT! Update this filter to suit your device. */
+void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
+{
+    if ((params->peerAddr[5] != HVC_ADDRESS[0]) ||
+            (params->peerAddr[4] != HVC_ADDRESS[1]) ||
+            (params->peerAddr[3] != HVC_ADDRESS[2]) ||
+            (params->peerAddr[2] != HVC_ADDRESS[3]) ||
+            (params->peerAddr[1] != HVC_ADDRESS[4]) ||
+            (params->peerAddr[0] != HVC_ADDRESS[5])) { /* !ALERT! Update this filter to suit your device. */
+        //  printf("Not adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
+        //         params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
+        //         params->rssi, params->isScanResponse, params->type);
         return;
     }
-    printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
+/*
+    printf("#adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
            params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
-           params->rssi, params->isScanResponse, params->type);
-
+           params->rssi, params->isScanResponse, params->type);*/
     ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
 }
 
-void serviceDiscoveryCallback(const DiscoveredService *service) {
+void serviceDiscoveryCallback(const DiscoveredService *service)
+{
     if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
-        printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
+ /*       pc.printf("#S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());*/
     } else {
-        printf("S UUID-");
+/*        pc.printf("#S UUID-");*/
         const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
         for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
-            printf("%02x", longUUIDBytes[i]);
+/*            pc.printf("%02x", longUUIDBytes[i]);*/
         }
-        printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
+/*        pc.printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());*/
     }
 }
 
-void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
-    printf("  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
-    if (characteristicP->getShortUUID() == 0xa001) { /* !ALERT! Update this filter to suit your device. */
-        buttonCharacteristic      = *characteristicP;
-        foundButtonCharacteristic = true;
+void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
+{
+/*    pc.printf("#  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());*/
+    if (characteristicP->getShortUUID() == 2) { /* !ALERT! Update this filter to suit your device. */
+        HVCWriteCharacteristic      = *characteristicP;
+        foundHVCWriteCharacteristic = true;
+/*        printf("#HVCWriteCharacteristic Found\r\n");*/
+    }
+    if (characteristicP->getShortUUID() == 3) { /* !ALERT! Update this filter to suit your device. */
+        HVCNotifyCharacteristic      = *characteristicP;
+        foundHVCNotifyCharacteristic = true;
+/*        printf("#HVCNotifyCharacteristic Found\r\n");*/
+    }
+    if (characteristicP->getShortUUID() == 4) { /* !ALERT! Update this filter to suit your device. */
+        HVCDeviceCharacteristic      = *characteristicP;
+        foundHVCDeviceCharacteristic = true;
+/*        printf("#HVCDeviceCharacteristic Found\r\n");*/
     }
 }
 
-void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
-    printf("terminated SD for handle %u\r\n", connectionHandle);
+void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
+{
+/*    pc.printf("# discovery terminated CallBack %u\r\n", connectionHandle);*/
 }
 
-void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
+{
     if (params->role == Gap::CENTRAL) {
         connectionHandle = params->handle;
         ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
         ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback/*, 0xa000, 0xa001*/);
+        ble.gap().stopScan();
+/*        pc.printf("#SCAN Stop\r\n");*/
     }
 }
 
-void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) {
-    printf("disconnected\r\n");
+void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
+{
+/*    pc.printf("#Disconnected\r\n");*/
+    // ble.gap().startScan(advertisementCallback);
+    // pc.printf("#RE SCAN Start\r\n");
 }
 
-void hvxCallback(const GattHVXCallbackParams *params) {
-    printf("received HVX callback for handle %u; type %s\r\n", params->handle, (params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication");
+void hvxCallback(const GattHVXCallbackParams *params)
+{
+    static bool flag=false; //flag=true no toki tudukiga aru
+    static int l;
+    static unsigned char buffer[100];
+    int k,human_no,hand_no,face_no;
+    int a;
+/*    pc.printf("#received HVX callback for handle %u; type %s\r\n", params->handle, (params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication");*/
+    if(flag==false)l=0;
     for (unsigned index = 0; index < params->len; index++) {
-        printf(" %02x", params->data[index]);
+/*        pc.printf("# %02x", params->data[index]);*/
+        buffer[l]=params->data[l];
+        l++;
     }
-    printf("\r\n");
+/*    pc.printf("\r\n");*/
+    if((buffer[0]==0xfe)||(buffer[1]==0x00)) {
+        k=buffer[2]+buffer[3]*0x100+buffer[4]*0x10000+buffer[5]*0x1000000;
+        human_no=buffer[6];
+        hand_no=buffer[7];
+        face_no=buffer[8];
+        if(l>2+4+4+8*human_no+8*hand_no+(8+3)*face_no-2)flag=false;
+        else flag=true;
+        if(flag==false) {
+/*            printf("# humanNo=%d HandNo=%d FaceNo=%d\r\n",human_no,hand_no,face_no);*/
+            if(face_no>0) {
+                a=buffer[9+human_no*8+hand_no*8+9];
+                printf("%d\r\n",a);
+            }
+        }
+    }
+    WaitSend=true;
+}
+void DataReadCallback(const GattReadCallbackParams *params)
+{
+/*    pc.printf("#recive dataread \r\n");*/
+    for (unsigned index = 0; index < params->len; index++) {
+/*        pc.printf("# %02x", params->data[index]);*/
+    }
+/*    pc.printf("\r\n");*/
 }
 
-int main(void) {
+
+void DataWriteCallback(const GattWriteCallbackParams *params)
+{
+  //  pc.printf("#send data %x\r\n",params->writeOp);
+  //  for (unsigned index = 0; index < params->len; index++) {
+  //      pc.printf(" %02x", params->data[index]);
+  //  }
+  //  pc.printf("\r\n");
+    //  ble.gattClient().read(connectionHandle, HVCDeviceCharacteristic.getValueHandle(), 0);
+//WaitSend=true;
+//HVCNotifyCharacteristic.read(0);
+}
+
+int main(void)
+{
+    pc.baud(9600);
+/*    pc.printf("#Start\r\n");*/
     Ticker ticker;
     ticker.attach(periodicCallback, 1);
 
     ble.init();
+
     ble.gap().onConnection(connectionCallback);
     ble.gap().onDisconnection(disconnectionCallback);
 
     ble.gap().setScanParams(500, 400);
     ble.gap().startScan(advertisementCallback);
 
+    ble.gattClient().onDataRead(DataReadCallback);
+    ble.gattClient().onDataWrite(DataWriteCallback);
     ble.gattClient().onHVX(hvxCallback);
 
+    uint8_t send[100]= {0xfe,03,03,0,4,0x1,0};
+    int state=-1;
     while (true) {
-        if (foundButtonCharacteristic && !ble.gattClient().isServiceDiscoveryActive()) {
-            foundButtonCharacteristic = false; /* need to do the following only once */
+        if(state<0) {
+            if (foundHVCWriteCharacteristic && foundHVCNotifyCharacteristic && foundHVCDeviceCharacteristic && !ble.gattClient().isServiceDiscoveryActive()) {
+            //    printf("# State 1 \r\n");
+                state=1;
+            }
+        } else if(state==1&&!ble.gattClient().isServiceDiscoveryActive()) {
+          //  printf("# State 2 \r\n");
+            state=2;
+            ble.gattClient().onHVX(hvxCallback);
+
+            uint16_t value = BLE_HVX_NOTIFICATION;
+            WaitSend=true;
+            ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
+                                   connectionHandle,
+                                   HVCNotifyCharacteristic.getValueHandle() + 1, /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
+                                   sizeof(uint16_t),                          /* HACK Alert! size should be made into a BLE_API constant. */
+                                   reinterpret_cast<const uint8_t *>(&value));
+            // HVCNotifyCharacteristic.write(   sizeof(uint16_t),     reinterpret_cast<const uint8_t *>(&value));                     /* HACK Alert! size should be made into a BLE_API constant. */
+            //
+            //HVCNotifyCharacteristic.enableNoticiation() ;
+        } else if(state==2&&!ble.gattClient().isServiceDiscoveryActive()&&WaitSend) {
+
+            WaitSend=false;
+        //    pc.printf("#loop\r\n");
+            foundHVCWriteCharacteristic = false; /* need to do the following only once */
 
             /* Note: Yuckiness alert! The following needs to be encapsulated in a neat API.
              * It isn't clear whether we should provide a DiscoveredCharacteristic::enableNoticiation() or
              * DiscoveredCharacteristic::discoverDescriptors() followed by DiscoveredDescriptor::write(...). */
-            uint16_t value = BLE_HVX_NOTIFICATION;
+            // uint16_t value = BLE_HVX_NOTIFICATION;
+            // ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
+            //                        connectionHandle,
+            //                        HVCNotifyCharacteristic.getValueHandle() + 1, /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
+            //                        sizeof(uint16_t),                          /* HACK Alert! size should be made into a BLE_API constant. */
+            //                        reinterpret_cast<const uint8_t *>(&value));
             ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
                                    connectionHandle,
-                                   buttonCharacteristic.getValueHandle() + 1, /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
-                                   sizeof(uint16_t),                          /* HACK Alert! size should be made into a BLE_API constant. */
-                                   reinterpret_cast<const uint8_t *>(&value));
+                                   HVCWriteCharacteristic.getValueHandle(), /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
+                                   7,                          /* HACK Alert! size should be made into a BLE_API constant. */
+                                   send);
+            //printf ( "snd_error %d \r\n" ,HVCWriteCharacteristic.write(4,send));
+
         }
         ble.waitForEvent();
     }