Forum: Mikrocontroller und Digitale Elektronik ESP32 Bluetooth Low Energy Geschwindigkeitsproblem


von Max (Gast)


Lesenswert?

Hallo,

Ich habe einen ESP32 mit der Arduino IDE programmiert, sodass ich 
Befehle in eine BLE Gatt Charakteristik schreiben kann. Zusätzlich habe 
ich eine Android App programmiert, die die Befehle sendet.
Das funktioniert bei einzelnen Befehlen problemlos, wenn ich aber 
mehrere Befehle direkt hintereinander schicke kommt immer nur der erste 
an.
Ich gehe also davon aus, dass es an irgendeiner Stelle ein 
Geschwindigkeitsproblem gibt.
Das kann entweder am BLE Standard an sich liegen, oder am ESP32 bzw. der 
Arduino Bibliothek oder das Problem liegt bei Android.
Wenn sich jemand mit dem Thema auskennt wäre ich sehr froh über ein paar 
Tipps oder Ideen zur Fehlereingrenzung, da die Fehlersuche an drei 
verschiedenen Stellen aufwendig werden kann.

Liebe Grüße
Max

von silsi (Gast)


Lesenswert?

Sollte eigentlich nicht sein, da Daten im BLE Protocol nur verschickt 
werden, sobald beide Geräte zum Empfangen bereit sind. Die Daten werden 
dann beim Empfänger in einem Stack gespeichert.. Wäre es möglich dass du 
den nicht ausliest?

von FK (Gast)


Lesenswert?

Sendest du die Daten vom Smartphone per Write Request oder per Write 
without Response?
Was passiert, wenn du zwischendrin ein delay von z.B. 1s einbaust?

von Max B. (max_power123)


Lesenswert?

An sich war ich auch der Meinung, dass entweder Android oder der ESP die 
Daten so lange puffern sollte, bis sie verarbeitet werden.

so weit ich weiß gibt es nur eine write Funktion.
Mit 10ms Delay funktioniert alles.

p.s. hab mir jetzt auch endlich mal nen account gemacht ;)

von EnVi (Gast)


Lesenswert?

Kannst du deinen Code posten? Ich würde gerne auch ein wenig mit ESP32 
experimentieren und es wäre ein guter Startpunkt.

von Max B. (max_power123)


Lesenswert?

