![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
スマートロックソフトウェア(BLE nano用)
Dependencies: BLE_API mbed nRF51822
Revision 0:fcfa8140d2db, committed 2015-09-04
- Comitter:
- toshiyukisaito
- Date:
- Fri Sep 04 13:29:59 2015 +0000
- Commit message:
- SmartLock Version1
Changed in this revision
diff -r 000000000000 -r fcfa8140d2db BLE_API.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLE_API.lib Fri Sep 04 13:29:59 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#8d316a3271a8
diff -r 000000000000 -r fcfa8140d2db Servo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Servo.cpp Fri Sep 04 13:29:59 2015 +0000 @@ -0,0 +1,42 @@ +/* + +Copyright (c) 2012-2014 RedBearLab + +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 "Servo.h" + +Servo::Servo(PinName pin) : _servo(pin) +{ + _servo.period_ms(20); +} + +Servo::~Servo(void) +{ + +} + +void Servo::write(unsigned char degree) +{ + convert(degree); + _servo.pulsewidth_us(pulse); +} + +void Servo::convert(unsigned char degree) +{ + // 0~180 degree correspond to 500~2500 + pulse = degree * 11 + 500; +}
diff -r 000000000000 -r fcfa8140d2db Servo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Servo.h Fri Sep 04 13:29:59 2015 +0000 @@ -0,0 +1,40 @@ +/* + +Copyright (c) 2012-2014 RedBearLab + +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. + +*/ + +#ifndef _SERVO_H +#define _SERVO_H + +#include "mbed.h" + +class Servo +{ +public: + Servo(PinName pin); + ~Servo(void); + + void write(unsigned char degree); + +private: + void convert(unsigned char degree); + + PwmOut _servo; + unsigned int pulse; +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r fcfa8140d2db main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Sep 04 13:29:59 2015 +0000 @@ -0,0 +1,261 @@ +#include "mbed.h" +#include "ble/BLE.h" +#include "Servo.h" + +#define LOCAL_NAME "SmartLock" +#define TXRX_BUF_LEN 20 +#define SERVO_PIN P0_8 // RTS +#define SERVO_PWR_PIN P0_11 // RXD +#define SWITCH_PIN P0_9 // TXD + +#define SERVO_ON_TIME 1 // s +#define SWITCH_WATCH_INTERVAL 2 // s +#define UNLOCK_PHRASE "O" +#define LOCK_PHRASE "C" +#define STATUS_PHRASE "S" +#define PAIRING_PHRASE "PAIR" +#define PASSPHRASE "PSS_" +#define SET_PASSPHRASE "PHRASE" +#define ALREADY_PAIRING "ALREADY" +#define PASSPHRASE_LENGTH 10 + +#define UNLOCK_SERVO_POS 90 +#define LOCK_SERVO_POS 0 + +#define ADVERTISING_INTERVAL 1000 // ms + +BLE ble; +Servo servo(SERVO_PIN); +DigitalOut sw(SERVO_PWR_PIN); +DigitalIn toggle(SWITCH_PIN); +DigitalOut led(P0_19); + +#define DEBUG 0 + +#if DEBUG +Serial pc(USBTX, USBRX); +#endif + +static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0x00, 0x00, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E}; +static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0x00, 0x03, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E}; +static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0x00, 0x02, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E}; +static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0x00, 0x00, 0x3D, 0x71}; + +uint8_t txPayload[TXRX_BUF_LEN] = {0,}; +uint8_t rxPayload[TXRX_BUF_LEN] = {0,}; + +GattCharacteristic txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE); +GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); +GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic}; +GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *)); + +bool isUnlock = false; // ロック状態 +bool isPairing = false; // ペアリング状態 +bool onPairing = false; // ペアリング中フラグ +char phrase[TXRX_BUF_LEN] = {0,}; // パスフレーズ + +/* + 文字列prefix+s1とs2の比較を行います。 +*/ +bool str_equal(const char* prefix, const char* s1, uint8_t* s2) { + int i = 0; + while (prefix[i] != '\0') { + if (prefix[i] != (char) s2[i]) { + return false; + } + i++; + } + int j = 0; + while(s1[j] != '\0') { + if (s1[j] != (char) s2[i]) { + return false; + } + i++; + j++; + } + return true; +} + +/* + char*の文字列をuint8_t*の文字列にコピーします。 +*/ +void uintstr_cpy(uint8_t* dest, const char* src) { + int i; + for (i = 0; src[i] != '\0'; i++) { + dest[i] = src[i]; + } + dest[i] = '\0'; +} + +/* + ロック状態のステータス更新 +*/ +void UpdateStatus() { + // ペアリングされていなければUpdateしない。 + if (!isPairing) return; + uint8_t buf[2]; + uintstr_cpy(buf, isUnlock ? UNLOCK_PHRASE : LOCK_PHRASE); + ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 2); +} + +/* + サムターン回転処理。unlock=trueで開錠。 +*/ +void Thumbturn(bool unlock) { + isUnlock = unlock; + sw.write(1); + wait(0.05); + servo.write(isUnlock ? UNLOCK_SERVO_POS : LOCK_SERVO_POS); + wait(SERVO_ON_TIME); + UpdateStatus(); + sw.write(0); + wait(0.05); +} + +/* + BLEのコールバック。centralと接続が切れた場合の処理。 +*/ +void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) { + ble.startAdvertising(); +} + +/* + BLEのコールバック。centralから書き込みがあった場合の処理 +*/ +void WrittenHandler(const GattWriteCallbackParams *Handler) { + uint8_t buf[TXRX_BUF_LEN]; + uint16_t bytesRead; + + if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) { + ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead); + memset(txPayload, 0, TXRX_BUF_LEN); + memcpy(txPayload, buf, bytesRead); +#if DEBUG + pc.printf("Receive: %d, %s\r\n", bytesRead, buf); +#endif + + // ペアリングしていなくて、ステータスチェックが来たら + if (!isPairing && str_equal(STATUS_PHRASE, "", buf)) { + // ペアリングの必要があるよ。 + uint8_t buf[TXRX_BUF_LEN]; + memset(txPayload, 0, TXRX_BUF_LEN); + uintstr_cpy(buf, PAIRING_PHRASE); + ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 5); + return; + } + + // ペアリング要求 + if (str_equal(PAIRING_PHRASE, "", buf)) { +#if DEBUG + pc.printf("Receive: PAIRING REQUEST\r\n", bytesRead, buf); +#endif + if (!isPairing) { + // パスフレーズ要求 + onPairing = true; + uint8_t buf[TXRX_BUF_LEN]; + memset(txPayload, 0, TXRX_BUF_LEN); + uintstr_cpy(buf, SET_PASSPHRASE); + ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 7); + } else { + // ペアリング不可。電源を落としてください。 + uint8_t buf[TXRX_BUF_LEN]; + memset(txPayload, 0, TXRX_BUF_LEN); + uintstr_cpy(buf, ALREADY_PAIRING); + ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 8); + } + return; + } + + // ペアリング処理中 + if (onPairing) { + if (str_equal(PASSPHRASE, "", buf)) { + // appから10桁のコードをもらう + for (int i = 0; i < PASSPHRASE_LENGTH; i++) { + phrase[i] = buf[i + strlen(PASSPHRASE)]; + } + phrase[PASSPHRASE_LENGTH+1] = '\0'; + onPairing = false; + isPairing = true; + led.write(1); + wait(0.5); + } + return; + } + + // ペアリング済み + if(str_equal(UNLOCK_PHRASE, phrase, buf)) { + Thumbturn(true); + } else if(str_equal(LOCK_PHRASE, phrase, buf)) { + Thumbturn(false); + } else if(str_equal(STATUS_PHRASE, phrase, buf)) { + UpdateStatus(); + } + } +} + +/* + ステータスチェック。 + タイマーで一定時間ごとに呼び出される。 +*/ +void StatusCheckHundler() { +#if DEBUG + pc.printf("SC %d %d\r\n", isPairing, onPairing); +#endif + if (isPairing) { + // ペアリング済みならtoggleボタンでUnlock/Lockできる + if (toggle.read() == 0) { + if (isUnlock) { + Thumbturn(false); + } else { + Thumbturn(true); + } + } + } else { + // 未ペアリング + + // onPairgingになったときにLEDを点滅させる + if (onPairing) { + if (led.read() != 0) { + led.write(0); + } else { + led.write(1); + } + } + } +} + +int main(void) { +#if DEBUG + pc.baud(9600); + pc.printf("INIT\r\n"); +#endif + + Ticker ticker; + ticker.attach_us(StatusCheckHundler, SWITCH_WATCH_INTERVAL * 1000 * 1000); + + ble.init(); + ble.onDisconnection(disconnectionCallback); + ble.onDataWritten(WrittenHandler); + + // setup advertising + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, + (const uint8_t *)LOCAL_NAME, sizeof(LOCAL_NAME) - 1); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, + (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid)); + ble.setDeviceName(LOCAL_NAME); + ble.setAdvertisingInterval(ADVERTISING_INTERVAL/0.625); + ble.addService(uartService); + + ble.startAdvertising(); + + // 起動時に、Lock状態にして、LEDを点灯させる(未ペアリングのため。) + Thumbturn(false); + led.write(0); + toggle.mode(PullUp); + + while(true) { + ble.waitForEvent(); + } +}
diff -r 000000000000 -r fcfa8140d2db mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Sep 04 13:29:59 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8ed44a420e5c \ No newline at end of file
diff -r 000000000000 -r fcfa8140d2db nRF51822.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nRF51822.lib Fri Sep 04 13:29:59 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#ca9c9c2cfc6a