AndroidのBLEラジコンプロポアプリ「BLEPropo」と接続し、RCサーボとDCモータを制御するプログラムです。 mbed HRM1017で動作を確認しています。 BLEPropo → https://github.com/lipoyang/BLEPropo

Dependencies:   BLE_API mbed

Fork of BLE_RCBController2 by Junichi Katsu

BLEを使ったAndroid用ラジコンプロポアプリ「BLEPropo」に対応するmbed HRM1017用ファームウェアです。
BLEPropoは、GitHubにて公開中。
https://github.com/lipoyang/BLEPropo
/media/uploads/lipoyang/blepropo_ui.png
ラジコンは、mbed HRM1017とRCサーボやDCモータを組み合わせて作ります。
/media/uploads/lipoyang/ble_wiring.png

Committer:
lipoyang
Date:
Sat Mar 14 11:51:38 2015 +0000
Revision:
7:505a9a98b776
Parent:
5:85c6be3d9008
- adjust servo center position

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lipoyang 5:85c6be3d9008 1 /*
lipoyang 5:85c6be3d9008 2 * This repo was forked from jksoft/BLE_RCBController2.
lipoyang 5:85c6be3d9008 3 * The copyrights of the original repo belongs to Junichi Katsu.
lipoyang 5:85c6be3d9008 4 */
lipoyang 5:85c6be3d9008 5
lipoyang 5:85c6be3d9008 6 /*
lipoyang 5:85c6be3d9008 7 * Copyright (C) 2014 Bizan Nishimura (@lipoyang)
lipoyang 5:85c6be3d9008 8 *
lipoyang 5:85c6be3d9008 9 * Licensed under the Apache License, Version 2.0 (the "License");
lipoyang 5:85c6be3d9008 10 * you may not use this file except in compliance with the License.
lipoyang 5:85c6be3d9008 11 * You may obtain a copy of the License at
lipoyang 5:85c6be3d9008 12 *
lipoyang 5:85c6be3d9008 13 * http://www.apache.org/licenses/LICENSE-2.0
lipoyang 5:85c6be3d9008 14 *
lipoyang 5:85c6be3d9008 15 * Unless required by applicable law or agreed to in writing, software
lipoyang 5:85c6be3d9008 16 * distributed under the License is distributed on an "AS IS" BASIS,
lipoyang 5:85c6be3d9008 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lipoyang 5:85c6be3d9008 18 * See the License for the specific language governing permissions and
lipoyang 5:85c6be3d9008 19 * limitations under the License.
lipoyang 5:85c6be3d9008 20 */
lipoyang 5:85c6be3d9008 21
jksoft 0:8c643bfe55b7 22 #include "mbed.h"
jksoft 1:48f6e08a3ac2 23 #include "BLEDevice.h"
jksoft 0:8c643bfe55b7 24
jksoft 1:48f6e08a3ac2 25 #define DBG 1
jksoft 0:8c643bfe55b7 26
lipoyang 5:85c6be3d9008 27 // BLE device object
jksoft 1:48f6e08a3ac2 28 BLEDevice ble;
lipoyang 5:85c6be3d9008 29
lipoyang 5:85c6be3d9008 30 // BluePropo service UUID
lipoyang 5:85c6be3d9008 31 //static const uint16_t UUID_BLUEPROPO = 0xFFF0;
lipoyang 5:85c6be3d9008 32 static const uint8_t UUID_BLUEPROPO[] =
lipoyang 5:85c6be3d9008 33 { 0xc4, 0x9d, 0xfd, 0x1b, 0x86, 0x04, 0x41, 0xd2, 0x89, 0x43, 0x13, 0x6f, 0x21, 0x4d, 0xd0, 0xbf };
jksoft 0:8c643bfe55b7 34
lipoyang 5:85c6be3d9008 35 // BluePropo::Stick characteristic UUID
lipoyang 5:85c6be3d9008 36 //static const uint16_t UUID_BLUEPROPO_STICK = 0xFFF1;
lipoyang 5:85c6be3d9008 37 static const uint8_t UUID_BLUEPROPO_STICK[] =
lipoyang 5:85c6be3d9008 38 { 0x74, 0x25, 0xfb, 0xa0, 0x72, 0x15, 0x41, 0x36, 0xaa, 0x3f, 0x07, 0x2a, 0xa0, 0x7d, 0x93, 0x54 };
lipoyang 5:85c6be3d9008 39
lipoyang 5:85c6be3d9008 40 // Device Name (for display)
lipoyang 5:85c6be3d9008 41 #define DEVICE_NAME "MiniSteer HRM1017"
jksoft 0:8c643bfe55b7 42
lipoyang 5:85c6be3d9008 43 // BluePropo::Stick data structure
lipoyang 5:85c6be3d9008 44 union StickData
lipoyang 5:85c6be3d9008 45 {
lipoyang 5:85c6be3d9008 46 struct {
lipoyang 5:85c6be3d9008 47 // F(-128)<- 0 ->B(+127)
lipoyang 5:85c6be3d9008 48 signed char fb;
lipoyang 5:85c6be3d9008 49 // L(-128)<- 0 ->R(+127)
lipoyang 5:85c6be3d9008 50 signed char lr;
lipoyang 5:85c6be3d9008 51 }value;
lipoyang 5:85c6be3d9008 52 unsigned char bytes[2];
lipoyang 5:85c6be3d9008 53 };
lipoyang 5:85c6be3d9008 54 StickData stickData;
jksoft 1:48f6e08a3ac2 55
lipoyang 5:85c6be3d9008 56 // buffer for BluePropo payload
lipoyang 5:85c6be3d9008 57 uint8_t payload[10] = {0,};
lipoyang 5:85c6be3d9008 58
lipoyang 5:85c6be3d9008 59 // BluePropo::Stick characteristic
lipoyang 5:85c6be3d9008 60 GattCharacteristic charStick (UUID_BLUEPROPO_STICK, payload, 2, 2,
jksoft 0:8c643bfe55b7 61 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
jksoft 0:8c643bfe55b7 62 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
lipoyang 5:85c6be3d9008 63 // BluePropo characteristics set
lipoyang 5:85c6be3d9008 64 GattCharacteristic *chars[] = {&charStick};
lipoyang 5:85c6be3d9008 65 // BluePropo service
lipoyang 5:85c6be3d9008 66 GattService serviceBluePropo(UUID_BLUEPROPO, chars, sizeof(chars) / sizeof(GattCharacteristic *));
lipoyang 5:85c6be3d9008 67
lipoyang 5:85c6be3d9008 68 // USB COM port for Debug
lipoyang 5:85c6be3d9008 69 Serial pc(USBTX, USBRX);
lipoyang 5:85c6be3d9008 70
lipoyang 5:85c6be3d9008 71 // pin asign
lipoyang 5:85c6be3d9008 72 DigitalOut tb6612_ain1(P0_28);
lipoyang 5:85c6be3d9008 73 DigitalOut tb6612_ain2(P0_29);
lipoyang 5:85c6be3d9008 74 PwmOut tb6612_pwma(P0_30);
lipoyang 5:85c6be3d9008 75 PwmOut servo_pwm (P0_12);
jksoft 0:8c643bfe55b7 76
lipoyang 5:85c6be3d9008 77 // DC motor driver (TB6612)
lipoyang 5:85c6be3d9008 78 void motor (float speed)
lipoyang 5:85c6be3d9008 79 {
lipoyang 5:85c6be3d9008 80 if (speed > 0) {
lipoyang 5:85c6be3d9008 81 // CW
lipoyang 5:85c6be3d9008 82 tb6612_pwma = speed;
lipoyang 5:85c6be3d9008 83 tb6612_ain1 = 1;
lipoyang 5:85c6be3d9008 84 tb6612_ain2 = 0;
lipoyang 5:85c6be3d9008 85 } else
lipoyang 5:85c6be3d9008 86 if (speed < 0) {
lipoyang 5:85c6be3d9008 87 // CCW
lipoyang 5:85c6be3d9008 88 tb6612_pwma = - speed;
lipoyang 5:85c6be3d9008 89 tb6612_ain1 = 0;
lipoyang 5:85c6be3d9008 90 tb6612_ain2 = 1;
lipoyang 5:85c6be3d9008 91 } else {
lipoyang 5:85c6be3d9008 92 // stop
lipoyang 5:85c6be3d9008 93 tb6612_pwma = 1;
lipoyang 5:85c6be3d9008 94 tb6612_ain1 = 0;
lipoyang 5:85c6be3d9008 95 tb6612_ain2 = 0;
lipoyang 5:85c6be3d9008 96 }
lipoyang 5:85c6be3d9008 97 }
jksoft 0:8c643bfe55b7 98
lipoyang 7:505a9a98b776 99 void motor_break()
lipoyang 7:505a9a98b776 100 {
lipoyang 7:505a9a98b776 101 // break
lipoyang 7:505a9a98b776 102 tb6612_pwma = 1;
lipoyang 7:505a9a98b776 103 tb6612_ain1 = 1;
lipoyang 7:505a9a98b776 104 tb6612_ain2 = 1;
lipoyang 7:505a9a98b776 105 }
lipoyang 7:505a9a98b776 106
lipoyang 7:505a9a98b776 107 // you must adjust center position
lipoyang 7:505a9a98b776 108 #define RL_ADJ (0)
lipoyang 7:505a9a98b776 109 #define RL_CENTER (1500)
lipoyang 7:505a9a98b776 110 #define RL_RANGE (500.0)
lipoyang 7:505a9a98b776 111
lipoyang 5:85c6be3d9008 112 // RC servo
lipoyang 7:505a9a98b776 113 // rl : -1.0 ? 1.0
lipoyang 7:505a9a98b776 114 void servo (float rl)
lipoyang 5:85c6be3d9008 115 {
lipoyang 7:505a9a98b776 116 servo_pwm.pulsewidth_us(RL_CENTER + RL_ADJ + (int)(RL_RANGE * rl));
lipoyang 5:85c6be3d9008 117 }
lipoyang 5:85c6be3d9008 118
lipoyang 5:85c6be3d9008 119 // BLE onConnection handler
jksoft 1:48f6e08a3ac2 120 void onConnected(uint16_t h)
jksoft 0:8c643bfe55b7 121 {
jksoft 0:8c643bfe55b7 122 #if DBG
jksoft 1:48f6e08a3ac2 123 pc.printf("Connected\n\r");
jksoft 0:8c643bfe55b7 124 #endif
jksoft 1:48f6e08a3ac2 125 }
jksoft 0:8c643bfe55b7 126
lipoyang 5:85c6be3d9008 127 // BLE onDisconnection handler
jksoft 1:48f6e08a3ac2 128 void onDisconnected(uint16_t h)
jksoft 1:48f6e08a3ac2 129 {
jksoft 1:48f6e08a3ac2 130 ble.startAdvertising();
jksoft 0:8c643bfe55b7 131 #if DBG
jksoft 1:48f6e08a3ac2 132 pc.printf("Disconnected\n\r");
jksoft 0:8c643bfe55b7 133 #endif
jksoft 1:48f6e08a3ac2 134 }
jksoft 1:48f6e08a3ac2 135
lipoyang 5:85c6be3d9008 136 // BLE onDataWritten handler (Gatt event)
jksoft 1:48f6e08a3ac2 137 void onDataWritten(uint16_t charHandle)
jksoft 0:8c643bfe55b7 138 {
lipoyang 5:85c6be3d9008 139 if (charHandle == charStick.getHandle()) {
jksoft 1:48f6e08a3ac2 140 uint16_t bytesRead;
lipoyang 5:85c6be3d9008 141 ble.readCharacteristicValue(charStick.getHandle(),payload, &bytesRead);
lipoyang 5:85c6be3d9008 142 memcpy( &stickData.bytes[0], payload, sizeof(stickData));
jksoft 0:8c643bfe55b7 143 #if DBG
jksoft 1:48f6e08a3ac2 144
lipoyang 5:85c6be3d9008 145 pc.printf("DATA:%02X %02X\n\r",stickData.bytes[0],stickData.bytes[1]);
jksoft 0:8c643bfe55b7 146 #endif
lipoyang 5:85c6be3d9008 147 float m = (float)stickData.value.fb / 128.0;
lipoyang 5:85c6be3d9008 148 motor(m);
lipoyang 5:85c6be3d9008 149 float s = (float)stickData.value.lr / 128.0;
lipoyang 5:85c6be3d9008 150 servo(s);
jksoft 1:48f6e08a3ac2 151 }
jksoft 1:48f6e08a3ac2 152 }
jksoft 0:8c643bfe55b7 153
lipoyang 5:85c6be3d9008 154 // Program entry point
jksoft 0:8c643bfe55b7 155 int main(void)
jksoft 0:8c643bfe55b7 156 {
jksoft 0:8c643bfe55b7 157 #if DBG
jksoft 0:8c643bfe55b7 158 pc.printf("Start\n\r");
jksoft 0:8c643bfe55b7 159 #endif
lipoyang 5:85c6be3d9008 160 // initialize servo & motor
lipoyang 5:85c6be3d9008 161 servo_pwm.period_ms(20);
lipoyang 7:505a9a98b776 162 servo(0);
lipoyang 5:85c6be3d9008 163 motor(0);
jksoft 1:48f6e08a3ac2 164
lipoyang 5:85c6be3d9008 165 // initialize BLE
jksoft 2:dd85fdc18224 166 ble.init();
jksoft 1:48f6e08a3ac2 167 ble.onConnection(onConnected);
jksoft 1:48f6e08a3ac2 168 ble.onDisconnection(onDisconnected);
jksoft 1:48f6e08a3ac2 169 ble.onDataWritten(onDataWritten);
lipoyang 5:85c6be3d9008 170 // setup advertising
jksoft 1:48f6e08a3ac2 171 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
jksoft 1:48f6e08a3ac2 172 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jksoft 1:48f6e08a3ac2 173 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
lipoyang 5:85c6be3d9008 174 (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME) - 1);
jksoft 1:48f6e08a3ac2 175 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
lipoyang 5:85c6be3d9008 176 (const uint8_t *)UUID_BLUEPROPO, sizeof(UUID_BLUEPROPO));
jksoft 1:48f6e08a3ac2 177 ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
jksoft 1:48f6e08a3ac2 178 ble.startAdvertising();
lipoyang 5:85c6be3d9008 179 ble.addService(serviceBluePropo);
jksoft 0:8c643bfe55b7 180
lipoyang 5:85c6be3d9008 181 // main loop (wait for BLE event)
jksoft 1:48f6e08a3ac2 182 while (true) {
jksoft 1:48f6e08a3ac2 183 ble.waitForEvent();
jksoft 0:8c643bfe55b7 184 }
jksoft 0:8c643bfe55b7 185 }