質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

0回答

1488閲覧

balaC(MPU6886)をbluetoothで操作できない

退会済みユーザー

退会済みユーザー

総合スコア0

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2021/07/27 14:28

M5stackのbalaCをbluetoothで操作しようと思い、BLEのコードをBalaCのコードに追加したのですが、
Bluetoothでつながりますが、その後に、倒立振り子動作にはいらなくなります。
bluetooth接続が切れると、倒立振り子動作が復活します。どうも、notifycallbackが実行されると、loopが止まってしまうように思うのですが、どうでしょうか?どなたかご教授よろしくお願いいたします。

Arduino

1#include <BLEDevice.h> 2#include <BLEUtils.h> 3#include <BLEScan.h> 4#include <BLEAdvertisedDevice.h> 5 6 7 8#include <M5StickC.h> 9 10#define LED 10 11#define N_CAL1 100 12#define N_CAL2 100 13#define LCDV_MID 60 14 15boolean serialMonitor=true; 16boolean standing=false; 17int16_t counter=0; 18uint32_t time0=0, time1=0; 19int16_t counterOverPwr=0, maxOvp=20; 20float power, powerR, powerL, yawPower; 21float varAng, varOmg, varSpd, varDst, varIang; 22float gyroXoffset, gyroYoffset, gyroZoffset, accXoffset; 23float gyroXdata, gyroYdata, gyroZdata, accXdata, accZdata; 24float aveAccX=0.0, aveAccZ=0.0, aveAbsOmg=0.0; 25float cutoff=0.1; //~=2 * pi * f (Hz) 26const float clk = 0.01; // in sec, 27const uint32_t interval = (uint32_t) (clk*1000); // in msec 28float Kang, Komg, KIang, Kyaw, Kdst, Kspd; 29int16_t maxPwr; 30float yawAngle=0.0; 31float moveDestination, moveTarget; 32float moveRate=0.0; 33const float moveStep=0.2*clk; 34int16_t fbBalance=0; 35int16_t motorDeadband=0; 36float mechFactR, mechFactL; 37int8_t motorRDir=0, motorLDir=0; 38bool spinContinuous=false; 39float spinDest, spinTarget, spinFact=1.0; 40float spinStep=0.0; //deg per 10msec 41int16_t ipowerL=0, ipowerR=0; 42int16_t motorLdir=0, motorRdir=0; //0:stop 1:+ -1:- 43float vBatt, voltAve=3.7; 44int16_t punchPwr, punchPwr2, punchDur, punchCountL=0, punchCountR=0; 45byte demoMode=1; 46 47 48// UUID HID 49static BLEUUID serviceUUID("1812"); 50// UUID Report Charcteristic 51static BLEUUID charUUID("2a4d"); 52 53static boolean doConnect = false; 54static boolean connected = false; 55static boolean doScan = false; 56 57static BLEAdvertisedDevice *myDevice; 58 59std::vector<BLEAdvertisedDevice*> myDevices; 60 61 62static void notifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic,uint8_t *pData,size_t length, bool isNotify) { 63 // ボタンを押すなどしてNotifyが実行されると呼び出される 64 65 66} 67 68class MyClientCallback: public BLEClientCallbacks { 69 void onConnect(BLEClient *pclient) { 70 71 72 73 } 74 75 void onDisconnect(BLEClient *pclient) { 76 connected = false; 77 Serial.println("onDisconnect"); 78 } 79}; 80 81bool connectToServer() { 82 83 Serial.printf("myDevices=%d\n", myDevices.size()); 84 for (int i = 0; i < myDevices.size(); i++) { 85 Serial.print("Forming a connection to "); 86 Serial.println(myDevices.at(i)->getAddress().toString().c_str()); 87 88 BLEClient *pClient = BLEDevice::createClient(); 89 Serial.println(" - Created client"); 90 91 pClient->setClientCallbacks(new MyClientCallback()); 92 93 // Connect to the remove BLE Server. 94 pClient->connect(myDevices.at(i)); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private) 95 Serial.println(" - Connected to server"); 96 97 98 // Obtain a reference to the service we are after in the remote BLE server. 99 BLERemoteService *pRemoteService = pClient->getService(serviceUUID); 100 if (pRemoteService == nullptr) { 101 Serial.print("Failed to find our service UUID: "); 102 Serial.println(serviceUUID.toString().c_str()); 103 pClient->disconnect(); 104 return false; 105 } 106 Serial.println(" - Found our service"); 107 108 // 複数のCharacteristicを持つHIDの事は考慮されていないので 109 // 複数のCharacteristicに対応した処理をする 110 std::map<uint16_t, BLERemoteCharacteristic*> *pCharacteristicMap; 111 pCharacteristicMap = pRemoteService->getCharacteristicsByHandle(); 112 // 引数なしのgetCharacteristics()は複数のCharacteristicを返してこないのでこちらを利用する 113 if (pCharacteristicMap == nullptr) { 114 Serial.println("pCharacteristicMap=null"); 115 return false; 116 } 117 118 for (auto itr = pCharacteristicMap->begin(); itr != pCharacteristicMap->end(); ++itr) { 119 Serial.print("UUID: "); 120 Serial.println(itr->second->getUUID().toString().c_str()); 121 if (itr->second->getUUID().equals(charUUID)) { 122 Serial.print("CharUUID matched: "); 123 Serial.println(itr->second->getUUID().toString().c_str()); 124 if (itr->second->canNotify()) { 125 // ReportCharacteristicsはNotifyCallbackでデータを通信するため 126 // Notify属性を持っているCharacteristicをすべて登録する 127 Serial.print("Notify registerd: "); 128 Serial.println(itr->second->getUUID().toString().c_str()); 129 itr->second->registerForNotify(notifyCallback); 130 } 131 } 132 } 133 134 135 } 136 connected = true; 137 return true; 138} 139/** 140 * Scan for BLE servers and find the first one that advertises the service we are looking for. 141 */ 142class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { 143 /** 144 * Called for each advertising BLE server. 145 */ 146 void onResult(BLEAdvertisedDevice advertisedDevice) { 147 Serial.print("BLE Advertised Device found: "); 148 Serial.println(advertisedDevice.toString().c_str()); 149 150 // We have found a device, let us now see if it contains the service we are looking for. 151 if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) { 152 153// BLEDevice::getScan()->stop(); 154 myDevice = new BLEAdvertisedDevice(advertisedDevice); 155 myDevices.push_back(myDevice); 156 doConnect = true; 157 doScan = true; 158 159 } // Found our server 160 } // onResult 161}; 162 163 164void setup() { 165 166 pinMode(LED, OUTPUT); 167 digitalWrite(LED, HIGH); 168 Serial.begin(115200); 169 M5.begin(); 170 Wire.begin(0, 26); //SDA,SCL 171 imuInit(); 172 M5.Axp.ScreenBreath(11); 173 M5.Lcd.setRotation(2); 174 M5.Lcd.setTextFont(4); 175 M5.Lcd.fillScreen(BLACK); 176 M5.Lcd.setTextSize(1); 177 resetMotor(); 178 resetPara(); 179 resetVar(); 180 calib1(); 181 #ifdef DEBUG 182 debugSetup(); 183 #else 184 setMode(true); 185 #endif 186 187 BLEDevice::init(""); 188 BLEScan *pBLEScan = BLEDevice::getScan(); 189 pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); 190 pBLEScan->setInterval(1349); 191 pBLEScan->setWindow(449); 192 pBLEScan->setActiveScan(true); 193 pBLEScan->start(5, false); 194 195} 196 197void loop() { 198 199 checkButtonP(); 200 #ifdef DEBUG 201 if (debugLoop1()) return; 202 #endif 203 getGyro(); 204 if (!standing) { 205 dispBatVolt(); 206 aveAbsOmg = aveAbsOmg * 0.9 + abs(varOmg) * 0.1; 207 aveAccZ = aveAccZ * 0.9 + accZdata * 0.1; 208 M5.Lcd.setCursor(10,130); 209 M5.Lcd.printf("%5.2f ", -aveAccZ); 210 if (abs(aveAccZ)>0.9 && aveAbsOmg<1.5) { 211 calib2(); 212 if (demoMode==1) startDemo(); 213 standing=true; 214 } 215 } 216 else { 217 if (abs(varAng)>30.0 || counterOverPwr>maxOvp) { 218 resetMotor(); 219 resetVar(); 220 standing=false; 221 setMode(false); 222 } 223 else { 224 drive(); 225 } 226 } 227 counter += 1; 228 if (counter >= 100) { 229 counter = 0; 230 dispBatVolt(); 231 if (serialMonitor) sendStatus(); 232 } 233 do time1 = millis(); 234 while (time1 - time0 < interval); 235 time0 = time1; 236 237 238 // If the flag "doConnect" is true then we have scanned for and found the desired 239 // BLE Server with which we wish to connect. Now we connect to it. Once we are 240 // connected we set the connected flag to be true. 241 if (doConnect == true) { 242 if (connectToServer()) { 243 Serial.println("We are now connected to the BLE Server."); 244 } 245 else { 246 Serial.println("We have failed to connect to the server; there is nothin more we will do."); 247 } 248 doConnect = false; 249 } 250 251 // If we are connected to a peer BLE Server, update the characteristic each time we are reached 252 // with the current time since boot. 253 if (connected) { 254 255 // String newValue = "Time since boot: " + String(millis()/1000); 256 // Serial.println("Setting new characteristic value to \"" + newValue + "\""); 257 258 // // Set the characteristic's value to be the array of bytes that is actually a string. 259 // pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length()); 260 } 261 else if (doScan) { 262 BLEDevice::getScan()->start(0); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino 263 } 264 265} 266 267void calib1() { 268 calDelay(30); 269 digitalWrite(LED, LOW); 270 calDelay(80); 271 M5.Lcd.fillScreen(BLACK); 272 M5.Lcd.setCursor(0, LCDV_MID); 273 M5.Lcd.print(" Cal-1 "); 274 gyroYoffset=0.0; 275 for (int i=0; i <N_CAL1; i++){ 276 readGyro(); 277 gyroYoffset += gyroYdata; 278 delay(9); 279 } 280 gyroYoffset /= (float)N_CAL1; 281 M5.Lcd.fillScreen(BLACK); 282 digitalWrite(LED, HIGH); 283} 284 285void calib2() { 286 resetVar(); 287 resetMotor(); 288 digitalWrite(LED, LOW); 289 calDelay(80); 290 M5.Lcd.setCursor(0, LCDV_MID); 291 M5.Lcd.println(" Cal-2 "); 292 accXoffset=0.0; 293 gyroZoffset=0.0; 294 for (int i=0; i <N_CAL2; i++){ 295 readGyro(); 296 accXoffset += accXdata; 297 gyroZoffset += gyroZdata; 298 delay(9); 299 } 300 accXoffset /= (float)N_CAL2; 301 gyroZoffset /= (float)N_CAL2; 302 M5.Lcd.fillScreen(BLACK); 303 digitalWrite(LED, HIGH); 304} 305 306void checkButtonP() { 307 byte pbtn=M5.Axp.GetBtnPress(); 308 if (pbtn==2) calib1(); //short push 309 else if (pbtn==1) setMode(true); //long push 310} 311 312void calDelay(int n) { 313 for (int i=0; i<n; i++) { 314 getGyro(); 315 delay(9); 316 } 317} 318 319void setMode(bool inc) { 320 if (inc) demoMode=++demoMode%2; 321 M5.Lcd.fillScreen(BLACK); 322 M5.Lcd.setCursor(5, 5); 323 if (demoMode==0) M5.Lcd.print("Stand "); 324 else if (demoMode==1) M5.Lcd.print("Demo "); 325 326} 327 328void startDemo() { 329 moveRate=0.0; 330 spinContinuous=false; 331 spinStep=0.0*clk; 332 333} 334 335以下 略

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/07/27 22:11 編集

