Scheduler Code

Class Scheduler Logic

The sketch that runs on the Circuit Playground Class Scheduler is fairly simple. It really only can do four things:

  • Beep and blink a red LED when it's turned on
  • Change the day of the week indicator NeoPixels when the right button is pressed
  • Change the class period indicator NeoPixels when the left button is pressed
  • Show or hide the display/lock the buttons when the toggle switch is flipped (this way you don't have to turn it off and reset everything, but can still save power or avoid annoying people with the bright lights)

Pseudo-code

Before you look at the code below, here's a pseudo-code version of it. "Pseudo-code" is a way of thinking about the logic of your code before diving into the details of proper syntax. Here are the steps the software will go through when it runs:

  1. Beep and blink when turned on or reset
  2. Check the slide switch to see if it is "on" or "off"
  3. If the slide switch is "off", do nothing other than continue checking the slide switch
  4. Otherwise, if the slide switch is "on", light up the Monday NeoPixel to white, and first period NeoPixel to the proper class subject color according to the schedule
  5. Check the right button. If it's pressed, advance to the next day, adjust the day NeoPixel to the proper day, and adjust the current period NeoPixel to the proper subject color according to the schedule
  6. Check the left button. If it's pressed, advance to the next period, adjust the NeoPixel to the proper period and color according to the schedule
  7. Repeat

Variables

Variables are a bit like names we can use to refer to values that may change depending on what's going on. For example, we can tell the software to turn on the day NeoPixel, where day is a variable that stands for then number of the day we've currently selected by pushing the button.

When you think about implementing the above logic as actual code in Arduino, there are a few things that stand out is needing to be expressed as variables:

  • Day of the week
  • Class period
  • Class subject
  • Schedule of class subjects per period per day
  • Colors correlated to each subject

 You can see examples of these variables in the code snippet below. The schedule and classColor variables are both a special type called a 2D matrix, which just means they have rows and columns like a spreadsheet. This makes it efficient later in the code for a function to ask for, say, the green value of the english class by querying classColor[4][1]

The positions of the values in the row and column arrays are indexed to begin at 0, so index 4 is actually the fifth row and so on.
Download: file
      // NUM_CLASSES is the number of class periods in a day
// You could adjust this -- may be fewer than 5 but not greater
// without running into the day-of-the-week pixels -- and you'd also
// need to adjust the "schedule" and "classColor" matrices below

const int NUM_CLASSES = 5;

//*******************************************************
// Adjust this "classColor" matrix to pick your own colors expressed
// as RGB value triplets from 0-255 per class subject
//*******************************************************

int classColor[NUM_CLASSES][3] = {
    {255,  0,  0}, // chorus    is red
    {  0,255,  0}, // science is green
    {  255,0,255}, // history is purple
    {  0,  0,255}, // math  is blue
    {255,255,  0}  // english is yellow
};

//*******************************************************
//Adjust this "schedule" matrix to reflect your own class schedule
//*******************************************************

const int NUM_DAYS = 5;
int schedule[NUM_DAYS][NUM_CLASSES] = {
    {0,1,2,3,4}, // Monday    = chorus, science, history, math, english
    {0,4,1,2,3}, // Tuesday   = chorus, english, science, history, math
    {0,3,4,1,2}, // Wednesday = chorus, math, english, science, history
    {0,2,3,4,1}, // Thursday  = chorus, history, math, english, science
    {0,1,2,3,4}  // Friday    = chorus, science, history, math, english
};

// Global variables that track the current day and current period.

int period = 0;
int day = 0;
    
Anything that follows two slashes // is considered a comment for human use only and won't be read by the Arduino software!

Additionally, there are variables we'll use to store the current state and previous state of the buttons. Each of these variables can be set to a value of "pressed" or "not pressed". By comparing the current and previous state of a these variables, the program knows when a button has been pressed and can then run a particular piece of code.

Download: file
bool leftFirst = CircuitPlayground.leftButton();
  bool rightFirst = CircuitPlayground.rightButton();
  delay(20);
  bool leftSecond = CircuitPlayground.leftButton();
  bool rightSecond = CircuitPlayground.rightButton();

Functions

You'll use a number of functions that are built into the Circuit Playground library. Functions are essentially little (or not so little!) pre-built routines that you can use to take care of a whole bunch of steps of processing for you. A good example is the CircuitPlayground.clearPixels() function. When you call this function a whole bunch of steps are run that go through and turn off each NeoPixel one by one, so you can imagine your sketch would be much longer and more complicated if you needed to do that step by step.

Here are some of the other key functions you'll use:

  • CircuitPlayground.begin() initializes the board
  • CircuitPlayground.playTone() makes sound
  • CircuitPlayground.redLED() turns the red LED on and off
  • CircuitPlayground.slideSwitch() checks the slide switch for input
  • CircuitPlayground.leftButton() checks the left button for input
  • CircuitPlayground.rightButton()checks the right button for input
  • CircuitPlayground.setPixelColor() lights up a particular NeoPixel to a specified color value

 

Arguments

Some functions require additional input when they are called. These clarifications are sometimes called arguments. For example, CircuitPlayground.redLED(true) will turn the red LED on, and CircuitPlayground.redLED(false) will turn it off. 

There are also functions that require multiple arguments, such as turning on a NeoPixel, where you must specify which one to address, and the individual red, green, and blue values. Here's an example of turning NeoPixel #0 red:

CircuitPlayground.setPixelColor(0, 255, 0, 0) 

While this set of arguements to the function will turn NeoPixel #9 purple:

CircuitPlayground.setPixelColor(9, 255, 0, 255) 

The Code

The code below is the full script.

Download: file
// ---------------------------------------------------------------------------
//Circuit Playground Class Scheduler
// John Park
// for Adafruit Industries
//
//
//Uses NeoPixels 0-4 to indicate class schedule by
//period (position) and subject (color),
//for a give day of the week indicated by NeoPixels 5-9.
//
// For use with the Adafruit Circuit Playground.
//
// MIT license, check LICENSE for more information
//
// ---------------------------------------------------------------------------
//Setup
//Set schedule (subject per period per day of the week)
//variables at top of sketch in the schedule matrix.
//Upload the sketch to Circuit Playground.
//
//Usage
//Flip the toggle switch to the right to show display, left to hide it
//Press right momentary button to change day of the week
//Press left momentary button to change class period
// ----------------------------------------------------------------------------

#include <Adafruit_CircuitPlayground.h>
#include <Wire.h>
#include <SPI.h>

// NUM_CLASSES is the number of class periods in a day
// You could adjust this -- may be fewer than 5 but not greater
// without running into the day-of-the-week pixels -- and you'd also
// need to adjust the "schedule" and "classColor" matrices below

const int NUM_CLASSES = 5;

//*******************************************************
// Adjust this "classColor" matrix to pick your own colors expressed
// as RGB value triplets from 0-255 per class subject
//*******************************************************

int classColor[NUM_CLASSES][3] = {
    {255,  0,  0}, // chorus    is red
    {  0,255,  0}, // science is green
    {  255,0,255}, // history is purple
    {  0,  0,255}, // math  is blue
    {255,255,  0}  // english is yellow
};

//*******************************************************
//Adjust this "schedule" matrix to reflect your own class schedule
//*******************************************************

const int NUM_DAYS = 5;
int schedule[NUM_DAYS][NUM_CLASSES] = {
    {0,1,2,3,4}, // Monday    = chorus, science, history, math, english
    {0,4,1,2,3}, // Tuesday   = chorus, english, science, history, math
    {0,3,4,1,2}, // Wednesday = chorus, math, english, science, history
    {0,2,3,4,1}, // Thursday  = chorus, history, math, english, science
    {0,1,2,3,4}  // Friday    = chorus, science, history, math, english
};

// Global variables that track the current day and current period.

int period = 0;
int day = 0;



void setup() {
    CircuitPlayground.begin(); //initialize the board
    CircuitPlayground.playTone(932,200); //startup beep frequency and duration
    //pulse the red LED twice
    int i=0;
    for(i=0;i<2;i++){
        CircuitPlayground.redLED(true);
        delay(200);
        CircuitPlayground.redLED(false);
        delay(200);
    }
    //fairly dim NeoPixel brightness setting -- goes up to a blinding 255!
    CircuitPlayground.setBrightness(15);
    CircuitPlayground.clearPixels(); //turns off all NeoPixels
}


void loop() {

    //check the slide switch, "off" to the right means the buttons
    //won't respond, acting like they are locked, and turning off the
    //NeoPixels to save power/avoid annoying people, "on" to the left

    if (!CircuitPlayground.slideSwitch()) {
        CircuitPlayground.clearPixels();
        return;
    }

    // ------------------------------------------------------------------------
    // Detect if the left or right button is released by taking two
    // readings with a small delay in between.  If the button changes
    // state from pressed -> released then we can update indicators.

    bool leftFirst = CircuitPlayground.leftButton();
    bool rightFirst = CircuitPlayground.rightButton();
    delay(10);
    bool leftSecond = CircuitPlayground.leftButton();
    bool rightSecond = CircuitPlayground.rightButton();

    // Read the day of the week (right) button, if pressed, increment
    // the "day" variable
    //"day" is an integer to represent the day of week 0-4 / M-F
    //starts on Monday which is index 0

    if (rightFirst && !rightSecond){
        day++;
        //cycles from friday back to monday
        if (day > NUM_DAYS - 1) {
            day=0;
        }
    }

    // Read the class period (left) button, if pressed, increment the
    // "period" variable

    // "period" is the class period counter to indicate current period
    // starts on 1st period, which is index 0

    if (leftFirst && !leftSecond){
        period++;
        //cycles from first to fifth period
        if (period > NUM_CLASSES -1) {
            period=0;
        }
    }

    // ------------------------------------------------------------------------
    // Now we're ready to update display with day/period.

    // Start by turning everything off

    CircuitPlayground.clearPixels();

    // Light up the day of the week pixel

    CircuitPlayground.setPixelColor((9-day), 255, 255, 255);

    // Light up the proper color for the class subject

    CircuitPlayground.setPixelColor(period,
                                    (classColor[(schedule[day][period])][0]),
                                    (classColor[(schedule[day][period])][1]) ,
                                    (classColor[(schedule[day][period])][2])) ;
}

Download the Code

You can press the button below to download the code. Unzip and move the directory CircuitPlaygroundClassScheduler to your Arduino sketch directory. 

Edit the Code

Open the ClassScheduler.ino file in the Arduino IDE. You can customize the schedule[][] and classColor[][] matrices to match your own class schedule.

For example, if your schedule is:

  • Monday - English, Cooking, Math, Italian, Science
  • Tuesday - English, Cooking, Math, Italian, Science
  • Tuesday - English, Cooking, Math, Italian, Science
  • Tuesday - Science, Cooking, Math, English, Italian
  • Tuesday - Science, Cooking, Math, English, Italian

The matrix would look like this:

Download: file
int schedule[NUM_DAYS][NUM_CLASSES] = {
  {0,1,2,3,4}, // Monday    =  English, Cooking, Math, Italian, Science
  {0,1,2,3,4}, // Tuesday   =  English, Cooking, Math, Italian, Science
  {0,1,2,3,4}, // Wednesday =  English, Cooking, Math, Italian, Science
  {4,1,2,0,3}, // Thursday  = Science, Cooking, Math, English, Italian
  {4,1,2,0,3}  // Friday    = Science, Cooking, Math, English, Italian
};

You can do the same type of editing if you'd like to chose different colors to correspond to your class subjects. For example:

  • English is green
  • Cooking is red
  • Math is white
  • Italian is blue
  • Science is purple

Would look like this:

Download: file
int classColor[NUM_DAYS][NUM_CLASSES] = {
  {0, 255, 0}, 
  {255, 0, 0},
  {255, 255, 255},
  {0, 0, 255},
  {255, 0, 255}
};

Save It

Once you've edited the code, save it. In the next section we'll upload it to the board.

Here's a great suggestion from John K Shaffstall aka NorthernPike: "Great idea for using a Playground. And the panel is a perfect way to define its use. I have a suggestion about the code. It has to do with the "day" and "period" variables. I find that variables used as what I call "cyclers" that wrap around are good candidates for the conditional operator. As in... if (rightFirst && !rightSecond){ day = day > (NUM_DAYS - 1) ? 0 : day + 1; //cycles from friday back to monday } Instead of a nested if as in... if (rightFirst && !rightSecond){ day++; //cycles from friday back to monday if (day > NUM_DAYS - 1) { day=0; } } Just a thought... The "Conditional" operator is too overlooked and under utilized in my opinion. MAKE a nice day..."
This guide was first published on Aug 24, 2016. It was last updated on Aug 24, 2016.
This page (Scheduler Code) was last updated on Jun 25, 2020.