205 lines
4.9 KiB
C++
205 lines
4.9 KiB
C++
#include <string.h>
|
|
#include <Arduino.h>
|
|
#include <SPI.h>
|
|
#include <Adafruit_NeoPixel.h>
|
|
#include "Adafruit_BLE.h"
|
|
#include "Adafruit_BluefruitLE_SPI.h"
|
|
#include "Adafruit_BluefruitLE_UART.h"
|
|
|
|
#if SOFTWARE_SERIAL_AVAILABLE
|
|
#include <SoftwareSerial.h>
|
|
#endif
|
|
|
|
#include "BluefruitConfig.h"
|
|
|
|
#define FACTORYRESET_ENABLE 1
|
|
#define DIM_FACTOR 50
|
|
|
|
uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout);
|
|
float parsefloat(uint8_t *buffer);
|
|
void printHex(const uint8_t * data, const uint32_t numBytes);
|
|
|
|
// the packet buffer
|
|
extern uint8_t packetbuffer[];
|
|
|
|
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);
|
|
|
|
volatile boolean irq_event_available = false;
|
|
void DfuIrqHandle(void) {
|
|
irq_event_available = true;
|
|
}
|
|
|
|
void bluetooth_setup(){
|
|
Serial.print(F("Initialising the Bluefruit LE module"));
|
|
if ( !ble.begin(VERBOSE_MODE) ) {
|
|
Serial.println(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
|
|
while(1); // halt
|
|
}
|
|
if ( FACTORYRESET_ENABLE ) {
|
|
Serial.println(F("Performing a factory reset"));
|
|
if ( ! ble.factoryReset() ){
|
|
Serial.println(F("Couldn't factory reset"));
|
|
while(1); // halt
|
|
}
|
|
}
|
|
pinMode(BLUEFRUIT_SPI_IRQ, INPUT_PULLUP);
|
|
attachInterrupt(digitalPinToInterrupt(BLUEFRUIT_SPI_IRQ), DfuIrqHandle, FALLING);
|
|
ble.echo(false); // disable command echo
|
|
ble.sendCommandCheckOK(F("AT+GAPDEVNAME=Suit LEDs")); // Change name displayed in bluetooth scans
|
|
ble.sendCommandCheckOK(F("AT+DFUIRQ=on")); // Change DFU Pin to IRQ Mode
|
|
ble.verbose(false); // disable debug info
|
|
//Serial.println("Requesting Bluefruit info:");
|
|
//ble.info();
|
|
ble.setConnectCallback(on_connect);
|
|
ble.setDisconnectCallback(on_disconnect);
|
|
ble.setBleUartRxCallback(on_rx);
|
|
ble.setMode(BLUEFRUIT_MODE_DATA);
|
|
Serial.println(F("Bluetooth ready"));
|
|
}
|
|
|
|
void on_connect(){
|
|
Serial.println(F("on_connect"));
|
|
}
|
|
void on_disconnect(){
|
|
Serial.println(F("on_disconnect"));
|
|
}
|
|
void on_rx(){
|
|
Serial.println(F("on_rx"));
|
|
/*uint8_t len = readPacket(&ble, BLE_READPACKET_TIMEOUT);
|
|
if (len == 0) return;
|
|
Serial.println(F("data"));
|
|
if (packetbuffer[1] == 'P'){
|
|
Serial.println(char(packetbuffer[2]));
|
|
} else {
|
|
printHex(packetbuffer, len);
|
|
}*/
|
|
}
|
|
|
|
uint32_t pack_color(uint8_t r, uint8_t g, uint8_t b) {
|
|
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
|
}
|
|
uint32_t pack_color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
|
return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
|
}
|
|
uint8_t red(uint32_t color){
|
|
return (color >> 16) & 0xFF;
|
|
}
|
|
uint8_t green(uint32_t color){
|
|
return (color >> 8) & 0xFF;
|
|
}
|
|
uint8_t blue(uint32_t color){
|
|
return color & 0xFF;
|
|
}
|
|
uint8_t white(uint32_t color){
|
|
return (color >> 24) & 0xFF;
|
|
}
|
|
|
|
class Strip {
|
|
private:
|
|
uint8_t pin;
|
|
uint8_t num_pixels;
|
|
uint16_t wait;
|
|
unsigned long last;
|
|
uint8_t offset;
|
|
Adafruit_NeoPixel pixel;
|
|
|
|
public:
|
|
Strip(uint8_t led_pin, uint8_t strip_len, uint16_t wait_ms) {
|
|
pin = led_pin;
|
|
num_pixels = strip_len;
|
|
wait = wait_ms;
|
|
last = millis();
|
|
offset = 0;
|
|
pixel = Adafruit_NeoPixel(num_pixels, pin, NEO_GRBW + NEO_KHZ800);
|
|
}
|
|
|
|
public:
|
|
void off(){
|
|
Serial.println(F("off()"));
|
|
pixel.begin();
|
|
for(uint8_t i=0; i<num_pixels; i++){
|
|
pixel.setPixelColor(i, pack_color(0,0,0));
|
|
}
|
|
pixel.show();
|
|
}
|
|
|
|
private:
|
|
void rainbow(){
|
|
uint8_t r = 255;
|
|
uint8_t g = 0;
|
|
uint8_t b = 0;
|
|
pixel.begin();
|
|
for (uint8_t index=0; index<num_pixels; index++){
|
|
uint8_t loc;
|
|
if (offset + index > num_pixels - 1){
|
|
loc = index + offset - num_pixels;
|
|
} else {
|
|
loc = offset + index;
|
|
}
|
|
pixel.setPixelColor(
|
|
loc,
|
|
pack_color(r/DIM_FACTOR, g/DIM_FACTOR, b/DIM_FACTOR)
|
|
);
|
|
if (index < 24){ // red -> yellow shifting
|
|
g += 10;
|
|
} else if (index < 48){ // yellow -> green shifting
|
|
if (index == 24){
|
|
g = 255;
|
|
}
|
|
r -= 10;
|
|
} else if (index < 72){ // green -> cyan shifting
|
|
if (index == 48){
|
|
r = 0;
|
|
}
|
|
b += 10;
|
|
} else if (index < 96){ // cyan -> blue shifting
|
|
if (index == 72){
|
|
b = 255;
|
|
}
|
|
g -= 10;
|
|
} else if (index < 120){ // blue -> magenta shifting
|
|
if (index == 96){
|
|
g = 0;
|
|
}
|
|
r += 10;
|
|
} else { // magenta -> red shifting
|
|
if (index == 120){
|
|
r = 255;
|
|
}
|
|
b -= 10;
|
|
}
|
|
}
|
|
pixel.show();
|
|
}
|
|
|
|
public:
|
|
void update(){
|
|
unsigned long now = millis();
|
|
if (now - wait > last){
|
|
last = now;
|
|
rainbow();
|
|
offset += 1;
|
|
if (offset == num_pixels){
|
|
offset = 0;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Strip strip = Strip(6, 144, 100);
|
|
|
|
void setup(void) {
|
|
while (!Serial); // required for Flora & Micro
|
|
Serial.begin(115200);
|
|
bluetooth_setup();
|
|
strip.off();
|
|
Serial.println(F("setup() finished"));
|
|
}
|
|
|
|
void loop(void) {
|
|
if (irq_event_available) {
|
|
ble.handleDfuIrq();
|
|
}
|
|
strip.update();
|
|
}
|