key lock and rear light

Dependencies:   BLE_API BMA250E mbed nRF51822

/media/uploads/mtmkimi/mbed-bike.jpeg

MtConnect04S Bike Proximity Lock

We have full tutorial, please visit our blog

main.cpp

Committer:
mtmkimi
Date:
2016-12-19
Revision:
2:7920d3227906
Parent:
1:9f5ecbaa7606

File content as of revision 2:7920d3227906:

/* Copyright (c) 2016 MtM Technology Corporation, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "mbed.h"
#include "ble/BLE.h"
#include "BMA250E.h"

/* UART printf */
Serial pc(p5, p4);

/* Rear light */
DigitalOut rl(p16, 0);

/* Buzzer */
PwmOut bz(p1);

/* Sensor */
BMA250E acclerameter(p14, p13, p0, NC);

/* UUID, Device name */
uint16_t syncServUUID = GattService::UUID_DEVICE_INFORMATION_SERVICE; /* Synchronize the status of Rear light with Head light */
uint16_t syncCharUUID = 0x2B03;
static const char     DEVICE_NAME[] = "MtM Proximity";
static const uint16_t uuid16_list[] = { syncServUUID };

/* Setup custom characteristics */
uint8_t syncPayload[1];
GattCharacteristic  syncChar(   syncCharUUID, syncPayload,
                                sizeof(syncPayload), sizeof(syncPayload),
                                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);

/* Setup custom service */
GattCharacteristic *characteristics[] = {&syncChar};
GattService syncServ(syncServUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));

void rl_on(void)
{
    rl = 1;
}

void rl_off(void)
{
    rl = 0;
}

void bz_on_494hz(void)
{
    bz.period(1.0f / 494);
    bz.write(0.5);
}

void bz_on_988hz(void)
{
    bz.period(1.0f / 988);
    bz.write(0.5);
}

void bz_off(void)
{
    bz.period(0);
    bz.write(1);    // output low
}

void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    pc.printf("connection\n");

    acclerameter.EnterStandbyMode();  // sensor enters standby mode

    /* flash and beep 1 times */
    rl_on();
    bz_on_988hz();
    wait(0.5);
    rl_off();
    bz_off();
    wait(0.5);
}

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising
    
    pc.printf("disconnection\n");
    
    /* flash and beep 2 times */
    rl_off();
    bz_off();
    wait(0.5);
    rl_on();
    bz_on_988hz();
    wait(0.5);
    rl_off();
    bz_off();
    wait(0.5);
    rl_on();
    bz_on_988hz();
    wait(0.5);
    rl_off();
    bz_off();

    acclerameter.LeaveStandbyMode();  // sensor leaves standby mode (enters normal mode)
}
    
void dataWrittenCallback(const GattWriteCallbackParams *params)
{
    pc.printf("dataWritten\n");
    
    if ((params->handle == syncChar.getValueHandle()) && (params->len == 1)) {
        pc.printf("data(%d)\n", *(params->data));

        uint8_t head_light_status = *(params->data);
        if (head_light_status)  rl_on();
        else                    rl_off();        
    }        
}

void _alarm(void)
{    
    for(int i=0; i<3; i++){
        rl_on();
        bz_on_494hz();
        wait(0.5);
        
        rl_off();
        bz_on_988hz();
        wait(0.5);
    }
}

void _two_tiger(void)
{
    bz.period(1.0f / 262);  //do
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 294);  //re
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 330);  //mi
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 262);  //do
    bz.write(0.5);
    wait(0.4);
    
    bz.period(1.0f / 262);  //do
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 294);  //re
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 330);  //mi
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 262);  //do
    bz.write(0.5);
    wait(0.4);

    
    bz.period(1.0f / 330);  //mi
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 349);  //fa
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 392);  //so
    bz.write(0.5);
    wait(0.8);
    
    bz.period(1.0f / 330);  //mi
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 349);  //fa
    bz.write(0.5);
    wait(0.4);
    bz.period(1.0f / 392);  //so
    bz.write(0.5);
    wait(0.8);
}

void AcclerameterOnShaked() {
    pc.printf("BMA250_int1\n");

#if 1
    _alarm();
#else
    _two_tiger();
#endif

    rl_off();
    bz_off();
}

void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE &ble          = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        return;
    }

    ble.setDeviceName((const uint8_t *)DEVICE_NAME);
    ble.gap().onConnection(connectionCallback);
    ble.gap().onDisconnection(disconnectionCallback);
    ble.gattServer().onDataWritten(dataWrittenCallback);

    /* Setup primary service. */
    ble.addService(syncServ);

    /* Setup advertising. */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(500); /* 500ms */
    ble.gap().startAdvertising();
}

int main(void)
{
    /* Force to disable the hardware flow control of Serial */
    *((uint32_t *)(0x40002000+0x56C)) = 0;
    pc.printf("~ Hell World ~\n");

    /* Init BLE */
    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
    ble.init(bleInitComplete);
    while (ble.hasInitialized()  == false) { /* spin loop */ }

    /* Init I/O */
    rl_off();
    bz_off();

    /* Config sensor */
    acclerameter.ShakeDetection(&AcclerameterOnShaked);

    /* Main loop */
    while (1) {
        /* low power wait for event */
        pc.printf("sleep\n");
        ble.waitForEvent();
        pc.printf("wakeup\n");
    }
}