How to Code a Song

30m

Introduction

Songs in the Little Robot Friend library are very similar to the expression type we explored in this previous guide.

One major difference is that songs can contain many more musical notes when compared to expressions which can only contain four notes. The setup process is similar to expressions as it requires two steps.

Declaring a Song

Just like expressions, we need to declare our song data. Each song is made up of four parts:

  • length
  • octaveShift
  • pattern
  • sounds

DECLARE SONGS AT THE TOP

Songs should be declared at the top of your Arduino sketch!

Let’s check out a basic example of what a song should look like:

LRFSong mySong = {
    .length = 25,
    .octaveShift = 1,
    .pattern = myPattern, // declared above
    .sounds = {
        { LRFNote_A, LRFOctave_Mid, ...
        { LRFNote_A, LRFOctave_Mid, ...
        ...
    }
};

Let’s check out each property of our song in more detail to find out exactly what it does!

Properties of a LRFSong

Name

When declaring a song, you need to give that song a name! If you have multiple songs, each will require a unique name. Naming the song is done simply by typing the name following “LRFSong”.

LRFSong mySong = {

Length

The length property refers to the number of musical notes in the song you are writing. It’s important that the number of notes listed in the sounds property (discussed below) matches the number set for the length property. A common mistake is to forget to update the length property when adding notes, failing to do this will result in the robot playing up to the set length and no further.

  .length = 9,

Octave Shift

Similarly to a piano or other musical instruments, Little Robot Friends musical notes fall into octaves which determine the pitch of a sound. Each note can be defined with its own octave within the sounds property, however if you want to adjust the octave of every note in the song, the octaveshift property can be used. You can use values from -2 to +2 to offset the octave value.

.octaveShift = 0,

Pattern

The pattern property refers to the eye color pattern or animation. You can set two colors and the transformation between them. Each of these components are separated by a comma and they are grouped by curly brackets.

 .pattern = { LRFColor_Green, LRFColor_Purple, LRFTransform_Boomerang },

Sounds

The sound property is usually the largest property as it contains all the musical notes that make up the song. These take the same form as within expressions, they are comprised of notes, octaves, intonations and durations - both for the actual note and the pause that comes after it.

.sounds = {
    {
      LRFNote_E,
      LRFOctave_3,
      LRFIntonation_Flat,
      LRFDuration_Medium,
      LRFDuration_DoubleShort
    },
    {
      LRFNote_A,
      LRFOctave_3,
      LRFIntonation_Flat,
      LRFDuration_Long,
      LRFDuration_DoubleShort
    }

Refer to link of how sounds work and their components or elaborate here.

Playing a Song

To play, or rather “sing” a song, there is the “lrf.sing()” function that will cause the robot to play the song that you declared above. It only requires the name of the song that you previously declared.

Putting it all together

#include <LittleRobotFriends.h>
LRFSong mySong = {
  .length = 9,
  .octaveShift = 0,
  .pattern = { LRFColor_Green, LRFColor_Purple, LRFTransform_Boomerang },
  .sounds = {
    { LRFNote_E,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_DS, LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_E,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_DS, LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_E,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_B,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_D,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_C,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Medium, LRFDuration_DoubleShort},
    { LRFNote_A,  LRFOctave_3,  LRFIntonation_Flat,   LRFDuration_Long,   LRFDuration_DoubleShort}
  }
};

void setup()
{
  lrf.setup();
}

void loop()
{
  lrf.loop();
  lrf.sing(&mySong);
  delay(5000);
}