オムロンの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

main.cpp

Committer:
yueee_yt
Date:
2015-07-22
Revision:
2:b94ca9b44b80
Parent:
1:e4ee755844de

File content as of revision 2:b94ca9b44b80:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mbed.h"
#include "ble/BLE.h"
#include "ble/DiscoveredCharacteristic.h"
#include "ble/DiscoveredService.h"

#include "ble_gatt.h"

char HVC_ADDRESS[]= {0xd5,0x32,0x26,0x3b,0x47,0x3d};
bool Reconnect=true;
char HumanDetect=1;
char HandDetect=1;
char FaceDetect=1;
char FaceDirection=1;
char FaceOld=1;
char FaceSex=1;
char FaceLook=1;
char FaceEyeClose=1;
char FaceExpression=1;
const uint8_t WriteCharacteristicAddr[]= {0x35,0x10,0x00,0x02,0xd1,0x3a,0x4f,0x39,0x8a,0xb3,0xbf,0x64,0xd4,0xfb,0xb4,0xb4};
const uint8_t NotifyCharacteristicAddr[]= {0x35,0x10,0x00,0x03,0xd1,0x3a,0x4f,0x39,0x8a,0xb3,0xbf,0x64,0xd4,0xfb,0xb4,0xb4};
const uint8_t DeviceCharacteristicAddr[]= {0x35,0x10,0x00,0x04,0xd1,0x3a,0x4f,0x39,0x8a,0xb3,0xbf,0x64,0xd4,0xfb,0xb4,0xb4};
BLE ble;
Serial pc(USBTX, USBRX);

Gap::Handle_t connectionHandle = 0xFFFF;

DigitalOut alivenessLED(LED1, 1);
bool foundHVCWriteCharacteristic = false;
bool foundHVCNotifyCharacteristic = false;
bool foundHVCDeviceCharacteristic = false;
int state=-1;
bool WaitSend;
DiscoveredCharacteristic HVCWriteCharacteristic;
DiscoveredCharacteristic HVCNotifyCharacteristic;
DiscoveredCharacteristic HVCDeviceCharacteristic;

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[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])) {
        //  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",
    //       params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
    //       params->rssi, params->isScanResponse, params->type);
    printf("#Look at HVC-C1B 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);
    ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);  //Connection
}

void serviceDiscoveryCallback(const DiscoveredService *service)
{
    if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
        //       pc.printf("#S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
    } else {
        //        pc.printf("#S UUID-");
        //        const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
        //        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
        //            pc.printf("%02x", longUUIDBytes[i]);
        //        }
        //        pc.printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
    }
}

void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
{
    bool flag;
    if (characteristicP->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
        printf("#short:\r\n");
        //dousasuruka wakaranai
        pc.printf("#  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID() , characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
        //  if (characteristicP->getShortUUID() == 2) {
        if (characteristicP->getUUID().getShortUUID() == 2) {
            HVCWriteCharacteristic      = *characteristicP;
            foundHVCWriteCharacteristic = true;
            printf("#HVCWriteCharacteristic Found\r\n");
        }
        //if (characteristicP->getShortUUID() == 3) {
        if (characteristicP->getUUID().getShortUUID() == 3) {
            HVCNotifyCharacteristic      = *characteristicP;
            foundHVCNotifyCharacteristic = true;
            printf("#HVCNotifyCharacteristic Found\r\n");
        }
        //if (characteristicP->getShortUUID() == 4) {
        if (characteristicP->getUUID().getShortUUID() == 4) {
            HVCDeviceCharacteristic      = *characteristicP;
            foundHVCDeviceCharacteristic = true;
            printf("#HVCDeviceCharacteristic Found\r\n");
        }
    } else {
        printf("#long:\r\n");
        const uint8_t *longUUIDBytes = characteristicP->getUUID().getBaseUUID();
        pc.printf("#  C UUID-");
        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
            printf("%02x", longUUIDBytes[i]);
        }
        printf(" valueAttr[%u] props[%x]\r\n",  characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
        flag=true;
        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
            if( longUUIDBytes[i]!=WriteCharacteristicAddr[i])flag=false;
        }
        if (flag==true) {
            HVCWriteCharacteristic      = *characteristicP;
            foundHVCWriteCharacteristic = true;
            printf("#HVCWriteCharacteristic Found\r\n");
        } else {
            flag=true;
            for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
                if( longUUIDBytes[i]!=NotifyCharacteristicAddr[i])flag=false;
            }
            if (flag==true) {
                HVCNotifyCharacteristic      = *characteristicP;
                foundHVCNotifyCharacteristic = true;
                printf("#HVCNotifyCharacteristic Found\r\n");
            } else {
                flag=true;
                for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
                    if( longUUIDBytes[i]!=DeviceCharacteristicAddr[i])flag=false;
                }
                if (flag==true) {
                    HVCDeviceCharacteristic      = *characteristicP;
                    foundHVCDeviceCharacteristic = true;
                    printf("#HVCDeviceCharacteristic Found\r\n");
                }
            }
        }
    }
}

