Using TinyBrite

The overview provides an outline of how things work, as well as circuitry and power considerations.  Here we’ll present working (Arduino) code for a couple of scenarios for using TinyBrite to control a chain of MegaBrites/ShiftBrites, namely:

Basic Usage

In most non-trivial applications, you use TinyBrite by:

  •  creating a TinyBrite object, and setting it up
  •  sending color (or command) data in discreet update cycles.

Basic usage might look like this on an Arduino:

        // include the library
        #include <TinyBrite.h>

	// define a few values
	#define num_chained_brites	3

	#define clockpin  0
	#define latchpin  2
	#define datapin   3

	// create the megabrite chain, as a global here
	TinyBrite brite_chain(num_chained_brites, TINYBRITE_AUTOUPDATE_ENABLE); 
        // three daisy-chained *brites, auto-updated.

	void setup() {
		// setup the pins to use
		brite_chain.setup(datapin, clockpin, latchpin);
	}

	void loop () {
		// send colors as desired, using sendColor(R,G,B)
		brite_chain.sendColor(0, 0, TINYBRITE_COLOR_MAXVALUE); // blue

		brite_chain.sendColor(TINYBRITE_COLOR_MAXVALUE, 0, 0); // red

		brite_chain.sendColor(500, 500, 0); // any mix of RGB

		// our 3-chained brites will now look like:
		// Arduino -> Yellow -> Red -> Blue

		delay(1000);
	}

Auto-Updating

Using beginUpdate()/endUpdate() around each set of updates ensures that the changes are configured for all the ‘brites prior to actually switching the colors displayed.  This is good in that it allows your updates to happen “instantaneously” (from an observer’s perspective) and can be important if you have long chains of ‘brites to configure.

If you don’t care about potentially seeing the transitions (or maybe some blinking), or are only using a few MegaBrites/ShiftBrites, then you can simplify your code by configuring the TinyBrite object to auto-update.  This setting makes it so TinyBrite performs the begin/end update for you (basically, latching every setting as it is sent), thereby freeing you from a little typing and complexity in your code.

The code above, modified to use auto-update, looks like this instead:

	// include the library
	#include <TinyBrite.h>

	// define a few values
	#define num_chained_brites   3

	#define clockpin  0
	#define latchpin  1
	#define datapin   2

	#define waitms 	  300

	// create the megabrite chain, as a global here
	TinyBrite brite_chain(num_chained_brites, TINYBRITE_AUTOUPDATE_ENABLE); 
        // 3 daisy-chained *brites, with auto-update

	void setup() {
		// setup the pins to use, same as before
		brite_chain.setup(datapin, clockpin, latchpin);
	}

	void loop () {
		// send colors as desired, using sendColor(R,G,B)

		// send updates, but forget about 
		// beginUpdate()/endUpdate(), in this case

		brite_chain.sendColor(0, 0, TINYBRITE_COLOR_MAXVALUE); // blue
		brite_chain.sendColor(0, TINYBRITE_COLOR_MAXVALUE, 0); // green
		brite_chain.sendColor(TINYBRITE_COLOR_MAXVALUE, 0, 0); // red

		// our 3-chained brites will now look like:
		// Arduino -> Red -> Green -> Blue

		delay(waitms); // wait a bit

		brite_chain.sendColor(0, 0, TINYBRITE_COLOR_MAXVALUE); // only blue

		// our 3-chained brites will now look like:
		// Arduino -> Blue -> Red -> Green 
		// (blue got pushed on the chain, and shifted red+green down one)

		delay(waitms); // wait a bit

		brite_chain.sendColor(0, TINYBRITE_COLOR_MAXVALUE, 0); // only green

		// our 3-chained brites will now look like:
		// Arduino -> Green -> Blue -> Red

		delay(waitms); // wait a bit

	}

This makes the coding cleaner, and there’s no risk of forgetting an endUpdate() call somewhere…

Finally, you can mix-and-match coding styles, by using the TinyBrite object’s setAutoUpdate() method.  With this, you could keep simple code straightforward:

// ... stuff happens, then
brite_chain.setAutoUpdate(true); // enable auto-updates

// ...

// push a red value on the chain
brite_chain.sendColor(TINYBRITE_COLOR_MAXVALUE, 0, 0);

// ... later, something more involved:
brite_chain.setAutoUpdate(false); //back to manual mode

brite_chain.beginUpdate(); // start an update cycle

brite_chain.sendColor(0, 0, TINYBRITE_COLOR_MAXVALUE); // blue
brite_chain.sendColor(0, TINYBRITE_COLOR_MAXVALUE, 0); // green
brite_chain.sendColor(TINYBRITE_COLOR_MAXVALUE, 0, 0); // red

