Fade Language Reference

Fade is a simple line-oriented language. It has basic looping constructs, conditionals, user-defined functions, and built-in functions.

Variables

Variable names can be any combination of alpha, numeric, and underscore characters, except for those reserved by the language. The first character cannot be a number.

Variables are locally scoped within a specific function.

Values

There are four types of values in Fade. All typing is implicit and determined by usage.

Integers

integers are 4-byte integer values.

Example:

345

Floats

Floats are 4-byte floating-point values

Example:

13.13

Strings

Strings are sequences of characters with opening and closing double-quotes.

Example:

"Here is some text"

Arrays

All integer or float values are implemented as single-valued arrays. Indexes are zero-based.

An array of values can be defined as a constant:

a = {1, 2, 3}

or can be created using array references:

a[0] = 1
a[1] = 2
a[2] = 3

 

Expressions and Operators

Expressions and operators use a "C-style" syntax.

The following operators are supported, in order of precedance:

Operator Description Example
MyFunc(...) Function call GetValue(1, b)
[] Array reference val[33]
() Parentheses (x + 5) * 2
+, - Unary plus or minus +33, -15.5
*, /, % Binary multiplication, division, and modulus 15 * 35
+, - Binary plus or minus x + 128
<, <=, >, >= Relational q > 55
==, != Equality and inequality value == 1
&& Logical AND value == 15 && test > 0
|| Logical OR value == 10 || debug != 0
= Assignment result = 15 * (35 + a)

 

Statements

for / endfor

Implements a loop.

for <variable> <first>:<last>[:<increment>]

variable The counter variable for the loop
first The value for the first iteration of the loop
last The value of the last iteration of the loop
increment The increment of the counter variable each iteration. Will be 1 if it is omitted.

The for loop will execute, starting with the first value and terminating when the value exceeds the last value. The increment is 1 if not specified.

Example:

 for channel 32:1:-1
      Di(1,channel,{red, green, blue})
      D(10,channel,{0, 0, 0})
      A(3)
endfor

while / dowhile

Implements a while loop

while <condition>

condition The condition to evaluate. Zero (0) is false, any non-zero value is true.

The while loop will execute as long as the condition is true.

if / elseif / else / endif

if <condition>

condition The condition to evaluate. Zero (0) is false, any non-zero value is true.

 Implements a condition statement.

Example:

if x == 1
     Pl("one")
elseif x== 2
     Pl("two")
else
     Pl("other")
endif

 

Assignment

Assignment is technically an operator, but is listed here for completeness.

<variable or array reference> = <value>

Examples:

x = y * y

g[x] = 33

break

Breaks out of a for loop and continues execution in the next statement after the endfor

return

Returns a value from a function.

Example:

return result

Functions

Functions may be defined and called:

Function Definition (func/endfunc)

func <name>(<parameterList>)

name The name of the function
parameterList A list of zero or more parameters

Declares a function.

Example:

func GetColor(colorNumber)

    if (colorNumber == 0)
        return {1, 0, 0}
    elseif (colorNumber == 1)
        return {1, 1, 0}
    elseif (colorNumber == 2)
        return {0, 1, 0}
    endif

endfunc

Function Invocation

Call a function.

Example:

color = GetColor(x)

Built In Functions

A

Perform the animation for a given number of cycles.

A(<cycleCount>)

int cycleCount The number of cycles to animate

The A() function drives the led hardware to perform all currently defined animations for the specified number of cycles.

Once a fade is completed, that led channel will remain at the final brightness value until a new fade for that channel is defined and executed. If there are no defined animations, calling the A() function merely delay by the specified cycle count.

 

ConfigButton

ConfigButton defines a button that can be used to control program flow.

ConfigButton (<buttonNumber>, <buttonType>, <buttonPin>, <param 1>, <param 2>, <param 3> , <param 4>)

int buttonNumber The number of this button, from 0 to 9
string buttonType The physical hardware type of the button.
int buttonPin The physical pin to use for the button.
int param A parameter specific to the button type

The following table defines the supported button types:

"TOUCH" A touch button implemented using the ESP32's built-in touch support. The param parameter defines the touch threshold used to determine whether the contact is touched or not
"ACTIVELOW" A electrical button that will be true when the specified button pin is low.

