Little Robot Friends
Arduino Library Reference  version 1.1
Firmware Basics

If you’re brand new to programming, we highly recommend taking a look at Arduino’s reference pages. There they explain syntax, structure, operators and variables - things that are outside the scope of this document. Once you’ve reviewed those pages you’ll be able to better understand what is happening in our code.

How a Little Robot Friend ‘Thinks’

Before we get too deep into the code, it’s important to understand what is happening when a Little Robot Friend is powered on and sitting idle.

On power-up, the LRF begins by setting up its hardware - making sure sensors are being read as inputs and outputs are being controlled as outputs. After that, it checks its long term memories (EEPROM) to remember its personality and recent history. It copies these memories to variables that make them easy to access. Once its done these simple tasks it logs it first ‘event’ of the day, to say that it has finished powering up. More about events in a little bit.

Setup Task Description
Hardware Setup Make sure inputs, outputs, timers, are configured
Power Setup Setup analog comparator for reading battery state
Personality Setup Read personality from memory
Expressions Setup Initialize expressions library variables
Memory Load Load additional memory variables from EEPROM
Sensors Setup Initialize sensor library variables
Events Setup Initialize event library variables
IrDA Setup Initialize infrared library
Enable interrupts Turn on global interrupts
'PowerUp' Event Post the 'PowerUp' event

After your LRF has completed its ‘setup’ code, it then goes into a ‘loop’ of tasks (or processes) that it performs until its powered down. This loop is comprised of the following tasks (in order): read the sensors, check for new events, express (light and sound), communicate with other robots (infrared), and finally check our power status. Sometimes it will ignore one of these tasks during the loop based on time, or if it will interfere with one of the other tasks, for example if the robot is expressing then it wont read its sensors (since they could give faulty results due to light or noise). Check out this list of loop tasks and when they are ignored.

Loop Task Description
Sensor Process Read sensors (disabled when expressing)
Events Process Handle logged events (disabled when expressing)
Expressions Process Blink and speak (only runs when required)
IrDA Process Interpret incoming messages, send queued messages
Power Process Check power-levels (only runs every 20-30 seconds)

Above I mention events a couple times. What do I mean by an ‘event’? The Little Robot Friends use what is called an event system. Every time something significant happens while your LRF is running, it logs it as an event. These events are split into system events and interaction events. System events are things like: “i’ve just powered up!”, “i’m running out of batteries”, or “i’m going to sleep”. Interaction events are things like: “i’ve been hugged”, or “the lights just turned off!”. It’s important to understand the different events if you want to eventually control how your LRF responds.

Event Name Event Type Event Description
LRFEvent_Tap InteractionSingle touch
LRFEvent_Tickle InteractionMultiple touch
LRFEvent_Hug InteractionLong touch (2-3 seconds)
LRFEvent_LightsOff InteractionAny light level to darkness
LRFEvent_LightsOn InteractionDarkness to any light level
LRFEvent_LightsBright InteractionAny light level to brightness
LRFEvent_LightsLongDark InteractionProlonged darkness (7-10 seconds)
LRFEvent_HeardLoudNoise InteractionMicrophone was triggered (must be close and loud)
LRFEvent_MessageReceived InteractionIrDA received a valid message
LRFEvent_MessageFailed InteractionIrDA recieved a garbled message (currently not handled)
LRFEvent_IsHungry System Battery is getting low
LRFEvent_IsBored System No interaction in a little while
LRFEvent_Sleep System Is about to go to sleep
LRFEvent_Wake System Just woke up
LRFEvent_PowerUp System Just powered on

Once an event is logged, its not ‘handled’ until we reach the event-handling process in its loop, at which point a special function called an ‘event handler’ is performed. This event handler function contains the code that defines how a robot should respond to a particular event. Each event listed above has its own event handler. To customize how your robot responds you can create custom event handlers that override the LRFs default behaviour.

After a little while your robot is going to get bored, say if you haven’t interacted with it for 30s or more, at which point it lets out a ‘yawn’ and/or says ‘boooring’. It’s trying to get you to keep playing with it. After its been bored for a little while (yawned 2 or 3 times) it will then go to sleep so it can save power (you’ll hear the snoring). When sleeping, the robot is easy to wake up again by giving it a hug until it makes a wake up sound. As you see above, sleep and wake up are both system events that you can override to make your robot do fun things.

Where does personality come in to play? The answer is ‘all over the place’. We’ve sprinkled personality code in a lot of places - how the robots read their sensors, make sounds, respond to events and even how they get bored. If you choose one of our template personalities (using the personality chooser - check out this video) you’ll also get a signature sound, which is your robots little calling card. With the API you’re going to have unlimited control over tweaking your personality variables and even how personality is used for your robot. More info to come.

That’s how your Little Robot Friend thinks. It powers on and sets itself up, then performs a loop of tasks: reading sensors, logging events, responding to events and expressing itself. Let’s learn more about how we can reprogram our robot, and for that we need to learn the API.

The LittleRobotFriend Class API

Over the past year we have written a lot of code (and sometimes rewritten, and rewritten again) to make these robots work. In the end, we’ve got over 30 source files containing instructions for the variety of different features of the LRF hardware. I don’t even want to count how many lines of code that is - but it’s somewhere between a thousand and a million. With all this code in our library, we wanted to create a single structure that would allow you to access all the important parts of the code without having to dig through tons of files. This structure is called a ‘class’ and we’ve named ours LittleRobotFriend. The files that define and implement that class are LRF.h and LRF.cpp.

