|
| 1 | +#include <string.h> |
| 2 | +#include <Arduino.h> |
| 3 | +#include <SPI.h> |
| 4 | +#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_) |
| 5 | + #include <SoftwareSerial.h> |
| 6 | +#endif |
| 7 | + |
| 8 | +#include "Adafruit_BLE.h" |
| 9 | +#include "Adafruit_BluefruitLE_SPI.h" |
| 10 | +#include "Adafruit_BluefruitLE_UART.h" |
| 11 | + |
| 12 | + |
| 13 | +#define PACKET_ACC_LEN (15) |
| 14 | +#define PACKET_GYRO_LEN (15) |
| 15 | +#define PACKET_MAG_LEN (15) |
| 16 | +#define PACKET_QUAT_LEN (19) |
| 17 | +#define PACKET_BUTTON_LEN (5) |
| 18 | +#define PACKET_COLOR_LEN (6) |
| 19 | +#define PACKET_LOCATION_LEN (15) |
| 20 | + |
| 21 | +// READ_BUFSIZE Size of the read buffer for incoming packets |
| 22 | +#define READ_BUFSIZE (20) |
| 23 | + |
| 24 | + |
| 25 | +/* Buffer to hold incoming characters */ |
| 26 | +uint8_t packetbuffer[READ_BUFSIZE+1]; |
| 27 | + |
| 28 | +/**************************************************************************/ |
| 29 | +/*! |
| 30 | + @brief Casts the four bytes at the specified address to a float |
| 31 | +*/ |
| 32 | +/**************************************************************************/ |
| 33 | +float parsefloat(uint8_t *buffer) |
| 34 | +{ |
| 35 | + float f = ((float *)buffer)[0]; |
| 36 | + return f; |
| 37 | +} |
| 38 | + |
| 39 | +/**************************************************************************/ |
| 40 | +/*! |
| 41 | + @brief Prints a hexadecimal value in plain characters |
| 42 | + @param data Pointer to the byte data |
| 43 | + @param numBytes Data length in bytes |
| 44 | +*/ |
| 45 | +/**************************************************************************/ |
| 46 | +void printHex(const uint8_t * data, const uint32_t numBytes) |
| 47 | +{ |
| 48 | + uint32_t szPos; |
| 49 | + for (szPos=0; szPos < numBytes; szPos++) |
| 50 | + { |
| 51 | + Serial.print(F("0x")); |
| 52 | + // Append leading 0 for small values |
| 53 | + if (data[szPos] <= 0xF) |
| 54 | + { |
| 55 | + Serial.print(F("0")); |
| 56 | + Serial.print(data[szPos] & 0xf, HEX); |
| 57 | + } |
| 58 | + else |
| 59 | + { |
| 60 | + Serial.print(data[szPos] & 0xff, HEX); |
| 61 | + } |
| 62 | + // Add a trailing space if appropriate |
| 63 | + if ((numBytes > 1) && (szPos != numBytes - 1)) |
| 64 | + { |
| 65 | + Serial.print(F(" ")); |
| 66 | + } |
| 67 | + } |
| 68 | + Serial.println(); |
| 69 | +} |
| 70 | + |
| 71 | +/**************************************************************************/ |
| 72 | +/*! |
| 73 | + @brief Waits for incoming data and parses it |
| 74 | +*/ |
| 75 | +/**************************************************************************/ |
| 76 | +uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout) |
| 77 | +{ |
| 78 | + uint16_t origtimeout = timeout, replyidx = 0; |
| 79 | + |
| 80 | + memset(packetbuffer, 0, READ_BUFSIZE); |
| 81 | + |
| 82 | + while (timeout--) { |
| 83 | + if (replyidx >= 20) break; |
| 84 | + if ((packetbuffer[1] == 'A') && (replyidx == PACKET_ACC_LEN)) |
| 85 | + break; |
| 86 | + if ((packetbuffer[1] == 'G') && (replyidx == PACKET_GYRO_LEN)) |
| 87 | + break; |
| 88 | + if ((packetbuffer[1] == 'M') && (replyidx == PACKET_MAG_LEN)) |
| 89 | + break; |
| 90 | + if ((packetbuffer[1] == 'Q') && (replyidx == PACKET_QUAT_LEN)) |
| 91 | + break; |
| 92 | + if ((packetbuffer[1] == 'B') && (replyidx == PACKET_BUTTON_LEN)) |
| 93 | + break; |
| 94 | + if ((packetbuffer[1] == 'C') && (replyidx == PACKET_COLOR_LEN)) |
| 95 | + break; |
| 96 | + if ((packetbuffer[1] == 'L') && (replyidx == PACKET_LOCATION_LEN)) |
| 97 | + break; |
| 98 | + |
| 99 | + while (ble->available()) { |
| 100 | + char c = ble->read(); |
| 101 | + if (c == '!') { |
| 102 | + replyidx = 0; |
| 103 | + } |
| 104 | + packetbuffer[replyidx] = c; |
| 105 | + replyidx++; |
| 106 | + timeout = origtimeout; |
| 107 | + } |
| 108 | + |
| 109 | + if (timeout == 0) break; |
| 110 | + delay(1); |
| 111 | + } |
| 112 | + |
| 113 | + packetbuffer[replyidx] = 0; // null term |
| 114 | + |
| 115 | + if (!replyidx) // no data or timeout |
| 116 | + return 0; |
| 117 | + if (packetbuffer[0] != '!') // doesn't start with '!' packet beginning |
| 118 | + return 0; |
| 119 | + |
| 120 | + // check checksum! |
| 121 | + uint8_t xsum = 0; |
| 122 | + uint8_t checksum = packetbuffer[replyidx-1]; |
| 123 | + |
| 124 | + for (uint8_t i=0; i<replyidx-1; i++) { |
| 125 | + xsum += packetbuffer[i]; |
| 126 | + } |
| 127 | + xsum = ~xsum; |
| 128 | + |
| 129 | + // Throw an error message if the checksum's don't match |
| 130 | + if (xsum != checksum) |
| 131 | + { |
| 132 | + Serial.print("Checksum mismatch in packet : "); |
| 133 | + printHex(packetbuffer, replyidx+1); |
| 134 | + return 0; |
| 135 | + } |
| 136 | + |
| 137 | + // checksum passed! |
| 138 | + return replyidx; |
| 139 | +} |
0 commit comments