See ReadButton() to read button values. For touch buttons, see Debug("DebugButtonNumber") to determine an appropriate threshold value.

The ESP-32 supports touch buttons on pins 0, 2, 4, 12, 13, 14, 15, 27, 32, 33

Examples:

ConfigButton (0, "TOUCH", 15, 20)

Defines a touch button connected to pin 15 of the ESP32 and use 20 as the touch threshold value.

 

ConfigLed

ConfigLed defines one or more LEDs that the system can animate.

ConfigLed (<ledStringNumber>, <ledStringType>, <ledCount>, <param 1>, ... , <param n>)

int ledStringNumber The number of this string. Fade supports up to 16 led strings. They must be defined sequentially, starting with string number zero.
string ledStringType The physical hardware type of the string.
int ledCount The number of leds in the string
int param Parameters specific to the physical hardware type of the string

The following table defines the supported string types:

"WS2812" or "RGB" A string of WS2812-compatible (aka "neopixel") addressable leds. The <ledCount> parameter defines the number of leds on the string, and <param 1> defines the physical pin the strip is connected to.
"APA102" A string of <ledCount> APA102 addressable leds.

The ESP supports two different sets of SPI hardware, known as VSPI and HSPI.

param 1: Choose VSPI (0) or HSPI (1).

There are 4 pins that are used by default for each set of hardware:

VSPI:
SCLK = 18
MISO = 19
MOSI = 23
SS = 5

HSPI:
SCLK = 14
MISO = 12
MOSI = 13
SS = 15

The 4 pins can be defined directly:

param 2: SCLK
param 3: MISO
param 4: MOSI
param 5: SS

SCLK is connected to the clock input on the LED strip, and MOSI is connected to the data input. MISO and SS are not connected.
"PWM" A non-addressable LED controlled through PWM. This feature uses the ESP-32's built in LED control hardware. 1-4 leds can be defined in a single statement, and the physical pins are defined using parameters 1-4.
"Servo" A servo motor controller with 1-2 mS pulses. This feature uses the ESP32's built-in LED control hardware. Specify 1 for the ledCount and the pin the servo is connected to.
"UdpSender" Takes animation data and sends it over the network to a remote ESP. Specify the ledCount as normal.
param 1: The number of values per pixel to send
param 2: The universe number. This must match with the number of the receiver
param 3: The UDP port to send the data on
"UdpReceiver" Takes animation data from a UdpSender and uses it on this system. ledCount must be set to zero.
param 1: The universe number. Must match the sender
param 2: The UDP port to listen on.
param 3: The starting channel to copy from the UDP data to this system
param 4: The number of channels to copy to this system.

Examples:

ConfigLed (0, "RGB", 8, 27)
ConfigLed (1, "PWM", 3, 17, 16, 4)
ConfigLed (2, "Servo", 1, 31)

Configures a string of 8 WS2812 leds connected to pin 27 as the first string, followed by 3 individually controlled PWM leds on pins 17, 16, and 4, followed by a single servo attached to pin 31

When animating, leds 0-7 will be the WS2812 leds, leds 8-10 will be the PWM ones, and led 11 will be the servo.

Remoting

Remoting provides the ability to define a set of leds/channels that look like they are implemented on the local ESP but are actually sent over the local network to remote ESP(s).

On the local ESP - the one that is running the animation - the UdpSender LED type is configured just like the other types. The UDP port is specified and a universe number is also specified so that multiple remoted scenarios could be run on the same network and port.

ConfigLed(1, "UdpSender", 16, 155, 4021)

This defines LED group 1 as 16 pixels/channels, transmitting on port 4021 and using universe 155

The UdpReceiver led type is used to pull the Udp data off the network and put it into the local system. The port and universe are specified and must match the UdpSender values. The receiver should be defined as the first group, and the led count must be zero.

 ConfigLed(0, "UdpReceiver", 0, 15, 4211, 8, 8)
ConfigLed(1, "Servo", 4, 4, 5, 6 ,7)
ConfigLed(2, "Servo", 4, 8, 9, 10, 11)

A(100000)

The receiver is listening on port 4211 and universe 15. The first 8 specifies that the first 8 channels in the data should be skipped and after that the next 8 should be copied into the system.