Hier ist der Code:
1
#include <BLEDevice.h>
2
#include <BLEUtils.h>
3
#include <BLEServer.h>
4
#include <BLE2902.h>//client Characteristic Configuration Descriptor
5
#include <QList.h>
6
7
#define SERIALNUMBER "0001"
8
#define HARDWAREREVISION "v1.2"
9
#define FIRMWAREREVISION "v2.0"
10
#define MANUFACTURER "myCompany"
11
12
// https://www.uuidgenerator.net/
13
#define SERVICE_UUID        "bcb7b7ef-ebea-470b-bf47-1c9543f9e8d9"//random 128bit uuid
14
#define WRITECHARACTERISTIC_UUID "41eefc86-b37c-4a17-9ee0-26fb02278c25"//random 128bit uuid
15
#define READCHARACTERISTIC_UUID "54dd87d0-17ad-4f4e-886c-6930a33c5b4d"//random 128bit uuid
16
17
#define BATTERYSERVICE_UUID 0x180F//standard 16bit uuid for battery service
18
#define BATTERYLEVEL_UUID 0x2A19//standard 16bit uuid for battery level characteristic
19
20
#define DEVICEINFORMATIONSERVICE_UUID 0x180A
21
#define SERIALNUMBER_UUID 0x2A25
22
#define FIRMWAREREVISION_UUID 0x2A26
23
#define HARDWAREREVISION_UUID 0x2A27
24
#define MANUFACTURER_UUID 0x2A29
25
26
BLEServer *pServer;
27
BLEAdvertising *pAdvertising;
28
29
BLEService *pDeviceInformationService;
30
BLECharacteristic *pSerialNumber;
31
BLECharacteristic *pHardwareRevision;
32
BLECharacteristic *pFirmwareRevision;
33
BLECharacteristic *pManufacturer;
34
35
BLEService *pService;
36
BLECharacteristic *pWriteCharacteristic;
37
BLECharacteristic *pReadCharacteristic;
38
39
BLEService *pBatteryService;
40
BLECharacteristic *pBatteryLevel;
41
42
bool bleConnected = false;//for reference in the main loop, true if client is connected
43
44
//callback function for the server
45
class MyServerCallbacks: public BLEServerCallbacks {
46
47
    void onConnect(BLEServer* pServer) {
48
      bleConnected = true;
49
      Serial.println("device connected");
50
    };
51
52
    void onDisconnect(BLEServer* pServer) {
53
      bleConnected = false;
54
      Serial.println("device disconnected");
55
    }
56
};
57
58
struct sAction
59
{
60
  int strength;
61
  int duration;
62
};
63
64
typedef struct sAction Action;
65
66
QList<Action> right_list;//list for instructions
67
QList<Action> left_list;//list for instructions
68
69
unsigned long right_time = 0;
70
unsigned long left_time = 0;
71
72
boolean right_running = false;
73
boolean left_running = false;
74
75
int right_last_strength = 0;
76
int left_last_strength = 0;
77
78
//callback function for Characteristics
79
class MyCharacteristicCallbacks : public BLECharacteristicCallbacks {
80
81
  public:
82
    void onRead(BLECharacteristic* pCharacteristic) {//characteristic has bben read
83
      //Serial.print("read Characteristic ");
84
      //Serial.println(pCharacteristic->getUUID().toString().c_str());//print characteristic
85
    }
86
    void onWrite(BLECharacteristic* pCharacteristic) {//characteristic has been written to
87
      //Serial.print("write Characteristic ");
88
      //Serial.println(pCharacteristic->getUUID().toString().c_str());//print characteristic
89
      //Serial.println(pCharacteristic->getValue().c_str());//print value that has been written
90
      String uuid = pCharacteristic->getUUID().toString().c_str();
91
      if (uuid.indexOf(WRITECHARACTERISTIC_UUID) != -1) {
92
        String instruction = pWriteCharacteristic->getValue().c_str();//convert characteristic value to string
93
94
  Serial.println("-----------------------------");
95
  Serial.println(instruction);
96
        
97
          int index1 = instruction.indexOf(",");
98
          int index2 = instruction.indexOf(",", index1 + 1);
99
100
          if (index1 > 0) {
101
          boolean right = false;
102
          boolean left = false;
103
          String side = instruction.substring(0, index1);
104
105
          if (side == "right") {
106
            right = true;
107
          }
108
          if (side == "left") {
109
            left = true;
110
          }
111
          if (side == "both") {
112
            right = true;
113
            left = true;
114
          }
115
116
          if (index2 > index1 + 1 && index2 != instruction.length() - 1) { //valid request   *,*,*
117
118
            int strength = instruction.substring(index1 + 1, index2).toInt();
119
            int duration = instruction.substring(index2 + 1).toInt();
120
            Action action = {.strength = strength, .duration = duration};
121
            if (right) {
122
              right_list.push_back(action);
123
            }
124
            if (left) {
125
              left_list.push_back(action);
126
            }
127
          }
128
          else {
129
            if (instruction.indexOf("clear") != -1) {
130
              if (right) {
131
                right_list.clear();
132
                right_running = false;
133
              }
134
              if (left) {
135
                left_list.clear();
136
                left_running = false;
137
              }
138
            }
139
            else if (instruction.indexOf("next") != 1) {
140
              if (right) {
141
                right_list.pop_front();
142
                right_running = false;
143
              }
144
              if (left) {
145
                left_list.pop_front();
146
                left_running = false;
147
              }
148
            }
149
          }
150
        }
151
      }
152
    }
153
};
154
155
156
void setup() {
157
158
  Serial.begin(115200);//set baudrate for serial communication
159
160
  setupBLE();
161
162
  Serial.println("Setup done");
163
164
  pinMode(14, OUTPUT);
165
  pinMode(16, OUTPUT);
166
  pinMode(25, OUTPUT);
167
  pinMode(26, OUTPUT);
168
169
  ledcSetup(0, 10000, 8);
170
  ledcAttachPin(25, 0);
171
172
  ledcSetup(1, 10000, 8);
173
  ledcAttachPin(26, 1);
174
}
175
176
//merge vibration and v_right/v_left
177
void loop() {
178
179
  int right_strength = 0;
180
  if (right_list.length() > 0) {
181
    right_strength = right_list.front().strength;
182
183
    if (!right_running) {
184
      right_time = millis() + right_list.front().duration;
185
      right_running = true;
186
    }
187
    else if (millis() >= right_time) {
188
      right_list.pop_front();
189
      right_running = false;
190
    }
191
  }
192
  int left_strength = 0;
193
  if (left_list.length() > 0) {
194
    left_strength = left_list.front().strength;
195
196
    if (!left_running) {
197
      left_time = millis() + left_list.front().duration;
198
      left_running = true;
199
    }
200
    else if (millis() >= left_time) {
201
      left_list.pop_front();
202
      left_running = false;
203
    }
204
  }
205
206
  if (right_last_strength != right_strength) {
207
    digitalWrite(14, right_strength);
208
    ledcWrite(0, right_strength);
209
    right_last_strength = right_strength;
210
  }
211
  if (left_last_strength != left_strength) {
212
    digitalWrite(16, left_strength);
213
    ledcWrite(1, left_strength);
214
    left_last_strength = left_strength;
215
  }
216
217
  //pReadCharacteristic->setValue("OK");//response for invalid instruction
218
  //pReadCharacteristic->notify();//notify the client to read the response
219
}
220
221
222
void setupBLE(void) {
223
  BLEDevice::init("myDevice");
224
  pServer = BLEDevice::createServer();
225
  pService = pServer->createService(SERVICE_UUID);//create custom service
226
227
  pDeviceInformationService = pServer->createService(BLEUUID((uint16_t)DEVICEINFORMATIONSERVICE_UUID));//create standard battery service
228
  pSerialNumber = pDeviceInformationService->createCharacteristic(//create standard battery level characteristic
229
                    BLEUUID((uint16_t)SERIALNUMBER_UUID),
230
                    BLECharacteristic::PROPERTY_READ
231
                  );
232
  pHardwareRevision = pDeviceInformationService->createCharacteristic(//create standard battery level characteristic
233
                        BLEUUID((uint16_t)HARDWAREREVISION_UUID),
234
                        BLECharacteristic::PROPERTY_READ
235
                      );
236
  pFirmwareRevision = pDeviceInformationService->createCharacteristic(//create standard battery level characteristic
237
                        BLEUUID((uint16_t)FIRMWAREREVISION_UUID),
238
                        BLECharacteristic::PROPERTY_READ
239
                      );
240
  pManufacturer = pDeviceInformationService->createCharacteristic(//create standard battery level characteristic
241
                    BLEUUID((uint16_t)MANUFACTURER_UUID),
242
                    BLECharacteristic::PROPERTY_READ
243
                  );
244
245
  pWriteCharacteristic = pService->createCharacteristic(//create custom characteristic
246
                           WRITECHARACTERISTIC_UUID,
247
                           BLECharacteristic::PROPERTY_WRITE
248
                         );
249
  pReadCharacteristic = pService->createCharacteristic(//create custom characteristic
250
                          READCHARACTERISTIC_UUID,
251
                          BLECharacteristic::PROPERTY_READ |
252
                          BLECharacteristic::PROPERTY_NOTIFY
253
                        );
254
255
  pBatteryService = pServer->createService(BLEUUID((uint16_t)BATTERYSERVICE_UUID));//create standard battery service
256
  pBatteryLevel = pBatteryService->createCharacteristic(//create standard battery level characteristic
257
                    BLEUUID((uint16_t)BATTERYLEVEL_UUID),
258
                    BLECharacteristic::PROPERTY_READ
259
                  );
260
261
262
  pReadCharacteristic->addDescriptor(new BLE2902());//add a Client Characteristic Configuration Descriptor, required to turn on notify
263
264
265
  pSerialNumber->setValue(SERIALNUMBER);
266
  pHardwareRevision->setValue(HARDWAREREVISION);
267
  pFirmwareRevision->setValue(FIRMWAREREVISION);
268
  pManufacturer->setValue(MANUFACTURER);
269
270
  pWriteCharacteristic->setValue("NULL");//initialize a standard value
271
  pWriteCharacteristic->setValue("NULL");//initialize a standard value
272
273
  pBatteryLevel->setValue({75});//initialize a standard battery level in %
274
275
  pServer->setCallbacks(new MyServerCallbacks());//specify callback for server
276
  pWriteCharacteristic->setCallbacks(new MyCharacteristicCallbacks());//specify callback for characteristic
277
  pReadCharacteristic->setCallbacks(new MyCharacteristicCallbacks());//specify callback for characteristic
278
279
  pDeviceInformationService->start();
280
  pService->start();
281
  pBatteryService->start();
282
  pAdvertising = pServer->getAdvertising();
283
  pAdvertising->start();
284
}

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.