void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
{
    pc.printf("# discovery terminated CallBack %u\r\n", connectionHandle);
}

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("#HVC-C1B Connect\r\n");
        pc.printf("#SCAN Stop\r\n");
    }
}

void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
    pc.printf("#HVC-C1B Disconnected\r\n");
    if(Reconnect==true) {
        state=-1;
        ble.gap().startScan(advertisementCallback);
        pc.printf("#RE SCAN Start\r\n");
    }
}

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,j,j1,j2,human_no,hand_no,face_no;
    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++) {
        buffer[l]=params->data[index];
        l++;
    }
    if((buffer[0]==0xfe)||(buffer[1]==0x00)) {
        //Sucess
        if(state==3) {
            if((l+1)>(6+0x13-1)) {
                printf("# State3 %c%c%c%c%c%c%c%c%c%c%c%c %x %x %x %x\r\n",
                       buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11],
                       buffer[12],buffer[13],buffer[14],buffer[15],buffer[16],buffer[17],
                       buffer[18],buffer[19],buffer[20],
                       buffer[21]*0x1000000+buffer[22]*0x10000+buffer[23]*0x100+buffer[24]);
                WaitSend=true;
                flag=false;
            } else {
                flag=true;
            }
        } else if(state==4) {
            k=buffer[2]+buffer[3]*0x100+buffer[4]*0x10000+buffer[5]*0x1000000;
            if((l+1)>(6+k-1)) {
                human_no=buffer[6];
                hand_no=buffer[7];
                face_no=buffer[8];

                if(human_no>0) {
                    printf("HumanDetect:%d \r\n",human_no);
                    for(k=0; k<human_no; k++) {
                        printf("Human(%d):x=%d,y=%d,size=%d,depend=%d\r\n",
                               k,buffer[10+k*8+0]+buffer[10+k*8+1]*0x100,
                               buffer[10+k*8+2]+buffer[10+k*8+3]*0x100,
                               buffer[10+k*8+4]+buffer[10+k*8+5]*0x100,
                               buffer[10+k*8+6]+buffer[10+k*8+7]*0x100);
                    }
                } else {
                    if(HumanDetect==1) {
                        printf("HumanDetect:0\r\n");
                    }
                }
                if(hand_no>0) {
                    printf("HandDetect:%d \r\n",hand_no);
                    j=10+human_no*8;
                    for(k=0; k<hand_no; k++) {
                        printf("Hand(%d):x=%d,y=%d,size=%d,depend=%d\r\n",
                               k,buffer[j+k*8+0]+buffer[j+k*8+1]*0x100,
                               buffer[j+k*8+2]+buffer[j+k*8+3]*0x100,
                               buffer[j+k*8+4]+buffer[j+k*8+5]*0x100,
                               buffer[j+k*8+6]+buffer[j+k*8+7]*0x100);
                    }
                } else {
                    if(HandDetect==1) {
                        printf("HandDetect:0\r\n");
                    }
                }
                if(face_no>0) {
                    printf("FaceDetect:%d \r\n",face_no);
                    j=10+human_no*8+hand_no*8;
                    j2=FaceDetect*8+FaceDirection*8+FaceOld*3+ FaceSex*3+ FaceLook*2+FaceEyeClose*4+FaceExpression*3;
                    if(FaceDetect==1) {
                        j1=0;
                        for(k=0; k<face_no; k++) {
                            printf("Face(%d):x=%d,y=%d,size=%d,depend=%d\r\n",
                                   k,buffer[j+k*j2+j1+0]+buffer[j+k*j2+j1+1]*0x100,
                                   buffer[j+k*j2+j1+2]+buffer[j+k*j2+j1+3]*0x100,
                                   buffer[j+k*j2+j1+4]+buffer[j+k*j2+j1+5]*0x100,
                                   buffer[j+k*j2+j1+6]+buffer[j+k*j2+j1+7]*0x100);
                        }
                    }
                    if(FaceDirection==1) {
                        j1=FaceDetect*8;
                        for(k=0; k<face_no; k++) {
                            printf("FaceDirection(%d):holizon=%d,vertical=%d,angle=%d,depend=%d\r\n",
                                   k,(signed short)(buffer[j+k*j2+j1+0]+buffer[j+k*j2+j1+1]*0x100),
                                   (signed short)(buffer[j+k*j2+j1+2]+buffer[j+k*j2+j1+3]*0x100),
                                   (signed short)(buffer[j+k*j2+j1+4]+buffer[j+k*j2+j1+5]*0x100),
                                   (signed short)(buffer[j+k*j2+j1+6]+buffer[j+k*j2+j1+7]*0x100));
                        }
                    }
                    if(FaceOld==1) {
                        j1=FaceDetect*8+FaceDirection*8;
                        for(k=0; k<face_no; k++) {
                            printf("FaceOld(%d):old=%d,depend=%d\r\n",
                                   k,(signed char)(buffer[j+k*j2+j1+0]),
                                   (short)(buffer[j+k*j2+j1+1]+buffer[j+k*j2+j1+2]*0x100));
                        }
                    }
                    if(FaceSex==1) {
                        j1=FaceDetect*8+FaceDirection*8+FaceOld*3;
                        for(k=0; k<face_no; k++) {
                            printf("FaceSex(%d):Sex=%d,depend=%d\r\n",
                                   k,(signed char)(buffer[j+k*j2+j1+0]),  //0--feminine 1---male
                                   (short)(buffer[j+k*j2+j1+1]+buffer[j+k*j2+j1+2]*0x100));
                        }
                    }
                    if(FaceLook==1) {
                        j1=FaceDetect*8+FaceDirection*8+FaceOld*3+FaceSex*3;
                        for(k=0; k<face_no; k++) {
                            printf("FaceLook(%d):holizon=%d,vertical=%d\r\n",
                                   k,(signed char)(buffer[j+k*j2+j1+0]),  //0--feminine 1---male
                                   (signed char)(buffer[j+k*j2+j1+1]));
                        }
                    }
                    if(FaceEyeClose==1) {
                        j1=FaceDetect*8+FaceDirection*8+FaceOld*3+FaceSex*3+FaceLook*2;
                        for(k=0; k<face_no; k++) {
                            printf("FaceEyeClose(%d):xleft=%d,right=%d\r\n",
                                   k,(signed short)(buffer[j+k*j2+j1+0]+buffer[j+k*j2+j1+1]*0x100),
                                   (signed short)(buffer[j+k*j2+j1+2]+buffer[j+k*j2+j1+3]*0x100));
                        }
                    }
                    if(FaceExpression==1) {
                        j1=FaceDetect*8+FaceDirection*8+FaceOld*3+FaceSex*3+FaceLook*2+FaceEyeClose*4;
                        for(k=0; k<face_no; k++) {
                            printf("FaceExpression(%d):TopExpression=%d,TopScore=%d,look=%d\r\n",
                                   k,(signed char)(buffer[j+k*j2+j1+0]),
                                   (signed char)(buffer[j+k*j2+j1+1]),
                                   (signed char)(buffer[j+k*j2+j1+2]));
                        }
                    }

                } else {
                    if(FaceDetect==1)        printf("FaceDetect:0\r\n");
                    if(FaceDirection==1)     printf("FaceDirection:0\r\n");
                    if(FaceOld==1)           printf("FaceOld:0\r\n");
                    if(FaceSex==1)           printf("FaceSex:0\r\n");
                    if(FaceLook==1)          printf("FaceLook:0\r\n");
                    if(FaceEyeClose==1)      printf("FaceEyeClose:0\r\n");
                    if(FaceExpression==1)    printf("FaceExpression:0\r\n");
                }
                flag=false;
                WaitSend=true;
            } else {
                flag=true;
            }
        }
    } else {
        flag=false;
    }
}