[PHOTO OF API vs LIBRARY]

When you begin programming your robot the first thing you need to do is include the LRF.h file in your code, as such:

#include <LRF.h>

This does two things - it allows your code to access the entire LRF library, and creates an instance of the LittleRobotFriend class storing it in a variable named ‘lrf’. Most of the things you’re going to see in this reference use this class instance that is magically created simply by importing the LRF library as seen above. The LittleRobotFriend class is designed to make programming an LRF easier, and so it doesn’t have all the features found in the library. We plan to expose more features over time, but if you’re a more advanced programmer or are just a brave tinkerer you can dig down into the library code for greater control. There will be more documentation of the underlying library available in due time, but for now this reference is focused on the API provided through the LittleRobotFriend class.

Setup & Loop

If you’ve reviewed the Arduino documentation, you’ll notice two functions that are the core functions for any sketch - setup() and loop(). Most computer programs - microcontrollers included - follow a similar structure.

setup() - is the main function that gets called when the program starts running. It can be used for setting up variables, loading preferences from persistent memory (EEPROM), setting timings and detecting various states that will control the rest of the programs execution. Its called first and only once. Performs the tasks described above in the setup task table.

loop() - is the main function that gets called repeatedly, for ever and ever. This is where all the good stuff happens. This is where you’ll read an input (like a touch sensor), control an output (like making a LED blink), and know that once thats done it will do it all over again during the next loop. Performs the tasks described above in the loop task table.

The LRF library also has setup() and loop() functions that should be called inside the setup() and loop() functions in your sketch, like so:

#include <LRF.h>
void setup(void)
{
lrf.setup();
}
void loop(void)
{
lrf.loop();
}

The MyLittleRobotFriend example file is exactly this code. You can find it in the ‘file > examples > LittleRobotFriends’ menu item in the Arduino IDE software.

This code is essential for running your robot the way we’ve set out in the library, however if you want to experiment we recommend keeping the setup() function and playing around with your own loop() function.

Patterns, Sounds & Expressions

Now that we’ve got a basic template for programming our robot, let’s have some fun. The first thing that most people want to do with their Little Robot Friend is create their own expressions using light and sound. Let’s begin with lights.

Blinking the LEDs with LRFPattern

To create a unique light pattern you’ll need to get familiar with the LRFPattern object. This object is what is called a ‘structure’ or ‘struct’ in the C programming language. By generalizing what a pattern can do, we can create a series of simple codes that point to larger pieces of data. We do this with sets of enumerated constants (or enum in C) and look-up tables. This allows us to efficiently pack a lot of data into a relative small space (our LRFPattern structure), and lots of patterns into the limited space of our microcontroller.

Each LRFPattern is comprised of two LRFColor codes, a starting color, and a target color, and a LRFPatternMode code that describes the type of animation to use between the two values. Click on the links below to learn more about the LRFPattern and its options, LRFColor and LRFPatternMode, then check out our light pattern example code for more information.

Speaking with LRFSound

Making unique sounds is very similar to making light patterns. Sounds are created using a similar ‘struct’, however this time we’ve got a couple more options that will need to be included. We tried to make Little Robot Friend sounds in a way that mimics how we say words.

Each LRFSound is comprised of a LRFNote and LRFOctave that combine to give us our frequency, which determines if we’re making a high-pitched or low-pitched sound. It also contains an LRFIntonation code that allows us to bend that pitch while it’s speaking, which gives the sound a lot of character. Finally we need to define how long we want that sound to be spoken, and whether or not we want to pause after we’ve spoken this sound, which is determined by two LRFDuration codes (the first one is for duration of the note, the second one is for the pause). Check out the documentation pages for LRFSound and it’s options in the links below, then check out the example code to see how to use them!

Combining Patterns and Sounds to Make Expressions

Now that we have a simple understanding of making patterns and sounds, what we really want to do is combine them to make full-blown robot expressions. There are a couple simple functions for doing this called lrf.blinkAndSay(). Once you’ve defined a pattern and a sound, you can combine them using this function.

Once you’ve been able to get this to work we can experiment with multi-sound expressions that allow us to use an array of sounds to give our robot even more character. Check out the example code below to see how to make expressions!

Events and Event Handlers

Up until now we’ve only been able to create expressions that play when our robot powers up, but what if we want our robot to make an expression when he’s ‘tapped’ or ‘tickled’? What about when the lights get dark or bright? For that we need to work with the LRFEvent system (see the ‘How a LRF Thinks’ section).

In order to do that we need to create an LRFEventHandler function, which is just a regular function with no parameters (inputs) or return values (outputs). Inside that code we can put whatever we want - but most ideally that will be a custom expression. Check out the LRFEvent codes and the example code listed below to find out more.

Sensors, Outputs, Infrared Chatting and More

We’re working hard on the documentation and creating tutorials to expand the LittleRobotFriend class and what you can do with it. There are already some undocumented features present in the class header file (LRF.h) for sensors, outputs, infrared and a couple other things. Feel free to play around with them, or wait a week (or so) for us to finish the documentation.

Otherwise, keep checking back for updates (here or our blog), or subscribe to our mailing list, twitter and facebook feeds if you want us to push updates to you. We plan to post regular updates throughout the summer and beyond, so you can continue to have fun and learn with your Little Robot Friend!