# Advanced Examples

## Advanced packet handling

In the usual flow of SFB affairs, packets are input from any of the four faces and are reacted to, and output packets are sent out to any of the four faces, from packet handlers, Alarm handlers, or the loop() method. But sometimes more fine-grained control over packet handling is needed, and the core software provides more advanced mechanisms for that purpose.

- Reacting to conscious packets

- Creating packets in memory

## Controlling the built-in LEDs without delays

For debugging, display, or just fun, we often want to blink the onboard LEDs in response to events. The 'good old-fashioned way' to blink an LED is (1) Turn it on, then (2) Delay for a while, then (3) turn it off, but if we do that -- step (2) specifically -- inside a packet (or alarm) handler, we can run into trouble. Since only one handler runs at a time, all handler functions (packet or alarm) need to be relatively quick, to give the other handlers a chance. But calling delay() is the opposite of being quick.

The QLED object (an instance of SFBQLED) provides a way to schedule LED 'on' and 'off' 'events' without calling delay().

- Blink LEDs from a packet handler without blocking

## Advanced EEPROM usage

In the basic tutorials, Using the EEPROM illustrated the primary functions used for accessing the EEPROM. Here we touch on one additional function -- eepromWait() -- and look at an advanced mechanism for initializing EEPROM data.

- Waiting for EEPROM writes to finish

- Use a checksum to validate/initialize EEPROM

## Using hardware timers

As an advanced technique, if you need more accurate timing than the `Alarms` system provides, you can use a hardware timer. There are three hardware timers specifically reserved for sketch use, named `Timer1`, `Timer2`, and `Timer3`. In addition, there is a fourth timer (named `Timer4`, naturally) also available, but that hardware is shared with the hardware PWM (Pulse Width Modulation, see Using the hardware PWM module) system, so a single sketch cannot use both hardware PWM and `Timer4`.

Hardware timers are a more advanced topic, primarily because (unlike with `Alarms`) the 'handler' functions you write are executed with interrupts disabled, meaning that while your handler is running, nothing else is happening -- no input is being read, no output is being shipped, the millis() clock isn't ticking, and so on. So you need to keep your timer handler functions relatively short and simple as much as possible.

But, that said, don't be afraid! Sometimes a hardware timer is just the right tool for the job!

- Blink an LED using a hardware timer

- Configure a twelve hour clock

- Red light Green light

- A whiter shade of blinky

## Profiling sketch behavior

As you add more and more behavior to your sketch, as you pile on more and more alarm and packet handlers, you will at some point begin to overtax the hardware and performance will suffer, and packets will get dropped, or alarm handlers will run later than scheduled, or the like. To help determine where time is actually being consumed, the core software provides a basic 'profiling' system consisting of two objects, a low-level object called Ticker, and a higher-level object called Profile.

The Ticker assigns microseconds to one of several broad categories (see SFBTickerCategories) like 'packet handler' or 'alarm handler', which are just what you would expect, or 'background processing', which includes time spent in the `setup()` and `loop()` functions as well as whatever isn't categorized somewhere else. Also, there are three categories (e.g., TICKER_SKETCH0) reserved for whatever execution-time-counting needs you may have. `Ticker`, an instance of SFBTicker, is built into the core software; its primary limitation is that its microsecond-based counters overflow after about an hour, just like micros().

The Profile operates with millisecond resolution, so it can count well over a month of time without overflowing, using the same set of SFBTickerCategories. It gathers data from Ticker and uses an alarm to reset Ticker regularly to keep it from overflowing (so if Profile is active, results returned from SFBTicker::getUsec(u32) may be somewhat hard to interpret -- use SFBProfile::getMsec(u32) instead).

- Demonstrate the low-level 'Ticker'

- Report a time profile of a sketch

- Use a custom profile category

## Changing the processor speed on the fly

The examples in Configuring the processor speed only demonstrated changing the processor speed in the setup() function. It is possible to change the Processor speed at any point(s) during a single sketch execution, but the sketch writer should be aware of some limitations and warnings before they try to do so. See SFBProcessor::setCode() for the details.

- Change processor speed on the fly

- Dynamic throttling of processor speed

## Extending printf/scanf with 'custom Z handlers'

Traditional printf and scanf functions excel at handling data using built-in formats such as decimal. The printf/scanf-style functions in the SFB core, such as facePrintf and packetScanf, have an extension called 'custom Z handlers', which enable you to define your own CustomPrintfHandler (which see, for details) and/or CustomPacketScanfHandler, and then handle formats involving mixtures of traditional formats and your custom format.

- Custom Z handlers to double a char

- Formatted I/O of 2D coordinates using custom Z handlers

- Custom Z handlers using recursion

## Using the hardware PWM module

--TO COME--

## Controlling power

--TO COME--