brite_chain.sendColor(0, 0, 0); // black
brite_chain.sendColor(440, 260, 900); // something

brite_chain.endUpdate(); // all changes take effect

Creating and using packets

You can use sendColor() exclusively as above, but if you want to easily store color settings you’re better off using BritePackets.  A BritePacket is a complete RGB setting for a specific color (or a command, as explained by the MegaBrite docs).  The easiest way to create a BritePacket is with the TinyBrite classmethods:

BritePacket some_color = TinyBrite.colorPacket(red_value, green_value, blue_value);

You can send a packet using:

brite_chain.sendPacket(some_color);

or set the color for all ‘brites in the chain using:

brite_chain.sendPacketToAll(some_color);

If you want to send a bunch of packets, prepare an array and use sendPackets():

 BritePacket lotsa_colors[20];
 lotsa_colors[0] = TinyBrite.colorPacket(0,0,0);
 lotsa_colors[1] = TinyBrite.colorPacket(40,40,10);
 // ...
 lotsa_colors[18] = TinyBrite.colorPacket(900, 900, 250);
 lotsa_colors[19] = TinyBrite.colorPacket(1020, 1020, 500);
 // send them all (passing pointer to first packet and total num):
 brite_chain.sendPackets(&aBunch[lotsa_colors], 20);

Command packets

In some cases, you may want to set correction/clock settings using command packets.  These function much like color packets, and are encapsulated in the same structure (the BritePacket):

BritePacket some_command = commandPacket(redCorrect, greenCorrect, 
                                             blueCorrect, clockMode);

The correction values should be between 0 and TINYBRITE_CORRECTION_MAXVALUE (127) and the clock mode must be one of:

  • TINYBRITE_COMMAND_CLOCK_800kHz
  • TINYBRITE_COMMAND_CLOCK_400kHz
  • TINYBRITE_COMMAND_CLOCK_200kHz
  • TINYBRITE_COMMAND_CLOCK_EXT

State tracking

In cases where you want to know the current value of one of your ShiftBrites/MegaBrites, you can use TinyBrite’s built-in state tracking.  This can be useful whenever you have some random, or user-generated, settings and you want to retrieve them.

To use state tracking, you need to enable it beforehand using:

brite_chain.setStateTracking(true);

Then, after the ‘brites have been set, you can query the current settings by calling getState(BRITE_INDEX) and casting the result to a BritePacket:

// get the state of the first 'brite in the chain (count as an
// array, i.e. starting at 0):
BritePacket * a_packet_ptr = (BritePacket*) brite_chain.getState(0);

Now this packet is a pointer to the (internal) buffer, and it is subject to change any time a color or command is sent… so if you want to store it for later, you make a copy.  The easiest way is just:

BritePacket packet_i_want_to_keep = *a_packet_ptr;

You can also use the saveState()/restoreState() methods to … well, do just that: they allow you to get and restore the state of the entire chain.  See the library code for details, or get back to me if you’re playing with that stuff–I’d like to help and would be interested to know what you’re doing!

Final note on state tracking: if you are using both command and color packets, only the last packet sent is tracked and will be returned so it might be a command packet.  You can check the type of packet by comparing it’s mode_pwm to TINYBRITE_PACKETMODE_COLOR:

 if (a_packet.mode_pwm == TINYBRITE_PACKETMODE_COLOR)
 {
     // it's a color packet
     // ...
 } else if (a_packet.mode_pwm == TINYBRITE_PACKETMODE_COMMAND)
 {
     // it's a command
     // ...
 } else {
     // shouldn't happen!
 }

Complete Examples

The library contains an examples/ folder with a few working Arduino programs.  If you’ve installed the library and are using the Arduino IDE, you’ll find these under Examples -> TinyBrite.

BriteChain

This is a complete example which exercises a number of TinyBrite methods for a single chain of Shift/MegaBrites.  It has a ton of commentary and shows most of the useful functions.  BriteChain.ino

BriteChainAuto

This is a simplified version of the BriteChain example above, which demonstrates the use of auto-updating. BriteChainAuto.ino

StateTrackingGame

The StateTrackingGame example is a simple game, or toy, where you need to press a button when the light is red.  It’s a bit convoluted, in terms of being a example of state tracking, but it was fun to do and surprisingly fun to play with!  StateTrackingGame.ino

 

Other Uses

You’ve now seen pretty much every aspect of using TinyBrite.  A description of all the important methods is available on the API page.  Please get the library and try it out, then let me know how it goes and what you’re using it for!

Project Pages:
TinyBrite Overview