working demo, with iPhone support

Dependencies:   NeoPixels NeoStrip mbed

Fork of NeoPixels by Allen Wild

main.cpp

Committer:
aswild
Date:
2014-03-12
Revision:
0:f38492690f0e
Child:
1:3b59b44884cd

File content as of revision 0:f38492690f0e:

/*
 * Adafruit NeoPixel 8x8 matrix example
 *
 * This program displays a couple simple patterns on an 8x8 NeoPixel matrix.
 *
 * 3 buttons are used for DigitalIns, 2 control the brightness up and down,
 * and the third switches patterns
 */

#include "mbed.h"
#include "NeoStrip.h"
#include "gt.h"

#define N 64
#define PATTERNS 3

int hueToRGB(float h);
void pattern0();
void pattern1();
void pattern2();

// array of function pointers to the various patterns
void (*patterns[])(void) = {&pattern0, &pattern1, &pattern2};

NeoStrip strip(p18, N);
DigitalIn b1(p20); // brightness up
DigitalIn b2(p19); // brightness down
DigitalIn b3(p21); // next pattern

// timer used for debugging
Timer timer;

int main()
{
	b1.mode(PullDown);
	b2.mode(PullDown);
	b3.mode(PullDown);
	
	int pattern = 0;
	float bright = 0.2;	// 20% is plenty for indoor use
	bool b3o = b3;		// old copy of button 3 to poll for changes

	strip.setBrightness(bright);	// set default brightness
	
	while (true)
	{
		timer.reset(); // use a timer to measure loop execution time for debugging purposes
		timer.start(); // for this application, the main loop takes approximately 3ms to run

		// button 1 increases brightness
		if (b1 && bright < 1)
		{
			bright += 0.01;
			if (bright > 1)
				bright = 1;
			strip.setBrightness(bright);
		}

		// button 2 decreases brightness
		if (b2 && bright > 0)
		{
			bright -= 0.01;
			if (bright < 0)
				bright = 0;
			strip.setBrightness(bright);
		}
		
		// button 3 changes the pattern, only do stuff when its state has changed
		if (b3 != b3o)
		{
			if (b3 && ++pattern == PATTERNS)
				pattern = 0;
			b3o = b3;
		}
		
		// run the pattern update function which sets the strip's pixels
		patterns[pattern]();
		strip.write();

		timer.stop();
		// print loop time if b3 is pressed
		if (b3)
			printf("Loop Time: %dus\n", timer.read_us());
		
		wait_ms(10);
	}
}

// pattern0 displays a static image
void pattern0()
{
	strip.setPixels(0, N, gt_img);
}

// display a shifting rainbow, all colors have maximum
// saturation and value, with evenly spaced hue
void pattern1()
{
	static float dh = 360.0 / N;
	static float x = 0;

	for (int i = 0; i < N; i++)
		strip.setPixel(i, hueToRGB((dh * i) - x));
	
	x += 1;
	if (x > 360)
		x = 0;
}

// display a shifting gradient between red and blue
void pattern2()
{
	// offset for each pixel to allow the pattern to move
	static float x = 0;

	float r, b, y;

	for (int i = 0; i < N; i++)
	{
		// y is a scaled position between 0 (red) and 1.0 (blue)
		y = 1.0 * i / (N - 1) + x;
		if (y > 1)
			y -= 1;

		// if on the left half, red is decreasing and blue is increasng
		if (y < 0.5)
		{
			b = 2 * y;
			r = 1 - b;
		}

		// else red is increasing and blue is decreasing
		else
		{
			r = 2 * (y - 0.5);
			b = 1 - r;
		}

		// scale to integers and set the pixel
		strip.setPixel(i, (uint8_t)(r * 255), 0, (uint8_t)(b * 200));
	}

	x += 0.003;
	if (x > 1)
		x = 0;
}

// Converts HSV to RGB with the given hue, assuming
// maximum saturation and value
int hueToRGB(float h)
{
	// lots of floating point magic from the internet and scratching my head
	float r, g, b;
	if (h > 360)
		h -= 360;
	if (h < 0)
		h += 360;
	int i = (int)(h / 60.0);
	float f = (h / 60.0) - i;
	float q = 1 - f;
	
	switch (i % 6)
	{
		case 0: r = 1; g = f; b = 0; break;
		case 1: r = q; g = 1; b = 0; break;
		case 2: r = 0; g = 1; b = f; break;
		case 3: r = 0; g = q; b = 1; break;
		case 4: r = f; g = 0; b = 1; break;
		case 5: r = 1; g = 0; b = q; break;
		default: r = 0; g = 0; b = 0; break;
	}
	
	// scale to integers and return the packed value
	uint8_t R = (uint8_t)(r * 255);
	uint8_t G = (uint8_t)(g * 255);
	uint8_t B = (uint8_t)(b * 255);

	return (R << 16) | (G << 8) | B;
}