Brain Coral Tutorial: Toggle animation sequences

Version 5

    Let’s make our program more interesting by introducing a way to toggle between animations.


    Create a new file named “1-4-idle-warn.js”. You can duplicate the previous file as a starting point. First, we’ll add a placeholder inside the “ready” function that will listen for incoming values from pin ‘A0’ on the Galileo:

     

    board.on('ready', function() {
        leds.rainbow(1, 25);
        this.analogRead('A0', function(data){
              console.log(data);
        });
        process.on('exit', function(){
              leds.off();
        });
    });
    
    
    
    
    
    
    

     

    Write a function that detects if a number is within a given range

    In order to get started, we need to write two functions to help us out. The first function determines if a number is between a specific range. We will use this in our “analogRead” function, which will have fluctuating input value based on the distance it detects on the physical sensor. The base logic for it is as follows:

     

    x >= min && x <= max

     

    In the snippet above, x, min, and max are all variables. If we were to run the condition using real numbers, we would return a true or false value. For example:


    5 >= 0 && 5 <=10; // true

    5 >= 10 && 5 <=20; // false


    We will wrap this logic inside a function so that it can be reusable:


    function between(x, min, max) { 
        return x >= min && x <= max;
    }
    
    
    
    
    
    
    

     

    Now, when we need to determine if a number falls within a specific range, we can call our new function:


    between(5, 0, 10); // true
    between(5, 10, 20): // false
    
    
    
    
    
    
    

     

    We will be calling our between function inside the next function we create.

     

    Use state machine logic to determine which animation is currently active

    While an animation is playing, we would like to know which animation is currently running so we know when to switch it. To do this, we need to write a function that updates the state of the animation that allows us to track it. There are two states that we want to track: an “idle” state, and an “active” state. Let’s start by giving these states a number:


    var STATE_IDLE = 0;
    var STATE_ACTIVE = 1;
    var currentState = STATE_IDLE;
    
    
    
    
    
    

     

    Here, we are also keeping track of the current state (named “stateCurrent”). This is equal to the “stateIdle” value because it will be our first state when our program starts.


    Next, we want to create a function that will constantly get called to check the state of the animation sequences. This function will be called in our “analogRead” function. We have several things we’d like to accomplish:

    • Start the program in the “idle” state and run the “rainbow” sequence
    • When the analog input reaches a certain range, we want to update the currentState and switch to a different animation called “pulseColor”, as defined in the “lpd8806-asyncfx” library
    • When the analog input reaches a different range, we want to do the same as above: stop the current sequence and start another (back to the “idle” sequence)

     

    Our objective is to toggle between two states, so that when the distance sensor is approached, the lights will pulse (fade in and out) the color red. Otherwise, the “rainbow” animation sequence will run.

     

    To do this, let's create a function called “updateState”:

     

    function updateState(val){
        if(currentState != STATE_IDLE && between(val, 0, 249)){
              currentState = STATE_IDLE;
              leds.rainbow(1, 20);
        }
        if(currentState != STATE_ACTIVE && between(val, 250, 500)){
              currentState = STATE_ACTIVE;
              leds.pulseColor(255, 0, 0);
        }
    }
    
    
    
    
    
    

     

    This new function will get called during the “analogRead” function. It takes a single parameter, “val”, that determines the current state (stateCurrent) of our animation. The value will be the analog input of our distance sensor.

     

    The following demonstrates how this would be called in our final code inside the "ready" event:

     

    this.analogRead('A0', function(data){
        data = parseInt(data, 10);
        updateState(data);
    });
    
    
    
    
    
    

     

    The value for “data” is of type “string”. In order to be able to run math functions on this value, we convert it to an integer using the “parseInt” JavaScript function. This way, we will pass an integer to the updateState function for proper processing.

     

    The completed program is shown here:

     

    var leds = require('lpd8806-asyncfx')(10);
    var Galileo = require('galileo-io');
    var board = new Galileo();
    
    board.on('ready', function() {
        leds.rainbow(1, 25);
        this.analogRead('A0', function(data){
              data = parseInt(data, 10);
              updateState(data);
        });
        process.on('exit', function(){
              leds.off();
        });
    });
    
    var STATE_IDLE = 0;
    var STATE_ACTIVE = 1;
    var currentState = STATE_IDLE;
    // Determines which state the animation is in based off the incoming value
    function updateState(val){
        if(currentState != STATE_IDLE && between(val, 0, 249)){
              currentState = STATE_IDLE;
              leds.rainbow(1, 20);
        }
        if(currentState != STATE_ACTIVE && between(val, 250, 500)){
              currentState = STATE_ACTIVE;
              leds.pulseColor(255, 0, 0);
        }
    }
    // Returns a boolean value determined by the returned condition
    function between(x, min, max) {
        return x >= min && x <= max;
    }
    
    process.on('SIGINT', function() {
        process.exit(0);
    });
    
    
    
    
    
    

     

    Run the program by executing node 1-4-idle-warn

     

    The pulseColor function takes 4 parameters. The first three are RGB value, with the remaining parameter equal to the brightness level. If no value is passed for the brightness, it will default to 1.0 (the brightest level).


    You can find all of the code used in this tutorial on this project's GitHub page: Inside the Blue: Brain Coral

    .
    < Using animation sequences on the LPD8806 pixel strip with lpd8806-asyncfx3d printing your coral >