提示のコードの動作の説明をしましょう。 どこが倒立振子のコードでしょうか
退会済みユーザー

退会済みユーザー

2021/07/27 23:59 編集

倒立振子のコードは以下です。よろしくお願いします。 // // BalaC balancing robot (IMU:MPU6886) // by Kiraku Labo // // 1. Lay the robot flat, and power on. // 2. Wait until Gal-1 (Pitch Gyro calibration) completes. // 3. Hold still the robot upright in balance until Cal-2 (Accel & Yaw Gyro cal) completes. // // short push of power button: Gyro calibration // long push (>1sec) of power button: switch mode between standig and demo(circle) // #include <M5StickC.h> #define LED 10 #define N_CAL1 100 #define N_CAL2 100 #define LCDV_MID 60 boolean serialMonitor=true; boolean standing=false; int16_t counter=0; uint32_t time0=0, time1=0; int16_t counterOverPwr=0, maxOvp=20; float power, powerR, powerL, yawPower; float varAng, varOmg, varSpd, varDst, varIang; float gyroXoffset, gyroYoffset, gyroZoffset, accXoffset; float gyroXdata, gyroYdata, gyroZdata, accXdata, accZdata; float aveAccX=0.0, aveAccZ=0.0, aveAbsOmg=0.0; float cutoff=0.1; //~=2 * pi * f (Hz) const float clk = 0.01; // in sec, const uint32_t interval = (uint32_t) (clk*1000); // in msec float Kang, Komg, KIang, Kyaw, Kdst, Kspd; int16_t maxPwr; float yawAngle=0.0; float moveDestination, moveTarget; float moveRate=0.0; const float moveStep=0.2*clk; int16_t fbBalance=0; int16_t motorDeadband=0; float mechFactR, mechFactL; int8_t motorRDir=0, motorLDir=0; bool spinContinuous=false; float spinDest, spinTarget, spinFact=1.0; float spinStep=0.0; //deg per 10msec int16_t ipowerL=0, ipowerR=0; int16_t motorLdir=0, motorRdir=0; //0:stop 1:+ -1:- float vBatt, voltAve=3.7; int16_t punchPwr, punchPwr2, punchDur, punchCountL=0, punchCountR=0; byte demoMode=1; void setup() { pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); Serial.begin(115200); M5.begin(); Wire.begin(0, 26); //SDA,SCL imuInit(); M5.Axp.ScreenBreath(11); M5.Lcd.setRotation(2); M5.Lcd.setTextFont(4); M5.Lcd.fillScreen(BLACK); M5.Lcd.setTextSize(1); resetMotor(); resetPara(); resetVar(); calib1(); #ifdef DEBUG debugSetup(); #else setMode(true); #endif } void loop() { checkButtonP(); #ifdef DEBUG if (debugLoop1()) return; #endif getGyro(); if (!standing) { dispBatVolt(); aveAbsOmg = aveAbsOmg * 0.9 + abs(varOmg) * 0.1; aveAccZ = aveAccZ * 0.9 + accZdata * 0.1; M5.Lcd.setCursor(10,130); M5.Lcd.printf("%5.2f ", -aveAccZ); if (abs(aveAccZ)>0.9 && aveAbsOmg<1.5) { calib2(); if (demoMode==1) startDemo(); standing=true; } } else { if (abs(varAng)>30.0 || counterOverPwr>maxOvp) { resetMotor(); resetVar(); standing=false; setMode(false); } else { drive(); } } counter += 1; if (counter >= 100) { counter = 0; dispBatVolt(); if (serialMonitor) sendStatus(); } do time1 = millis(); while (time1 - time0 < interval); time0 = time1; } void calib1() { calDelay(30); digitalWrite(LED, LOW); calDelay(80); M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(0, LCDV_MID); M5.Lcd.print(" Cal-1 "); gyroYoffset=0.0; for (int i=0; i <N_CAL1; i++){ readGyro(); gyroYoffset += gyroYdata; delay(9); } gyroYoffset /= (float)N_CAL1; M5.Lcd.fillScreen(BLACK); digitalWrite(LED, HIGH); } void calib2() { resetVar(); resetMotor(); digitalWrite(LED, LOW); calDelay(80); M5.Lcd.setCursor(0, LCDV_MID); M5.Lcd.println(" Cal-2 "); accXoffset=0.0; gyroZoffset=0.0; for (int i=0; i <N_CAL2; i++){ readGyro(); accXoffset += accXdata; gyroZoffset += gyroZdata; delay(9); } accXoffset /= (float)N_CAL2; gyroZoffset /= (float)N_CAL2; M5.Lcd.fillScreen(BLACK); digitalWrite(LED, HIGH); } void checkButtonP() { byte pbtn=M5.Axp.GetBtnPress(); if (pbtn==2) calib1(); //short push else if (pbtn==1) setMode(true); //long push } void calDelay(int n) { for (int i=0; i<n; i++) { getGyro(); delay(9); } } void setMode(bool inc) { if (inc) demoMode=++demoMode%2; M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(5, 5); if (demoMode==0) M5.Lcd.print("Stand "); else if (demoMode==1) M5.Lcd.print("Demo "); } void startDemo() { moveRate=0.0; spinContinuous=false; spinStep=0.0*clk; } void resetPara() { Kang=37.0; Komg=0.84; KIang=800.0; Kyaw=4.0; Kdst=85.0; Kspd=2.7; mechFactL=0.45; mechFactR=0.45; punchPwr=20; punchDur=1; fbBalance=-3; motorDeadband=10; maxPwr=120; punchPwr2=max(punchPwr, motorDeadband); } void getGyro() { readGyro(); varOmg = (gyroYdata-gyroYoffset); //unit:deg/sec yawAngle += (gyroZdata-gyroZoffset) * clk; //unit:g varAng += (varOmg + ((accXdata-accXoffset) * 57.3 - varAng) * cutoff ) * clk; //complementary filter } void readGyro() { float gX, gY, gZ, aX, aY, aZ; M5.Imu.getGyroData(&gX,&gY,&gZ); M5.Imu.getAccelData(&aX,&aY,&aZ); gyroYdata=gX; gyroZdata=-gY; gyroXdata=-gZ; accXdata=aZ; accZdata=aY; } void drive() { #ifdef DEBUG debugDrive(); #endif if (abs(moveRate)>0.1) spinFact=constrain(-(powerR+powerL)/10.0, -1.0, 1.0); //moving else spinFact=1.0; //standing if (spinContinuous) spinTarget += spinStep * spinFact; else { if (spinTarget < spinDest) spinTarget += spinStep; if (spinTarget > spinDest) spinTarget -= spinStep; } moveTarget += moveStep * (moveRate +(float)fbBalance/100.0); varSpd += power * clk; varDst += Kdst * (varSpd * clk -moveTarget); varIang += KIang * varAng * clk; power = varIang + varDst + (Kspd * varSpd) + (Kang * varAng) + (Komg * varOmg); if (abs(power) > 1000.0) counterOverPwr += 1; else counterOverPwr =0; if (counterOverPwr > maxOvp) return; power = constrain(power, -maxPwr, maxPwr); yawPower = (yawAngle - spinTarget) * Kyaw; powerR = power - yawPower; powerL = power + yawPower; ipowerL = (int16_t) constrain(powerL * mechFactL, -maxPwr, maxPwr); int16_t mdbn=-motorDeadband; int16_t pp2n=-punchPwr2; if (ipowerL > 0) { if (motorLdir == 1) punchCountL = constrain(++punchCountL, 0, 100); else punchCountL=0; motorLdir = 1; if (punchCountL<punchDur) drvMotorL(max(ipowerL, punchPwr2)); else drvMotorL(max(ipowerL, motorDeadband)); } else if (ipowerL < 0) { if (motorLdir == -1) punchCountL = constrain(++punchCountL, 0, 100); else punchCountL=0; motorLdir = -1; if (punchCountL<punchDur) drvMotorL(min(ipowerL, pp2n)); else drvMotorL(min(ipowerL, mdbn)); } else { drvMotorL(0); motorLdir = 0; } ipowerR = (int16_t) constrain(powerR * mechFactR, -maxPwr, maxPwr); if (ipowerR > 0) { if (motorRdir == 1) punchCountR = constrain(++punchCountR, 0, 100); else punchCountR=0; motorRdir = 1; if (punchCountR<punchDur) drvMotorR(max(ipowerR, punchPwr2)); else drvMotorR(max(ipowerR, motorDeadband)); } else if (ipowerR < 0) { if (motorRdir == -1) punchCountR = constrain(++punchCountR, 0, 100); else punchCountR=0; motorRdir = -1; if (punchCountR<punchDur) drvMotorR(min(ipowerR, pp2n)); else drvMotorR(min(ipowerR, mdbn)); } else { drvMotorR(0); motorRdir = 0; } } void drvMotorL(int16_t pwm) { drvMotor(0, (int8_t)constrain(pwm, -127, 127)); } void drvMotorR(int16_t pwm) { drvMotor(1, (int8_t)constrain(-pwm, -127, 127)); } void drvMotor(byte ch, int8_t sp) { Wire.beginTransmission(0x38); Wire.write(ch); Wire.write(sp); Wire.endTransmission(); } void resetMotor() { drvMotorR(0); drvMotorL(0); counterOverPwr=0; } void resetVar() { power=0.0; moveTarget=0.0; moveRate=0.0; spinContinuous=false; spinDest=0.0; spinTarget=0.0; spinStep=0.0; yawAngle=0.0; varAng=0.0; varOmg=0.0; varDst=0.0; varSpd=0.0; varIang=0.0; } void sendStatus () { Serial.print(millis()-time0); Serial.print(" stand="); Serial.print(standing); Serial.print(" accX="); Serial.print(accXdata); Serial.print(" power="); Serial.print(power); Serial.print(" ang=");Serial.print(varAng); Serial.print(", "); Serial.print(millis()-time0); Serial.println(); } void imuInit() { M5.Imu.Init(); if (M5.Imu.imuType=M5.Imu.IMU_MPU6886) { M5.Mpu6886.SetGyroFsr(M5.Mpu6886.GFS_250DPS); //250DPS 500DPS 1000DPS 2000DPS M5.Mpu6886.SetAccelFsr(M5.Mpu6886.AFS_4G); //2G 4G 8G 16G if (serialMonitor) Serial.println("MPU6886 found"); } else if (serialMonitor) Serial.println("MPU6886 not found"); } void dispBatVolt() { M5.Lcd.setCursor(5, LCDV_MID); vBatt= M5.Axp.GetBatVoltage(); M5.Lcd.printf("%4.2fv ", vBatt); }
退会済みユーザー

