API

This page will detail all the important TinyBrite methods. See the overview for a quickstart and details on circuitry, or the Using TinyBrite page for a more in-depth look at real-world usage.

Construction

	
	TinyBrite(uint8_t num_brites, bool auto_update_cycle =
			TINYBRITE_AUTOUPDATE_DISABLE);

Call the constructor with the number of MegaBrites/ShiftBrites in the chain. You may optionally pass a second parameter to enable auto-updating, e.g.

	TinyBrite my_chain = TinyBrite(3, TINYBRITE_AUTOUPDATE_ENABLE);

Configuration

	setup(uint8_t datapin, uint8_t clockpin, uint8_t latchpin [, uint8_t nEnablepin]);

Register and configure the pins used for data, clock and latch using setup() by passing it the pin numbers for data, clock and latch. The optional 4th parameter is used to specify the ~enable pin, if you want to manually enable and disable the chain.

Update Cycle

Unless you’re using auto-update, every block of packets you send (using sendColor() or one of the sendPacket*() methods) should be wrapped by a beginUpdate()/endUpdate().

	void beginUpdate();

The beginUpdate() methods begins an update cycle. The cycle ends, and the changes all take effect, when endUpdate() is called.

	DriverNum endUpdate();

Calling endUpdate() ends the update cycle, and all changes take effect immediately. This method returns the number of packets sent to the chain during the cycle. E.g.

	// send a new color to all the 'brites

	// start the update cycle
	my_chain.beginUpdate()

	// send the colors
	my_chain.sendColor(500,0,0);
	my_chain.sendColor(0,0,0);
	my_chain.sendColor(0,0,500);
	// ...

	// make it happen:
	my_chain.endUpdate();

Auto-Update

With auto-updating, you avoid needing to wrap all your packet sends with beginUpdate()/endUpdate()–the latching happens automatically on every send. The downside is that it will slow down transmission (because of the required delay in latching every packet as it’s sent) and may cause transient states of illumination to appear (e.g. if you are sending many different colors to a large number of ShiftBrites, these colors will travel down the chain as they get pushed out).

	void setAutoUpdate(bool setToEnabled);

In addition to specifying the auto-update setting with the constructor, you can use setAutoUpdate() to turn auto-updating on or off.

	bool autoUpdate();

Returns current state of auto-update setting.

Setting Colors and Commands

	void sendColor(TinyBriteColorValue red, 
			TinyBriteColorValue green, 
			TinyBriteColorValue blue);

The sendColor() method is the simplest way to send color info to the ‘brites. The color must be a value between 0 and 1023.

Note that, unless you set auto-updating, calls to sendColor() need to be wrapped by begin- and endUpdate()s.

If you want to send a color repeatedly, either in a single update cycle or in various places in your code, you should use the sendPacket() method described below.

	void sendCommand(unsigned int redDotCorrect, 
			unsigned int greenDotCorrect,
			unsigned int blueDotCorrect, 
			unsigned char clockMode);

The sendCommand() method is used to send correction and clock mode setting commands to the MegaBrites, see the commandPacket() description below for details on the parameters.

Creating And Using BritePackets

In many circumstances, creating and manipulating BritePacket structs will make your code more efficient and concise.

Packet Creation

	BritePacket colorPacket(TinyBriteColorValue red, TinyBriteColorValue green,
			TinyBriteColorValue blue);

	BritePacket commandPacket(unsigned int redCorrect0,
			unsigned int greenCorrect1, unsigned int blueCorrect2,
			unsigned char clockMode);

If you want to store color (or command) settings, you create BritePackets using the class methods above.

The methods may be called with or without a TinyBrite object, e.g.

	BritePacket a = my_chain.colorPacket(800, 0, 0);

	// or equivalently:
	BritePacket b = TinyBrite::colorPacket(800, 0, 0);

	// one advantage of the classmethod is that you can initialize global arrays
	// even before you have a TinyBrite object at hand, e.g.

	#define on_value  1023
	BritePacket startup_colors[6] = {
				TinyBrite::colorPacket(0, 0, on_value), // blue
				TinyBrite::colorPacket(0, on_value, 0), // green
				TinyBrite::colorPacket(on_value, 0, 0), // red
				TinyBrite::colorPacket(0, 0, on_value), // blue
				TinyBrite::colorPacket(0, on_value, 0), // green
				TinyBrite::colorPacket(on_value, 0, 0) // red

	};

