38
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @copyright heinrichs weikamp gmbh
|
|
4 * @file bonexConnect.c
|
|
5 * @author heinrichs weikamp gmbh
|
|
6 * @date 29-Sept-2015
|
|
7 * @version 0.2
|
|
8 * @since 01-Okt-2015
|
|
9 * @brief connect to bluetooth LTE of BonexInfoSystem
|
|
10 * @bug
|
|
11 * @warning
|
|
12 @verbatim
|
|
13 ==============================================================================
|
|
14
|
|
15 BLE:
|
|
16 first of all:
|
|
17 AT+LEROLE=1 // set BLE role of the device to Central
|
|
18 it is invisible and does not accept incoming BLE connections
|
|
19
|
|
20 then:
|
|
21 AT+LESCAN
|
|
22 AT+LENAME=<bdaddr> request remote device name over BLE
|
|
23 ATD <brad>,TIO Initiate Bluetooth Link (for outgoing connections)
|
|
24
|
|
25
|
|
26 ==============================================================================
|
|
27 @endverbatim
|
|
28 ******************************************************************************
|
|
29 * @attention
|
|
30 *
|
|
31 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>
|
|
32 *
|
|
33 ******************************************************************************
|
|
34 */
|
|
35
|
|
36 #include "bonexConnect.h"
|
|
37
|
|
38 #ifndef BONEXBLUETOOTH
|
|
39 void bonexControl(void)
|
|
40 {
|
|
41 return;
|
|
42 }
|
|
43 void bC_setConnectRequest(void)
|
|
44 {
|
|
45 return;
|
|
46 }
|
|
47 uint8_t bC_getStatus(void)
|
|
48 {
|
|
49 return BC_DISCONNECTED;
|
|
50 }
|
|
51 uint8_t bC_getName(char *name)
|
|
52 {
|
|
53 *name = 0;
|
|
54 return 0;
|
|
55 }
|
|
56 uint8_t bC_getData(float *watt, float *temperature, uint16_t *drehzahl, uint8_t *residualcapacity)
|
|
57 {
|
|
58 *watt = 0;
|
|
59 *temperature = 0;
|
|
60 *drehzahl = 0;
|
|
61 *residualcapacity = 0;
|
|
62
|
|
63 return BC_DISCONNECTED;
|
|
64 }
|
|
65
|
|
66 #else
|
|
67
|
|
68
|
|
69 /* Includes ------------------------------------------------------------------*/
|
|
70 #include "settings.h"
|
|
71 #include "ostc.h"
|
|
72 #include "string.h"
|
|
73 #include "data_central.h"
|
|
74
|
|
75
|
|
76
|
|
77 union tempFloat16{
|
|
78 uint16_t u16;
|
|
79 uint8_t u8[2];
|
|
80 } temp;
|
|
81
|
|
82 /* Private function prototypes -----------------------------------------------*/
|
|
83 void bC_connect(void);
|
|
84 uint8_t bC_connect_sub_Search(void);
|
|
85 uint8_t bC_connect_sub_Connect(void);
|
|
86 void bC_call(void);
|
|
87 void bC_evaluateData(void);
|
|
88
|
|
89
|
|
90 /* Private variables with external access ------------------------------------*/
|
|
91 uint8_t status = 0;
|
|
92 uint8_t searchrequest = 0;
|
|
93 char nameOfScooter[20];
|
|
94 uint8_t dataBuffer[9];
|
|
95 uint8_t StartListeningToUARTscooter = 1;
|
|
96
|
|
97 float scooterWattstunden = 0;
|
|
98 float scooterTemperature = 0;
|
|
99 uint8_t scooterRestkapazitaet = 0;
|
|
100 uint16_t scooterDrehzahl = 0;
|
|
101
|
|
102 /* Exported functions --------------------------------------------------------*/
|
|
103
|
|
104 uint8_t bC_evaluateData(void)
|
|
105 {
|
|
106 for
|
|
107 pStateReal->lifeData.wireless_data[i].data[j]
|
|
108
|
|
109 }
|
|
110
|
|
111
|
|
112 uint8_t bC_getData(float *watt, float *temperature, uint16_t *drehzahl, uint8_t *residualcapacity)
|
|
113 {
|
|
114 if(watt)
|
|
115 *watt = scooterWattstunden;
|
|
116 if(temperature)
|
|
117 *temperature = scooterTemperature;
|
|
118 if(drehzahl)
|
|
119 *drehzahl = scooterDrehzahl;
|
|
120 if(residualcapacity)
|
|
121 *residualcapacity = scooterRestkapazitaet;
|
|
122 return status;
|
|
123 }
|
|
124
|
|
125 uint8_t bC_getStatus(void)
|
|
126 {
|
|
127 return status;
|
|
128 }
|
|
129
|
|
130
|
|
131 void bC_setConnectRequest(void)
|
|
132 {
|
|
133 searchrequest = 1;
|
|
134 }
|
|
135
|
|
136
|
|
137 uint8_t bC_getName(char *name)
|
|
138 {
|
|
139 if(status != BC_CONNECTED)
|
|
140 *name = 0;
|
|
141
|
|
142 strncpy(name,nameOfScooter,20);
|
|
143 name[19] = 0;
|
|
144 return strlen(name);
|
|
145 }
|
|
146
|
|
147 /*
|
|
148 void bonexControl(void)
|
|
149 {
|
|
150 static uint32_t time = 0;
|
|
151
|
|
152 if(settingsGetPointer()->scooterControl == 0)
|
|
153 {
|
|
154 status = BC_DISCONNECTED;
|
|
155 time = 0;
|
|
156 return;
|
|
157 }
|
|
158
|
|
159 if(settingsGetPointer()->bluetoothActive == 0)
|
|
160 {
|
|
161 status = BC_DISCONNECTED;
|
|
162 time = 0;
|
|
163 return;
|
|
164 }
|
|
165
|
|
166 if(searchrequest)
|
|
167 {
|
|
168 searchrequest = 0;
|
|
169 // maybe we have to disconnect first?
|
|
170 bC_connect();
|
|
171 StartListeningToUARTscooter = 1;
|
|
172 time = 0;
|
|
173 return;
|
|
174 }
|
|
175
|
|
176 if(status != BC_CONNECTED)
|
|
177 {
|
|
178 time = 0;
|
|
179 return;
|
|
180 }
|
|
181
|
|
182 if(UartReady == SET)
|
|
183 {
|
|
184 UartReady = RESET;
|
|
185 StartListeningToUARTscooter = 1;
|
|
186 bC_evaluateData();
|
|
187 return;
|
|
188 }
|
|
189
|
|
190 if(time_elapsed_ms(time, HAL_GetTick()) < 1000)
|
|
191 {
|
|
192 return;
|
|
193 }
|
|
194 */
|
|
195 // test
|
|
196 /*
|
|
197 const char request[4] = {0xA3, 5, 0, 0xA6};
|
|
198 HAL_UART_Transmit(&UartHandle, (uint8_t*)request, 4, 1000);
|
|
199 time = HAL_GetTick();
|
|
200 return;
|
|
201 */
|
|
202 if((UartReady == RESET) && StartListeningToUARTscooter)
|
|
203 {
|
|
204 bC_call();
|
|
205 time = HAL_GetTick();
|
|
206 }
|
|
207 }
|
|
208
|
|
209
|
|
210 /* Private functions ---------------------------------------------------------*/
|
|
211
|
|
212 void BONEX_to_16bit(uint16_t *dataOutUint16, int16_t *dataOutInt16, uint8_t *dataIn)
|
|
213 {
|
|
214 union tempU16{
|
|
215 int16_t i16;
|
|
216 uint16_t u16;
|
|
217 uint8_t u8[2];
|
|
218 } temp;
|
|
219
|
|
220 temp.u8[0] = dataIn[0];
|
|
221 temp.u8[1] = dataIn[1];
|
|
222
|
|
223 if(dataOutUint16)
|
|
224 *dataOutUint16 = temp.u16;
|
|
225
|
|
226 if(dataOutInt16)
|
|
227 *dataOutInt16 = temp.i16;
|
|
228 }
|
|
229
|
|
230 void bC_evaluateData(void)
|
|
231 {
|
|
232 uint8_t crc = dataBuffer[0];
|
|
233 for(int i=1;i<=8;i++)
|
|
234 crc ^= dataBuffer[i];
|
|
235
|
|
236 if(crc != 0)
|
|
237 return;
|
|
238
|
|
239 uint16_t watt;
|
|
240 int16_t temperatureL;
|
|
241
|
|
242 BONEX_to_16bit(&watt,0, &dataBuffer[1]);
|
|
243 BONEX_to_16bit(0,&temperatureL, &dataBuffer[4]);
|
|
244 BONEX_to_16bit(&scooterDrehzahl,0, &dataBuffer[6]);
|
|
245
|
|
246 // scooterWattstunden = ((float)(dataBuffer[3]))/100;
|
|
247 // scooterWattstunden += watt;
|
|
248 scooterWattstunden = watt; // neu ohne milliWattSekunden hw 160113
|
|
249 scooterRestkapazitaet = dataBuffer[3];
|
|
250 scooterTemperature = ((float)(temperatureL))/10;
|
|
251
|
|
252 /*
|
|
253 aTxBuffer[0] = uartSendNext; // 0 UINT8_T
|
|
254 BONEX_16to8(&aTxBuffer[1],&WattStunden); // 1+2 LSB first UINT16_T
|
|
255 alt: aTxBuffer[3] = (uint8_t)(milliWattSekunden/36000);// 3 UINT8_T
|
|
256 neu: aTxBuffer[3] = (uint8_t)(RestKapazitaet); // 3 UINT8_T
|
|
257 BONEX_16to8(&aTxBuffer[4],&TemperaturLStufe); // 4+5 LSB first INT16_T
|
|
258 BONEX_16to8(&aTxBuffer[6],&DrehzahlNeu); // 6+7 LSB first UINT16_T
|
|
259 crc UINT8_T
|
|
260 */
|
|
261 }
|
|
262
|
|
263 void bC_call(void)
|
|
264 {
|
|
265 const char request[4] = {0xA3, 1, 0, 0xA2};
|
|
266 uint8_t answer = BONEX_OK;
|
|
267
|
|
268 answer = HAL_UART_Transmit(&UartHandle, (uint8_t*)request, 4, 1000);
|
|
269 if(answer != HAL_OK)
|
|
270 return;
|
|
271
|
|
272 StartListeningToUARTscooter = 0;
|
|
273 answer = HAL_UART_Receive_IT(&UartHandle, dataBuffer, 9);
|
|
274 }
|
|
275
|
|
276
|
|
277 void bC_connect(void)
|
|
278 {
|
|
279 status = BC_SEARCHING;
|
|
280 uint8_t answer = BONEX_OK;
|
|
281
|
|
282 answer = BONEX_OK;
|
|
283 if(settingsGetPointer()->scooterDeviceAddress[0] == 0)
|
|
284 {
|
|
285 answer = bC_connect_sub_Search();
|
|
286 }
|
|
287
|
|
288 if(answer == BONEX_OK)
|
|
289 {
|
|
290 answer = bC_connect_sub_Connect();
|
|
291 }
|
|
292
|
|
293 if(answer == BONEX_OK)
|
|
294 status = BC_CONNECTED;
|
|
295 else
|
|
296 status = BC_DISCONNECTED;
|
|
297 }
|
|
298
|
|
299
|
|
300 uint8_t bC_connect_sub_Search(void)
|
|
301 {
|
|
302 uint8_t answer = BONEX_OK;
|
|
303 char buffer[256];
|
|
304 uint8_t bufferPtr = 0;
|
|
305 uint8_t length;
|
|
306 uint32_t time;
|
|
307 char *startOfBONEXString;
|
|
308 char *startOfRemoteDeviceAddress;
|
|
309 uint8_t okayNotSend;
|
|
310
|
|
311
|
|
312 strncpy(buffer,"AT+BINQ\r",256);
|
|
313 length = strlen(buffer);
|
|
314 answer = HAL_UART_Transmit(&UartHandle, (uint8_t*)buffer, length, 1000);
|
|
315 time = HAL_GetTick();
|
|
316 bufferPtr = 0;
|
|
317 okayNotSend = 6;
|
|
318 while((time_elapsed_ms(time, HAL_GetTick()) < 20000) && (bufferPtr < 255) && (okayNotSend))
|
|
319 {
|
|
320 answer = HAL_UART_Receive(&UartHandle, (uint8_t*)&buffer[bufferPtr], 1, 1000);
|
|
321 if(answer == HAL_OK)
|
|
322 {
|
|
323 switch(okayNotSend)
|
|
324 {
|
|
325 case 1:
|
|
326 if(buffer[bufferPtr] == '\n')
|
|
327 {
|
|
328 okayNotSend = 0;
|
|
329 break;
|
|
330 }
|
|
331 case 2:
|
|
332 if(buffer[bufferPtr] == '\r')
|
|
333 {
|
|
334 okayNotSend = 1;
|
|
335 break;
|
|
336 }
|
|
337 case 3:
|
|
338 if(buffer[bufferPtr] == 'K')
|
|
339 {
|
|
340 okayNotSend = 2;
|
|
341 break;
|
|
342 }
|
|
343 case 4:
|
|
344 if(buffer[bufferPtr] == 'O')
|
|
345 {
|
|
346 okayNotSend = 3;
|
|
347 break;
|
|
348 }
|
|
349 case 5:
|
|
350 if(buffer[bufferPtr] == '\n')
|
|
351 {
|
|
352 okayNotSend = 4;
|
|
353 break;
|
|
354 }
|
|
355 case 6:
|
|
356 if(buffer[bufferPtr] == '\r')
|
|
357 {
|
|
358 okayNotSend = 5;
|
|
359 break;
|
|
360 }
|
|
361 default:
|
|
362 okayNotSend = 6;
|
|
363 break;
|
|
364 }
|
|
365 bufferPtr++;
|
|
366 }
|
|
367 }
|
|
368
|
|
369 buffer[bufferPtr] = 0; // just for safety of search routines
|
|
370 length = bufferPtr;
|
|
371
|
|
372 if(length < 1)
|
|
373 return BONEX_NOTFOUND;
|
|
374
|
|
375 startOfBONEXString = strstr(buffer,"BONEX");
|
|
376
|
|
377 if(!startOfBONEXString)
|
|
378 return BONEX_NOTFOUND;
|
|
379
|
|
380
|
|
381 // copy to scooterDeviceAddress
|
|
382 startOfRemoteDeviceAddress = startOfBONEXString - 1;
|
|
383 while(startOfRemoteDeviceAddress >= buffer)
|
|
384 {
|
|
385 if(*startOfRemoteDeviceAddress == '\r')
|
|
386 break;
|
|
387 startOfRemoteDeviceAddress--;
|
|
388 }
|
|
389 /*
|
|
390 startOfBONEXString = 0; // for strrchr
|
|
391
|
|
392 startOfRemoteDeviceAddress = strrchr(buffer, '\r');
|
|
393 */
|
|
394 // first in list?
|
|
395 if(!startOfRemoteDeviceAddress)
|
|
396 startOfRemoteDeviceAddress = buffer;
|
|
397 else
|
|
398 {
|
|
399 startOfRemoteDeviceAddress += 1;
|
|
400 if(*startOfRemoteDeviceAddress == '\n')
|
|
401 startOfRemoteDeviceAddress += 1;
|
|
402 }
|
|
403 strncpy(settingsGetPointer()->scooterDeviceAddress, startOfRemoteDeviceAddress, 12);
|
|
404
|
|
405 for(int i=0;i<19;i++)
|
|
406 {
|
|
407 if((startOfBONEXString[i] == 0) || (startOfBONEXString[i] == '\r'))
|
|
408 {
|
|
409 settingsGetPointer()->scooterDeviceName[i] = 0;
|
|
410 break;
|
|
411 }
|
|
412 else
|
|
413 settingsGetPointer()->scooterDeviceName[i] = startOfBONEXString[i];
|
|
414 }
|
|
415 return BONEX_OK;
|
|
416 }
|
|
417
|
|
418
|
|
419 uint8_t bC_connect_sub_Connect(void)
|
|
420 {
|
|
421 uint8_t answer = BONEX_OK;
|
|
422 char buffer2[256];
|
|
423 uint8_t bufferPtr = 0;
|
|
424 uint8_t length;
|
|
425 uint32_t time;
|
|
426
|
|
427 strncpy(buffer2,"ATD ",256);
|
|
428 length = strlen(buffer2);
|
|
429 strncpy(&buffer2[length], settingsGetPointer()->scooterDeviceAddress, 12);
|
|
430 length += 12;
|
|
431 buffer2[length++] = '\r';
|
|
432 buffer2[length++] = 0;
|
|
433 answer = HAL_UART_Transmit(&UartHandle, (uint8_t*)buffer2, length, 1000);
|
|
434
|
|
435 time = HAL_GetTick();
|
|
436 bufferPtr = 0;
|
|
437 while((time_elapsed_ms(time, HAL_GetTick()) < 5000) && (bufferPtr < 255))
|
|
438 {
|
|
439 answer = HAL_UART_Receive(&UartHandle, (uint8_t*)&buffer2[bufferPtr], 1, 1000);
|
|
440 if(answer == HAL_OK)
|
|
441 bufferPtr++;
|
|
442 }
|
|
443
|
|
444 if(bufferPtr < 7)
|
|
445 return BONEX_NOTFOUND;
|
|
446
|
|
447 if(strstr(buffer2,"CONNECT"))
|
|
448 {
|
|
449 strncpy(nameOfScooter, settingsGetPointer()->scooterDeviceName, 19);
|
|
450 nameOfScooter[19] = 0;
|
|
451 return BONEX_OK;
|
|
452 }
|
|
453 else
|
|
454 return BONEX_NOCONNECT;
|
|
455 }
|
|
456
|
|
457 #endif // BONEXBLUETOOTH
|
|
458
|
|
459
|
|
460 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
|