Commit d9e5da97 authored by Mitchell Pomery's avatar Mitchell Pomery

Initial Commit

Code so far.
parents
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
/*
BlinkenLights
by Mitchell Pomery [BG3] with help from Andrew Adamson [BOB]
modified 20 Jan 2014
*/
///TODO: Vary light pattern randomly
///TODO: Make run when no network is present
///TODO: Recover when network reappears
#include <Ethernet.h> // Needed For Reasons
#include <WebServer.h> // Lets us easily do web requests
#include <SPI.h> // Needed to control Lights
#include <Adafruit_NeoPixel.h> // Controls the Lights
#define STRIPLENGTH 42 // Number of LED's in light strip
#define PIN 6 // Pin that the LED strip is attached to
#define PREFIX "" // Document root for our pages
#define PORT 80 // Web Server Port
#define NAMELEN 8 // Max variable length in request
#define VALUELEN 256 // Max value from request
#define WIDTH // How many LEDs wide our array is
#define HEIGHT // How many LEDs high our array is
// Used to store the LED's values
struct led {
char red;
char green;
char blue;
};
int position = 0;
// led array
struct led ledArray[STRIPLENGTH];
char brightness = (char) 128;
static uint8_t mac[] = { 0xC0, 0xCA, 0xC0, 0x1A, 0x19, 0x82 }; // C0CA C01A 1982
IPAddress ip(130,95,13,96);
int lightOption = 0;
// Set up our light strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIPLENGTH, PIN, NEO_GRB + NEO_KHZ800);
// Set up our webserver
WebServer webserver(PREFIX, 80);
// showArray
void showArray() {
for (int i = 0; i < STRIPLENGTH; i ++) {
strip.setPixelColor(i, (int) ledArray[i].red, (int) ledArray[i].green, (int) ledArray[i].blue);
}
strip.show();
}
// setLED
void setLED(int pos, int red, int green, int blue) {
ledArray[pos].red = red;
ledArray[pos].green = green;
ledArray[pos].blue = blue;
}
// Sets the light sequence to one that is predefined
void webSetSequence(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
URLPARAM_RESULT rc;
char name[NAMELEN];
char value[VALUELEN];
server.httpSuccess();
// Kill the connection before doing anything if all they want is the head
if (type == WebServer::HEAD) {
return;
}
else if (type == WebServer::POST) {
while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
{
//Serial.print(name);
//Serial.print(" = ");
//Serial.println(value);
//if (name == "seq") {
// lightOption = value;
//}
}
}
else if (type == WebServer::GET) { //WebServer::POST
if (strlen(url_tail)) {
while (strlen(url_tail)) {
rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
if (rc != URLPARAM_EOS) {
//Serial.println(name);
//Serial.println(value);
if (String(name).equals("seq")) {
lightOption = atoi(value);
server.print(lightOption);
}
}
}
}
///TODO: Get ?seq=X and set lightOption to X
}
else {
server.print("Unknown");
}
}
void webSetLED(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
URLPARAM_RESULT rc;
char name[NAMELEN];
char value[VALUELEN];
int xPos = -1;
int yPos = -1;
int r = -1;
int g = -1;
int b = -1;
server.httpSuccess();
// Kill the connection before doing anything if all they want is the head
if (type == WebServer::HEAD) {
return;
}
else if (type == WebServer::POST) {
while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
{
//Serial.print(name);
//Serial.print(" = ");
//Serial.println(value);
//if (name == "seq") {
// lightOption = value;
//}
}
}
else if (type == WebServer::GET) { //WebServer::POST
if (strlen(url_tail)) {
while (strlen(url_tail)) {
rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
if (rc != URLPARAM_EOS) {
//Serial.println(name);
//Serial.println(value);
if (String(name).equals("x")) {
xPos = atoi(value);
}
else if (String(name).equals("y")) {
yPos = atoi(value);
}
else if (String(name).equals("r")) {
r = atoi(value);
}
else if (String(name).equals("g")) {
g = atoi(value);
}
else if (String(name).equals("b")) {
b = atoi(value);
}
}
}
}
}
else {
server.print("Unknown");
}
//Serial.println(xPos);
//Serial.println(yPos);
//Serial.println(r);
//Serial.println(g);
//Serial.println(b);
if (xPos != -1 && yPos != -1 && r != -1 && g != -1 && b != -1) {
setLED(xPos, r, g, b);
}
}
void webSetBrightness(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
URLPARAM_RESULT rc;
char name[NAMELEN];
char value[VALUELEN];
int xPos = -1;
int yPos = -1;
int r = -1;
int g = -1;
int b = -1;
server.httpSuccess();
// Kill the connection before doing anything if all they want is the head
if (type == WebServer::HEAD) {
return;
}
else if (type == WebServer::POST) {
while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
{
//Serial.print(name);
//Serial.print(" = ");
//Serial.println(value);
//if (name == "seq") {
// lightOption = value;
//}
}
}
else if (type == WebServer::GET) { //WebServer::POST
if (strlen(url_tail)) {
while (strlen(url_tail)) {
rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
if (rc != URLPARAM_EOS) {
//Serial.println(name);
//Serial.println(value);
if (String(name).equals("brightness")) {
strip.setBrightness(atoi(value));
}
}
}
}
}
else {
server.print("Unknown");
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+position) & 255));
}
strip.show();
delay(wait);
position++;
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
void setup() {
// Open //Serial communications and wait for port to open:
//Serial.begin(9600);
//while (!//Serial) {
//; // wait for //Serial port to connect. Needed for Leonardo only
//}
//Serial.println("//Serial Port Opened");
// start the Ethernet connection and the server:
//Serial.println("Starting Ethernet");
Ethernet.begin(mac, ip);
//Serial.println("Setting Up Server");
webserver.setDefaultCommand(&webSetSequence);
webserver.addCommand("custom", &webSetSequence);
webserver.addCommand("individual", &webSetLED);
webserver.addCommand("brightness", &webSetBrightness);
//Serial.println("Starting Server");
webserver.begin();
//Serial.print("server is at ");
//Serial.println(Ethernet.localIP());
// Initialize our LED Array
for (int i = 0; i < STRIPLENGTH; i ++) {
ledArray[i].red = (char) 128;
ledArray[i].green = (char) 128;
ledArray[i].blue = (char) 128;
}
// Start Lights
strip.begin();
//strip.show();
strip.setBrightness(32);
showArray();
}
void loop()
{
// process incoming connections one at a time forever
char buff[64];
int len = 64;
webserver.processConnection(buff, &len);
position = position % 256;
rainbow(10);
// Run our light sequence after checking for we requests
/*switch (lightOption) {
case 0:
break;
case 1:
colorWipe(strip.Color(255, 0, 0), 50); // Red
break;
case 2:
colorWipe(strip.Color(0, 255, 0), 50); // Green
break;
case 3:
colorWipe(strip.Color(0, 0, 255), 50); // Blue
break;
case 4:
theaterChase(strip.Color(127, 127, 127), 50); // White
break;
case 5:
theaterChase(strip.Color(127, 0, 0), 50); // Red
break;
case 6:
theaterChase(strip.Color( 0, 0, 127), 50); // Blue
break;
case 7:
rainbow(100);
break;
case 8:
rainbowCycle(20);
break;
case 9:
theaterChaseRainbow(50);
break;
default:
lightOption = 7;
break;
}*/
showArray();
}
/*-------------------------------------------------------------------------
Arduino library to control a wide variety of WS2811- and WS2812-based RGB
LED devices such as Adafruit FLORA RGB Smart Pixels and NeoPixel strips.
Currently handles 400 and 800 KHz bitstreams on 8, 12 and 16 MHz ATmega
MCUs, with LEDs wired for RGB or GRB color order. 8 MHz MCUs provide
output on PORTB and PORTD, while 16 MHz chips can handle most output pins
(possible exception with upper PORT registers on the Arduino Mega).
Written by Phil Burgess / Paint Your Dragon for Adafruit Industries,
contributions by PJRC and other members of the open source community.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing products
from Adafruit!
-------------------------------------------------------------------------
This file is part of the Adafruit NeoPixel library.
NeoPixel is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "Adafruit_NeoPixel.h"
Adafruit_NeoPixel::Adafruit_NeoPixel(uint16_t n, uint8_t p, uint8_t t) : numLEDs(n), numBytes(n * 3), pin(p), pixels(NULL)
#if defined(NEO_RGB) || defined(NEO_KHZ400)
,type(t)
#endif
#ifdef __AVR__
,port(portOutputRegister(digitalPinToPort(p))),
pinMask(digitalPinToBitMask(p))
#endif
{
if((pixels = (uint8_t *)malloc(numBytes))) {
memset(pixels, 0, numBytes);
}
}
Adafruit_NeoPixel::~Adafruit_NeoPixel() {
if(pixels) free(pixels);
pinMode(pin, INPUT);
}
void Adafruit_NeoPixel::begin(void) {
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void Adafruit_NeoPixel::show(void) {
if(!pixels) return;
// Data latch = 50+ microsecond pause in the output stream. Rather than
// put a delay at the end of the function, the ending time is noted and
// the function will simply hold off (if needed) on issuing the
// subsequent round of data until the latch time has elapsed. This
// allows the mainline code to start generating the next frame of data
// rather than stalling for the latch.
while((micros() - endTime) < 50L);
// endTime is a private member (rather than global var) so that mutliple
// instances on different pins can be quickly issued in succession (each
// instance doesn't delay the next).
// In order to make this code runtime-configurable to work with any pin,
// SBI/CBI instructions are eschewed in favor of full PORT writes via the
// OUT or ST instructions. It relies on two facts: that peripheral
// functions (such as PWM) take precedence on output pins, so our PORT-
// wide writes won't interfere, and that interrupts are globally disabled
// while data is being issued to the LEDs, so no other code will be
// accessing the PORT. The code takes an initial 'snapshot' of the PORT
// state, computes 'pin high' and 'pin low' values, and writes these back
// to the PORT register as needed.
noInterrupts(); // Need 100% focus on instruction timing
#ifdef __AVR__
volatile uint16_t
i = numBytes; // Loop counter
volatile uint8_t
*ptr = pixels, // Pointer to next byte
b = *ptr++, // Current byte value
hi, // PORT w/output bit set high
lo; // PORT w/output bit set low
// Hand-tuned assembly code issues data to the LED drivers at a specific
// rate. There's separate code for different CPU speeds (8, 12, 16 MHz)
// for both the WS2811 (400 KHz) and WS2812 (800 KHz) drivers. The
// datastream timing for the LED drivers allows a little wiggle room each
// way (listed in the datasheets), so the conditions for compiling each
// case are set up for a range of frequencies rather than just the exact
// 8, 12 or 16 MHz values, permitting use with some close-but-not-spot-on
// devices (e.g. 16.5 MHz DigiSpark). The ranges were arrived at based
// on the datasheet figures and have not been extensively tested outside
// the canonical 8/12/16 MHz speeds; there's no guarantee these will work
// close to the extremes (or possibly they could be pushed further).
// Keep in mind only one CPU speed case actually gets compiled; the
// resulting program isn't as massive as it might look from source here.
// 8 MHz(ish) AVR ---------------------------------------------------------
#if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL)
#ifdef NEO_KHZ400
if((type & NEO_SPDMASK) == NEO_KHZ800) { // 800 KHz bitstream
#endif
volatile uint8_t n1, n2 = 0; // First, next bits out
// Squeezing an 800 KHz stream out of an 8 MHz chip requires code
// specific to each PORT register. At present this is only written
// to work with pins on PORTD or PORTB, the most likely use case --
// this covers all the pins on the Adafruit Flora and the bulk of
// digital pins on the Arduino Pro 8 MHz (keep in mind, this code
// doesn't even get compiled for 16 MHz boards like the Uno, Mega,
// Leonardo, etc., so don't bother extending this out of hand).
// Additional PORTs could be added if you really need them, just
// duplicate the else and loop and change the PORT. Each add'l
// PORT will require about 150(ish) bytes of program space.