Cubelets API Documentation 2.0
C API
Loading...
Searching...
No Matches
moodring_pachinko.c File Reference

Creates a symmetrical LED pattern with blinking effects as seen in the Mood Ring Pachinko personality. More...

Functions

void setup ()
 Initialization function called once at the start. The setup() Function runs once when the program starts. Here, it’s empty because we don't have any initialization.
 
void loop ()
 Main loop function that runs repeatedly. The loop() Function runs repeatedly. It calls two functions:
 
void think ()
 Computes the block_value if there is no manual override.
 
void act ()
 Lights up the LED ring with a symmetrical pattern and blinking effects.
 

Detailed Description

The Goal

We want to create a symmetrical LED pattern where:

  • LEDs light up with colors that gradually shift (based on a hue value), in a symmetrical pattern.
  • Brightness increases with a value called block_value.
  • One LED blinks brighter than the others at random.

Workflow

  1. The setup() function initializes the system (empty in this case).
  2. The loop() function continuously calls think() and act().
  3. The think() function computes the block_value based on sensor input.
  4. The act() function lights up LEDs symmetrically and introduces dynamic effects.

Challenges

  • Modify the blinking LED to change its color randomly.
  • Experiment with other symmetrical patterns, such as sequential lighting.

Step-by-Step Explanations

Function Documentation

◆ setup()

void setup ( )

Function ran just a single time. Used for setting up variables or timers.

void setup()
{
}
void setup()
Function ran just a single time. Used for setting up variables or timers.
Definition bargraph.c:3

◆ loop()

void loop ( )

The loop() function gets called repeatedly while a Cubelet is powered on.

  • think(): Determines the block_value.
  • act(): Lights up the LEDs based on the block_value.
void loop()
{
think();
act();
}
void act()
Using to perform an action based on a previously calculated block value.
Definition bargraph.c:19
void think()
Used in Action and Think Cubelets to calculate their block value.
Definition bargraph.c:14
void loop()
The loop() function gets called repeatedly while a Cubelet is powered on.
Definition bargraph.c:8

◆ think()

void think ( )

Used in Action and Think Cubelets to calculate their block value.

The think() function calculates block_value, a number that determines:

  • How bright the LEDs are.
  • How quickly they blink.

The weighted_average() function calculates this based on sensor inputs (not shown in the code). If there’s no manual override (block_value_override), it updates block_value.

void think()
{
if (!block_value_override)
{
block_value = weighted_average();
}
}
uint8_t weighted_average(void)
Calculates a block value based on the on the weighted average of neighbors block values.

◆ act()

void act ( )

Using to perform an action based on a previously calculated block value.

This is where the magic happens! Let’s break it into smaller sections.

  1. Symmetry in LED Colors

    The 8 LEDs are arranged in pairs: LED 0 pairs with LED 7. LED 1 pairs with LED 6, and so on.

    The following loop runs for half the LEDs, setting their colors and mirroring them for the other half.

    for (uint8_t i = 0; i < 4; i++)
    {
    // snip code for now
    // Set LEDs in mirrored pairs
    LedSet(i, r, g, b); // LED i
    LedSet(7 - i, r, g, b); // Symmetrical LED (7 - i)
    }
  2. Color Calculation

    The hueToRGB() function converts a hue (a number between 0 and 255) into red (r), green (g), and blue (b) values.

    The hue shifts slightly for each pair:

    The % 255 ensures the hue wraps around within the valid range.

    hueToRGB((hue + i * 64) % 255, 10, &r, &g, &b);
  3. Brightness Adjustment

    a. Brightness depends on block_value and a random factor.This ensures that brightness increases with block_value but also has some variation for a cool effect.

    brightness = (uint8_t)((block_value / 2) + (rand() % (block_value / 2 + 1)));

    b. The RGB values are scaled by brightness

    r = (r * brightness) / 255;
    g = (g * brightness) / 255;
    b = (b * brightness) / 255;
  4. Setting the LEDs

    The LedSet() function lights up a specific LED with the calculated color. This creates a symmetrical pattern.

    LedSet(i, r, g, b); // LED i
    LedSet(7 - i, r, g, b); // Symmetrical LED (7 - i)
  5. Blinking Effect

    One random LED blinks brightly. The chance of blinking increases with block_value. Note: rand() % 8 selects a random LED to blink.

    if (rand() % (256 - block_value) < 5)
    {
    blink_led = rand() % 8;
    LedSetHue(blink_led, last_hue, 255);
    }
  6. Dynamic Hue and Speed

    The hue shifts slightly each loop.

    last_hue = (last_hue + 1) % 255;

    The update speed also changes with block_value:

    wait(150 - (block_value / 2));
    void wait(uint16_t delay)
    Function to delay execution for a specified amount of time.
  7. Turn the LEDs on

    The last line of code is when we tell the Cubelet to turn the LEDs on to their newest colors. Without this call, the LEDs will never update.

    LedRingUpdate();

And now, for the full code:

void act()
{
uint8_t r, g, b, brightness;
static uint8_t last_hue = 0;
static uint8_t blink_led = 0;
uint8_t hue = (uint8_t)(block_value * 2);
// Iterate through LEDs in mirrored pairs
for (uint8_t i = 0; i < 4; i++)
{
hueToRGB((hue + i * 64) % 255, 10, &r, &g, &b); // Generate RGB based on hue
brightness = (uint8_t)((block_value / 2) + (rand() % (block_value / 2 + 1))); // Randomized brightness
// Scale RGB by brightness
r = (r * brightness) / 255;
g = (g * brightness) / 255;
b = (b * brightness) / 255;
// Set LEDs in mirrored pairs
LedSet(i, r, g, b); // LED i
LedSet(7 - i, r, g, b); // Symmetrical LED (7 - i)
}
// Blinking effect for a random LED
if (rand() % (256 - block_value) < 5)
{
blink_led = rand() % 8;
LedSetHue(blink_led, last_hue, 255); // Set random LED to bright hue
}
last_hue = (last_hue + 1) % 255; // Increment hue for smooth transitions
wait(150 - (block_value / 2)); // Adjust speed based on block_value
LedRingUpdate();
}