304 lines
9.6 KiB
C++
304 lines
9.6 KiB
C++
#include <noise.h>
|
||
#include <bitswap.h>
|
||
#include <fastspi_types.h>
|
||
#include <pixelset.h>
|
||
#include <fastled_progmem.h>
|
||
#include <led_sysdefs.h>
|
||
#include <hsv2rgb.h>
|
||
#include <fastled_delay.h>
|
||
#include <colorpalettes.h>
|
||
#include <color.h>
|
||
#include <fastspi_ref.h>
|
||
#include <fastspi_bitbang.h>
|
||
#include <controller.h>
|
||
#include <fastled_config.h>
|
||
#include <colorutils.h>
|
||
#include <chipsets.h>
|
||
#include <pixeltypes.h>
|
||
#include <fastspi_dma.h>
|
||
#include <fastpin.h>
|
||
#include <fastspi_nop.h>
|
||
#include <platforms.h>
|
||
#include <lib8tion.h>
|
||
#include <cpp_compat.h>
|
||
#include <fastspi.h>
|
||
#include <FastLED.h>
|
||
#include <dmx.h>
|
||
#include <power_mgt.h>
|
||
|
||
/*********************************************************************
|
||
This is an example for our nRF51822 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 <string.h>
|
||
#include <Arduino.h>
|
||
#include <SPI.h>
|
||
#include "Adafruit_BLE.h"
|
||
#include "Adafruit_BluefruitLE_SPI.h"
|
||
#include "Adafruit_BluefruitLE_UART.h"
|
||
|
||
|
||
#include "BluefruitConfig.h"
|
||
|
||
|
||
/*=========================================================================
|
||
APPLICATION SETTINGS
|
||
|
||
FACTORYRESET_ENABLE Perform a factory reset when running this sketch
|
||
|
||
Enabling this will put your Bluefruit LE module
|
||
in a 'known good' state and clear any config
|
||
data set in previous sketches or projects, so
|
||
running this at least once is a good idea.
|
||
|
||
When deploying your project, however, you will
|
||
want to disable factory reset by setting this
|
||
value to 0. If you are making changes to your
|
||
Bluefruit LE device via AT commands, and those
|
||
changes aren't persisting across resets, this
|
||
is the reason why. Factory reset will erase
|
||
the non-volatile memory where config data is
|
||
stored, setting it back to factory default
|
||
values.
|
||
|
||
Some sketches that require you to bond to a
|
||
central device (HID mouse, keyboard, etc.)
|
||
won't work at all with this feature enabled
|
||
since the factory reset will clear all of the
|
||
bonding data stored on the chip, meaning the
|
||
central device won't be able to reconnect.
|
||
PIN Which pin on the Arduino is connected to the NeoPixels?
|
||
NUMPIXELS How many NeoPixels are attached to the Arduino?
|
||
-----------------------------------------------------------------------*/
|
||
#define FACTORYRESET_ENABLE 1
|
||
|
||
/*-----------------------------------------------------------------------*/
|
||
#define STRING_PIN 9
|
||
#define ONBOARD_PIN 8
|
||
#define NUM_LED_STRING 9
|
||
#define NUM_LED_ONBOARD 1
|
||
#define NUM_LED NUM_LED_STRING + NUM_LED_ONBOARD
|
||
|
||
#define MIN_BRIGHTNESS 10
|
||
#define MAX_BRIGHTNESS 200
|
||
#define HUE_SPREAD 15
|
||
#define HUE_RATE_MODULO 10 //96 // increasing this value makes the hue change slower
|
||
#define BT_CHECK_CONN_MODULO 20
|
||
#define MIN_SATURATION 192
|
||
#define MAX_SATURATION 255
|
||
#define MIN_RATE 1
|
||
#define MAX_RATE 3
|
||
#define SPEED 20
|
||
|
||
CRGB leds[NUM_LED];
|
||
|
||
byte clock = 0;
|
||
byte globalHue = 0;
|
||
byte hues[NUM_LED + 1];
|
||
int brightnesses[NUM_LED + 1];
|
||
int saturations[NUM_LED + 1];
|
||
int rates[NUM_LED + 1];
|
||
bool isInDataMode = false;
|
||
bool fixedHue = false;
|
||
/*=========================================================================*/
|
||
|
||
// Create the bluefruit object
|
||
Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN);
|
||
|
||
// A small helper
|
||
void error(const __FlashStringHelper*err) {
|
||
Serial.println(err);
|
||
|
||
while (1) {
|
||
// flash red led
|
||
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
|
||
delay(1000); // wait 1 second
|
||
digitalWrite(7, LOW); // turn the LED off by making the voltage LOW
|
||
delay(1000); // wait 1 second
|
||
}
|
||
}
|
||
|
||
// function prototypes over in packetparser.cpp
|
||
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[];
|
||
|
||
|
||
/**************************************************************************/
|
||
/*!
|
||
@brief Sets up the HW an the BLE module (this function is called
|
||
automatically on startup)
|
||
*/
|
||
/**************************************************************************/
|
||
void setup(void)
|
||
{
|
||
//while (!Serial); // required for Flora & Micro
|
||
delay(500);
|
||
|
||
FastLED.addLeds<NEOPIXEL, STRING_PIN>(leds, NUM_LED_STRING);
|
||
FastLED.addLeds<NEOPIXEL, ONBOARD_PIN>(leds, NUM_LED_STRING, NUM_LED_ONBOARD);
|
||
for (int i=0; i<NUM_LED; i++)
|
||
{
|
||
hues[i] = globalHue + random(0,HUE_SPREAD);
|
||
saturations[i] = random(MIN_SATURATION,MAX_SATURATION);
|
||
rates[i] = random(MIN_RATE,MAX_RATE);
|
||
brightnesses[i] = random(MIN_BRIGHTNESS,MAX_BRIGHTNESS);
|
||
}
|
||
|
||
Serial.begin(115200);
|
||
Serial.println(F("Adafruit Bluefruit Neopixel Color Picker Example"));
|
||
Serial.println(F("------------------------------------------------"));
|
||
|
||
/* Initialise the module */
|
||
Serial.print(F("Initialising the Bluefruit LE module: "));
|
||
|
||
if ( !ble.begin(VERBOSE_MODE) )
|
||
{
|
||
error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
|
||
}
|
||
Serial.println( F("OK!") );
|
||
|
||
if ( FACTORYRESET_ENABLE )
|
||
{
|
||
/* Perform a factory reset to make sure everything is in a known state */
|
||
Serial.println(F("Performing a factory reset: "));
|
||
if ( ! ble.factoryReset() ){
|
||
error(F("Couldn't factory reset"));
|
||
}
|
||
}
|
||
|
||
/* Disable command echo from Bluefruit */
|
||
ble.echo(false);
|
||
|
||
Serial.println("Requesting Bluefruit info:");
|
||
/* Print Bluefruit information */
|
||
ble.info();
|
||
//ble.setMode(BLUEFRUIT_MODE_DATA);
|
||
|
||
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();
|
||
}
|
||
|
||
/**************************************************************************/
|
||
/*!
|
||
@brief Constantly poll for new command or response data
|
||
*/
|
||
/**************************************************************************/
|
||
void loop(void)
|
||
{
|
||
// Twinkle
|
||
for (int i=0; i<NUM_LED; i++)
|
||
{
|
||
brightnesses[i] += rates[i];
|
||
// Rate is positive but the new brightness is lower, so we overflowed.
|
||
if (brightnesses[i] >= MAX_BRIGHTNESS)
|
||
{
|
||
// Flip the sign of the rate & start decaying light.
|
||
rates[i] *= -1;
|
||
brightnesses[i] += rates[i];
|
||
}
|
||
// Rate is negative but the new brightness is bigger, so we underflowed.
|
||
else if (brightnesses[i] <= MIN_BRIGHTNESS)
|
||
{
|
||
// reset this pixel to a different color and start anew.
|
||
hues[i] = globalHue + random(0,HUE_SPREAD);
|
||
saturations[i] = random(MIN_SATURATION,MAX_SATURATION);
|
||
rates[i] = random(MIN_RATE,MAX_RATE);
|
||
brightnesses[i] = MIN_BRIGHTNESS;
|
||
}
|
||
else
|
||
{
|
||
brightnesses[i] += rates[i];
|
||
}
|
||
|
||
leds[i] = CHSV(hues[i], saturations[i], brightnesses[i]);
|
||
}
|
||
FastLED.show();
|
||
|
||
clock++;
|
||
if (clock % HUE_RATE_MODULO == 0 && !fixedHue)
|
||
{
|
||
globalHue++;
|
||
}
|
||
|
||
delay(SPEED);
|
||
|
||
if (!isInDataMode) {
|
||
if (clock % BT_CHECK_CONN_MODULO == 0 && ble.isConnected()) { // ble.isConnected() takes time, so don't do it every loop
|
||
isInDataMode = true;
|
||
Serial.println(F("***********************"));
|
||
// Set Bluefruit to DATA mode
|
||
Serial.println( F("Switching to DATA mode!") );
|
||
ble.setMode(BLUEFRUIT_MODE_DATA);
|
||
Serial.println(F("***********************"));
|
||
ble.verbose(false); // debug info is a little annoying after this point!
|
||
}
|
||
return;
|
||
}
|
||
|
||
/* Wait for new data to arrive */
|
||
uint8_t len = readPacket(&ble, BLE_READPACKET_TIMEOUT);
|
||
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);
|
||
|
||
if (red == 0 && blue == 0 && green == 0) {
|
||
// receiving #000000 is a special control color that enables the hue cycle.
|
||
fixedHue = false;
|
||
}
|
||
else {
|
||
CRGB color(red, green, blue);
|
||
CHSV hsv = rgb2hsv_approximate(color);
|
||
globalHue = hsv.hue;
|
||
fixedHue = true;
|
||
}
|
||
|
||
// reset them all
|
||
for (int i=0; i<NUM_LED; i++) {
|
||
hues[i] = globalHue + random(0,HUE_SPREAD);
|
||
saturations[i] = random(MIN_SATURATION,MAX_SATURATION);
|
||
rates[i] = random(MIN_RATE,MAX_RATE);
|
||
brightnesses[i] = MIN_BRIGHTNESS;
|
||
|
||
if (rates[i] < 0) {
|
||
rates[i] = rates[i] * -1;
|
||
}
|
||
}
|
||
|
||
/*
|
||
for(uint8_t i=0; i<NUMPIXELS; i++) {
|
||
pixel.setPixelColor(i, pixel.Color(red,green,blue));
|
||
}
|
||
pixel.show(); // This sends the updated pixel color to the hardware.
|
||
*/
|
||
}
|
||
}
|