From 3da3457fb2d96ab82e4dfd22e40104b90d27fd01 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Thu, 14 Jun 2018 17:59:08 -0600 Subject: [PATCH] Initial commit --- dad-van-leds/dad-van-leds.ino | 125 +++++++++++++++++++++++++++++++ dad-van-leds/packetParser.cpp | 134 ++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 dad-van-leds/dad-van-leds.ino create mode 100644 dad-van-leds/packetParser.cpp diff --git a/dad-van-leds/dad-van-leds.ino b/dad-van-leds/dad-van-leds.ino new file mode 100644 index 0000000..070b2ce --- /dev/null +++ b/dad-van-leds/dad-van-leds.ino @@ -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 +#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(); + } + +} diff --git a/dad-van-leds/packetParser.cpp b/dad-van-leds/packetParser.cpp new file mode 100644 index 0000000..8f0194f --- /dev/null +++ b/dad-van-leds/packetParser.cpp @@ -0,0 +1,134 @@ +#include +#include +#include + + +#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