void DataReadCallback(const GattReadCallbackParams *params)
{
    //    pc.printf("#Data Readed \r\n");
    //for (unsigned index = 0; index < params->len; index++) {
    //        pc.printf("# %02x", params->data[index]);
    //}
    //    pc.printf("\r\n");
}

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");
    if(state==2) {
        printf("#State=2 Wited\r\n");
        WaitSend=true;
    }
}

int main(void)
{
    pc.baud(9600);
    pc.printf("#Progran Start\r\n");
    Ticker ticker;   //LED  HertBeat
    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 SendByte0[4]= {0xfe,00,00,00,};
    uint8_t SendByte1[7]= {0xfe,03,03,0,4,0x1,0};
    SendByte1[4]=FaceEyeClose*0x80+FaceLook*0x40+FaceSex*0x20+FaceOld*0x10+FaceDirection*0x8+FaceDetect*0x4+HandDetect*0x2+HumanDetect;
    SendByte1[5]=FaceExpression;
    state=-1;

    while (true) {
        if(state<0) {
            if (foundHVCWriteCharacteristic && foundHVCNotifyCharacteristic && foundHVCDeviceCharacteristic && !ble.gattClient().isServiceDiscoveryActive()) {
                printf("# State 1 Wait for Caracteristic Found \r\n");
                state=1;
            }
        } else if(state==1&&!ble.gattClient().isServiceDiscoveryActive()) {
            printf("# State 2 Notify Enable \r\n");
            state=2;
            uint16_t value = BLE_HVX_NOTIFICATION;
            WaitSend=false;
            ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
                                   connectionHandle,
                                   HVCNotifyCharacteristic.getValueHandle() + 1,
                                   sizeof(uint16_t),
                                   reinterpret_cast<const uint8_t *>(&value));
        } else if(state==2&&!ble.gattClient().isServiceDiscoveryActive()&&WaitSend) {
            //3 KIDOUKAKUNIN
            state=3;
            WaitSend=false;
            pc.printf("# State3 kidoukakunin\r\n");
            ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
                                   connectionHandle,
                                   HVCWriteCharacteristic.getValueHandle(),
                                   4,SendByte0);
        } else if((state==3||state==4)&&!ble.gattClient().isServiceDiscoveryActive()&&WaitSend) {
            //4 DataSend
            state=4;
            WaitSend=false;
            pc.printf("# State4 DataSending\r\n");
            ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
                                   connectionHandle,
                                   HVCWriteCharacteristic.getValueHandle(),
                                   7,SendByte1);
        }
        ble.waitForEvent();
    }
}