For color packets, the value for each RGB component must be between 0 and 1023. For command packets, the correction values should be between 0 and 127 while the clockMode must be one of:

  • TINYBRITE_COMMAND_CLOCK_800kHz
  • TINYBRITE_COMMAND_CLOCK_400kHz
  • TINYBRITE_COMMAND_CLOCK_200kHz
  • TINYBRITE_COMMAND_CLOCK_EXT

If you don’t know what these mean, check the MegaBrite docs.

Sending Packets

	void sendPacket(BritePacket packet, [uint8_t number_of_times]);

Use sendPacket() to send a single BritePacket to the chain. If you want to send the packet multiple times, specify how many using the second number_of_times parameter.

If you just want to send the color to all the ‘brites, you can use sendPacketToAll() below.

	void sendPacketToAll(BritePacket packet);

If you want to send a given packet to every Shift/MegaBrite in this chain, use sendPacketToAll().

	void sendPackets(BritePacket * packets, uint8_t numPackets);

If you have a number of packets to send stored in an array, using sendPackets() (note the plural) is the way to go. You’ll need to pass a pointer to the first element in the list, as well as the number of packets in total as parameters. E.g.

	#define on_value   512
	BritePacket startup_colors[6] = {
				TinyBrite::colorPacket(0, 0, on_value), // blue
				TinyBrite::colorPacket(0, on_value, 0), // green
				TinyBrite::colorPacket(on_value, 0, 0), // red
				TinyBrite::colorPacket(0, 0, on_value), // blue
				TinyBrite::colorPacket(0, on_value, 0), // green
				TinyBrite::colorPacket(on_value, 0, 0) // red

	}; 

	// ...

	// set every color
	my_chain.beginUpdate();
	my_chain.sendPackets( &(startup_colors[0]), 6);
	my_chain.endUpdate();

State Tracking

State tracking is discussed on the usage page. In essence, it allows you to query TinyBrite about the state of a given module in the chain.

	bool setStateTracking(bool setTo);

To use state tracking, it must first be enabled and this is done by passing a true value to setStateTracking(). The method returns true if state tracking is enabled after the call. Enabling state tracking may fail in certain circumstances, if you are getting NULLs returned by getState() after enabling state tracking this is probably why… you may want to do something like:

	bool state_tracking_enabled = my_brite_chain.setStateTracking(true);
	if (! state_tracking_enabled)
	{
		Serial.println("ERROR! Could not enable state tracking");
	}

Basically if you don’t have enough RAM available for the ring buffer in which state is preserved, the call to enable state tracking will fail. The functionality only needs 32 bits per ‘brite in the chain, so this shouldn’t be an issue too often.

	bool stateTracking();

Returns true if state tracking is enabled.

StatePacket * getState(DriverNum driver_index);

You can get the current state of a module using getState(). The pointer returned may be cast to a BritePacket, to access it’s contents, e.g.

	BritePacket * cur_state = (BritePacket*) my_chain.getState(0);

	Serial.print("Red is at: ");
	Serial.println(cur_state->red, DEC);

Note that this pointer is pointing at an internal value–which may change any time packets are sent–so if you want to keep it for later, make a local copy:

	// keep the current state for later:
	BritePacket the_old_state = *cur_state;

For more info, see the state tracking discussion on the TinyBrite usage page.

	DriverNum saveState(StatePacket * a_state_vector);

If you want to preserve the state of the entire chain, and state tracking has been enabled, you can do so using saveState(). This function requires a pointer to an array of StatePackets that can hold at least as many packets as there are modules in the chain.

You can either use a static array (but be sure to pass the pointer to the first element):

	StatePacket preserved_states[NUMBER_OF_BRITES];

	// save the state
	brite_chain.saveState(&(preserved_states[0]));

or you can dynamically allocate the array:

	StatePacket * state_vector = (StatePacket*)malloc(sizeof(StatePacket) * NUMBER_OF_BRITES );

	// TODO: check that state_vector != NULL

	// save the state
	brite_chain.saveState(state_vector);

Either way, the list should now contain a StatePacket (which may be cast to BritePacket) for each module in the chain. You can use this to save state to ROM and/or to restore it later.

	void restoreState(StatePacket * a_state_vector);

Call restoreState() with an appropriate vector (a pointer to an array) to restore a chain of ‘brites to that previous state.

Project Pages:
TinyBrite Overview