The Servo configs after that specify two blocks of 4 servos, each connected to a different pin.

 

D and Di

D and Di define a fade for the animation system to perform.

D(<cycleCount>, <ledIndex>, <targetBrightness>)
Di(<cycleCount>, <ledIndex>, <targetBrightness>)

int cycleCount The number of animation cycles over which to perform the fade
int ledIndex The index of the led to animate. Led indexes run from zero to n-1, where n is the number of LEDs defined across all led groups.
brightness targetBrightness The target brightness for the led

The cycleCount parameter is used to control how fast the fade occurs, expressed in 10 millisecond units.

The targetBrightnessparameter defines the target brightness, and the format depends upon the type of underlying LED hardware. For PWM leds, it is a single floating point value. For addressable LEDs, it is a series of values.

The Di function is used to simplify code when only a single fade operation is required by also performing the animation; it is equivalent to:

D(<cycleCount>, <ledIndex>, <targetBrightness>)
A(<cycleCount>)

Examples:

D(100, 3, 1.0)

Define a fade led #3 to full brightness over the next 100 cycles (1 second)

D(30, 5, {1.0, 0.0, 0.0})
D(30, 6, {0.0, 0.5, 0.0})

Define two fades that will occur over the next 30 cycles; led #5 will fade to red and led #6 will fade to 50% green.

Debug

Debug sets a debugging flag.

Debug (<debugFlag>, <value>)

string debugFlag The debug flag to set
int value The value to set for the flag

The Fade animation system provides debug flags that can make understanding system behavior easier. The following debug flags are defined

"LogStatements" Every statement that is executed will be logged to the Serial console.
"LogHeapFreeOnAllocation"  The amount of free heap memory is logged when allocations are performed.
"DebugTouchButtonValues" Logs the current button touch value whenever the button value is read. Used to determine an appropriate threshold number
"DebugPrintOverUdp" Sends all print output over the network using UDP broadcast messages. Useful for remote debugging. WinFade can read and display these messages, or you could use a utility like wireshark

HsvToRgb

Converts a Hue-Saturation-Value color to an RGB Color

HsvToRgb (<hue>, <saturation>, <value>)

float hue The hue value from 0-359
float saturation The saturation from 0-1
float value The intensity value from 0-1

 

Min
Max

Min and Max return the minimum or maximum of all the values passed in. 

Min(<value>,...)
Max(<value>,...)

value A numeric value

 

P
Pl

Prints one or more values to the serial subsystem 

P(<value>,...)
Pl(<value>,...)

value A string, integer, or brightness value

Pl performs the print operation followed by a new line.

Rand

Rand generates a pseudo-random number between the minimum and maximum value, inclusive.

Rand(<minimumValue>, <maximumValue>)

int minimumValue The smallest number to generate
int maximumValue The largest number to generate

ReadButton

ReadButton reads the current value of a button to determine if it is pressed.

int ReadButton (<buttonNumber>)

int buttonNumber The number of this button, from 0 to 9

This function returns 1 if the button is pressed and 0 if the button is not pressed.

Examples:

if ReadButton (0) == 1

endif

S and Si

S and Si define a fade for the animation system to perform for multiple leds.

S(<cycleCount>, <firstLedTargetBrightness>, ..., <lastLedTargetBrightness>)
Si(<cycleCount>, <firstLedTargetBrightness>, ..., <lastLedTargetBrightness>)

int cycleCount The number of animation cycles over which to perform the fade
target brightness list A list of target brightnesses for the leds

The S and Si functions are used to define a fade that is performed on multiple LEDs using the same cycle count.

The cycleCount parameter is used to control how fast the fade occurs, expressed in 10 millisecond units.

The target brightness list defines the target brightness for the leds, starting with led #0 and continuing based on the number of values listed

The Si function is used to simplify code when only a single fade operation is required by also performing the animation. See Di for more information.

Examples:

S(100, 1.0)

Define a fade for led #0 to full brightness over one second.

Si(200, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} )

Define three fades that will occur over the next 200 cycles; led #0 will fade to red, #1 to green, and #2 to blue. This is equivalent to:

D(200, 0, {1.0, 0.0, 0.0})
D(200, 1, {0.0, 1.0, 0.0})
D(200, 2, {0.0, 0.0, 1.0} )
A(200)