退会済みユーザー

2021/07/27 23:57

Ble 受信のコードは以下です。 #include <BLEDevice.h> #include <BLEUtils.h> #include <BLEScan.h> #include <BLEAdvertisedDevice.h> #include <M5StickC.h> // UUID HID static BLEUUID serviceUUID("1812"); // UUID Report Charcteristic static BLEUUID charUUID("2a4d"); static boolean doConnect = false; static boolean connected = false; static boolean doScan = false; static BLEAdvertisedDevice *myDevice; std::vector<BLEAdvertisedDevice*> myDevices; static void notifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic,uint8_t *pData,size_t length, bool isNotify) { // ボタンを押すなどしてNotifyが実行されると呼び出される } class MyClientCallback: public BLEClientCallbacks { void onConnect(BLEClient *pclient) { } void onDisconnect(BLEClient *pclient) { connected = false; Serial.println("onDisconnect"); } }; bool connectToServer() { Serial.printf("myDevices=%d\n", myDevices.size()); for (int i = 0; i < myDevices.size(); i++) { Serial.print("Forming a connection to "); Serial.println(myDevices.at(i)->getAddress().toString().c_str()); BLEClient *pClient = BLEDevice::createClient(); Serial.println(" - Created client"); pClient->setClientCallbacks(new MyClientCallback()); // Connect to the remove BLE Server. pClient->connect(myDevices.at(i)); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private) Serial.println(" - Connected to server"); // Obtain a reference to the service we are after in the remote BLE server. BLERemoteService *pRemoteService = pClient->getService(serviceUUID); if (pRemoteService == nullptr) { Serial.print("Failed to find our service UUID: "); Serial.println(serviceUUID.toString().c_str()); pClient->disconnect(); return false; } Serial.println(" - Found our service"); // 複数のCharacteristicを持つHIDの事は考慮されていないので // 複数のCharacteristicに対応した処理をする std::map<uint16_t, BLERemoteCharacteristic*> *pCharacteristicMap; pCharacteristicMap = pRemoteService->getCharacteristicsByHandle(); // 引数なしのgetCharacteristics()は複数のCharacteristicを返してこないのでこちらを利用する if (pCharacteristicMap == nullptr) { Serial.println("pCharacteristicMap=null"); return false; } for (auto itr = pCharacteristicMap->begin(); itr != pCharacteristicMap->end(); ++itr) { Serial.print("UUID: "); Serial.println(itr->second->getUUID().toString().c_str()); if (itr->second->getUUID().equals(charUUID)) { Serial.print("CharUUID matched: "); Serial.println(itr->second->getUUID().toString().c_str()); if (itr->second->canNotify()) { // ReportCharacteristicsはNotifyCallbackでデータを通信するため // Notify属性を持っているCharacteristicをすべて登録する Serial.print("Notify registerd: "); Serial.println(itr->second->getUUID().toString().c_str()); itr->second->registerForNotify(notifyCallback); } } } } connected = true; return true; } /** * Scan for BLE servers and find the first one that advertises the service we are looking for. */ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { /** * Called for each advertising BLE server. */ void onResult(BLEAdvertisedDevice advertisedDevice) { Serial.print("BLE Advertised Device found: "); Serial.println(advertisedDevice.toString().c_str()); // We have found a device, let us now see if it contains the service we are looking for. if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) { // BLEDevice::getScan()->stop(); myDevice = new BLEAdvertisedDevice(advertisedDevice); myDevices.push_back(myDevice); doConnect = true; doScan = true; } // Found our server } // onResult }; void setup() { BLEDevice::init(""); BLEScan *pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setInterval(1349); pBLEScan->setWindow(449); pBLEScan->setActiveScan(true); pBLEScan->start(5, false); } void loop() { // If the flag "doConnect" is true then we have scanned for and found the desired // BLE Server with which we wish to connect. Now we connect to it. Once we are // connected we set the connected flag to be true. if (doConnect == true) { if (connectToServer()) { Serial.println("We are now connected to the BLE Server."); } else { Serial.println("We have failed to connect to the server; there is nothin more we will do."); } doConnect = false; } // If we are connected to a peer BLE Server, update the characteristic each time we are reached // with the current time since boot. if (connected) { // String newValue = "Time since boot: " + String(millis()/1000); // Serial.println("Setting new characteristic value to \"" + newValue + "\""); // // Set the characteristic's value to be the array of bytes that is actually a string. // pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length()); } else if (doScan) { BLEDevice::getScan()->start(0); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問