commit
3da3457fb2
2 changed files with 259 additions and 0 deletions
@ -0,0 +1,125 @@ |
||||
/*********************************************************************
|
||||
This is an example for our nRF52 based Bluefruit LE modules |
||||
|
||||
Pick one up today in the adafruit shop! |
||||
|
||||
Adafruit invests time and resources providing this open source code, |
||||
please support Adafruit and open-source hardware by purchasing |
||||
products from Adafruit! |
||||
|
||||
MIT license, check LICENSE for more information |
||||
All text above, and the splash screen below must be included in |
||||
any redistribution |
||||
*********************************************************************/ |
||||
|
||||
#include <bluefruit.h> |
||||
#include "Adafruit_NeoPixel.h" |
||||
|
||||
#define PIXEL_COUNT 4 * 60 // The number of NeoPixels connected to the board.
|
||||
|
||||
#define PIXEL_PIN 4 // The pin connected to the input of the NeoPixels.
|
||||
|
||||
// Create NeoPixel strip from above parameters.
|
||||
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); |
||||
|
||||
BLEUart bleuart; |
||||
|
||||
// Function prototypes for packetparser.cpp
|
||||
uint8_t readPacket (BLEUart *ble_uart, uint16_t timeout); |
||||
float parsefloat (uint8_t *buffer); |
||||
void printHex (const uint8_t * data, const uint32_t numBytes); |
||||
|
||||
// Packet buffer
|
||||
extern uint8_t packetbuffer[]; |
||||
|
||||
void setup(void) |
||||
{ |
||||
Serial.begin(115200); |
||||
Serial.println(F("Adafruit Bluefruit52 Controller App Example")); |
||||
Serial.println(F("-------------------------------------------")); |
||||
|
||||
// Initialize NeoPixels.
|
||||
strip.begin(); |
||||
for (int i = 0; i < strip.numPixels(); i++) { |
||||
strip.setPixelColor(i, 50, 50, 50); |
||||
} |
||||
strip.show(); |
||||
|
||||
Bluefruit.begin(); |
||||
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
|
||||
Bluefruit.setTxPower(4); |
||||
Bluefruit.setName("Lightstrip"); |
||||
|
||||
// Configure and start the BLE Uart service
|
||||
bleuart.begin(); |
||||
|
||||
// Set up and start advertising
|
||||
startAdv(); |
||||
|
||||
Serial.println(F("Please use Adafruit Bluefruit LE app to connect in Controller mode")); |
||||
Serial.println(F("Then activate/use the sensors, color picker, game controller, etc!")); |
||||
Serial.println();
|
||||
} |
||||
|
||||
void startAdv(void) |
||||
{ |
||||
// Advertising packet
|
||||
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); |
||||
Bluefruit.Advertising.addTxPower(); |
||||
|
||||
// Include the BLE UART (AKA 'NUS') 128-bit UUID
|
||||
Bluefruit.Advertising.addService(bleuart); |
||||
|
||||
// Secondary Scan Response packet (optional)
|
||||
// Since there is no room for 'Name' in Advertising packet
|
||||
Bluefruit.ScanResponse.addName(); |
||||
|
||||
/* Start Advertising
|
||||
* - Enable auto advertising if disconnected |
||||
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms |
||||
* - Timeout for fast mode is 30 seconds |
||||
* - Start(timeout) with timeout = 0 will advertise forever (until connected) |
||||
*
|
||||
* For recommended advertising interval |
||||
* https://developer.apple.com/library/content/qa/qa1931/_index.html
|
||||
*/ |
||||
Bluefruit.Advertising.restartOnDisconnect(true); |
||||
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
|
||||
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
|
||||
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
|
||||
} |
||||
|
||||
/**************************************************************************/ |
||||
/*!
|
||||
@brief Constantly poll for new command or response data |
||||
*/ |
||||
/**************************************************************************/ |
||||
void loop(void) |
||||
{ |
||||
// Wait for new data to arrive
|
||||
uint8_t len = readPacket(&bleuart, 500); |
||||
if (len == 0) return; |
||||
|
||||
// Got a packet!
|
||||
// printHex(packetbuffer, len);
|
||||
|
||||
// Color
|
||||
if (packetbuffer[1] == 'C') { |
||||
uint8_t red = packetbuffer[2]; |
||||
uint8_t green = packetbuffer[3]; |
||||
uint8_t blue = packetbuffer[4]; |
||||
Serial.print ("RGB #"); |
||||
if (red < 0x10) Serial.print("0"); |
||||
Serial.print(red, HEX); |
||||
if (green < 0x10) Serial.print("0"); |
||||
Serial.print(green, HEX); |
||||
if (blue < 0x10) Serial.print("0"); |
||||
Serial.println(blue, HEX); |
||||
|
||||
for (int i = 0; i < strip.numPixels(); i++) { |
||||
strip.setPixelColor(i, red, green, blue); |
||||
} |
||||
strip.show(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,134 @@ |
||||
#include <string.h> |
||||
#include <Arduino.h> |
||||
#include <bluefruit.h> |
||||
|
||||
|
||||
#define PACKET_ACC_LEN (15) |
||||
#define PACKET_GYRO_LEN (15) |
||||
#define PACKET_MAG_LEN (15) |
||||
#define PACKET_QUAT_LEN (19) |
||||
#define PACKET_BUTTON_LEN (5) |
||||
#define PACKET_COLOR_LEN (6) |
||||
#define PACKET_LOCATION_LEN (15) |
||||
|
||||
// READ_BUFSIZE Size of the read buffer for incoming packets
|
||||
#define READ_BUFSIZE (20) |
||||
|
||||
|
||||
/* Buffer to hold incoming characters */ |
||||
uint8_t packetbuffer[READ_BUFSIZE+1]; |
||||
|
||||
/**************************************************************************/ |
||||
/*!
|
||||
@brief Casts the four bytes at the specified address to a float |
||||
*/ |
||||
/**************************************************************************/ |
||||
float parsefloat(uint8_t *buffer)
|
||||
{ |
||||
float f; |
||||
memcpy(&f, buffer, 4); |
||||
return f; |
||||
} |
||||
|
||||
/**************************************************************************/ |
||||
/*!
|
||||
@brief Prints a hexadecimal value in plain characters |
||||
@param data Pointer to the byte data |
||||
@param numBytes Data length in bytes |
||||
*/ |
||||
/**************************************************************************/ |
||||
void printHex(const uint8_t * data, const uint32_t numBytes) |
||||
{ |
||||
uint32_t szPos; |
||||
for (szPos=0; szPos < numBytes; szPos++)
|
||||
{ |
||||
Serial.print(F("0x")); |
||||
// Append leading 0 for small values
|
||||
if (data[szPos] <= 0xF) |
||||
{ |
||||
Serial.print(F("0")); |
||||
Serial.print(data[szPos] & 0xf, HEX); |
||||
} |
||||
else |
||||
{ |
||||
Serial.print(data[szPos] & 0xff, HEX); |
||||
} |
||||
// Add a trailing space if appropriate
|
||||
if ((numBytes > 1) && (szPos != numBytes - 1)) |
||||
{ |
||||
Serial.print(F(" ")); |
||||
} |
||||
} |
||||
Serial.println(); |
||||
} |
||||
|
||||
/**************************************************************************/ |
||||
/*!
|
||||
@brief Waits for incoming data and parses it |
||||
*/ |
||||
/**************************************************************************/ |
||||
uint8_t readPacket(BLEUart *ble_uart, uint16_t timeout)
|
||||
{ |
||||
uint16_t origtimeout = timeout, replyidx = 0; |
||||
|
||||
memset(packetbuffer, 0, READ_BUFSIZE); |
||||
|
||||
while (timeout--) { |
||||
if (replyidx >= 20) break; |
||||
if ((packetbuffer[1] == 'A') && (replyidx == PACKET_ACC_LEN)) |
||||
break; |
||||
if ((packetbuffer[1] == 'G') && (replyidx == PACKET_GYRO_LEN)) |
||||
break; |
||||
if ((packetbuffer[1] == 'M') && (replyidx == PACKET_MAG_LEN)) |
||||
break; |
||||
if ((packetbuffer[1] == 'Q') && (replyidx == PACKET_QUAT_LEN)) |
||||
break; |
||||
if ((packetbuffer[1] == 'B') && (replyidx == PACKET_BUTTON_LEN)) |
||||
break; |
||||
if ((packetbuffer[1] == 'C') && (replyidx == PACKET_COLOR_LEN)) |
||||
break; |
||||
if ((packetbuffer[1] == 'L') && (replyidx == PACKET_LOCATION_LEN)) |
||||
break; |
||||
|
||||
while (ble_uart->available()) { |
||||
char c = ble_uart->read(); |
||||
if (c == '!') { |
||||
replyidx = 0; |
||||
} |
||||
packetbuffer[replyidx] = c; |
||||
replyidx++; |
||||
timeout = origtimeout; |
||||
} |
||||
|
||||
if (timeout == 0) break; |
||||
delay(1); |
||||
} |
||||
|
||||
packetbuffer[replyidx] = 0; // null term
|
||||
|
||||
if (!replyidx) // no data or timeout
|
||||
return 0; |
||||
if (packetbuffer[0] != '!') // doesn't start with '!' packet beginning
|
||||
return 0; |
||||
|
||||
// check checksum!
|
||||
uint8_t xsum = 0; |
||||
uint8_t checksum = packetbuffer[replyidx-1]; |
||||
|
||||
for (uint8_t i=0; i<replyidx-1; i++) { |
||||
xsum += packetbuffer[i]; |
||||
} |
||||
xsum = ~xsum; |
||||
|
||||
// Throw an error message if the checksum's don't match
|
||||
if (xsum != checksum) |
||||
{ |
||||
Serial.print("Checksum mismatch in packet : "); |
||||
printHex(packetbuffer, replyidx+1); |
||||
return 0; |
||||
} |
||||
|
||||
// checksum passed!
|
||||
return replyidx; |
||||
} |
||||
|
Loading…
Reference in new issue