Skip to content
Parallax Learn

Parallax Learn

  • Welcome
  • Tutorials
        • Tutorial Series head tag

          Tutorial Series
        • Tutorial Series

          The special, classroom-ready series pages are organized collections of tutorials for our most popular hardware and/or languages. The tutorials for each topic are conveniently accessible from a single page, shown in the order it is recommended that they be completed.
        • Robotics Series Head tag

          Robotics Series
        • Robotics Series

          • Artificial Intelligence
          • Cybersecurity: Radio Data tutorialCybersecurity
          • cyber:bot + Python
          • cyber:bot + MakeCode
          • Boe-Bot Tutorial SeriesBoe-Bot
          • Arduino Shield-Bot
          • ActivityBot with C TutorialsActivityBot + C
          • ActivityBot with BlocklyProp Tutorial SeriesActivityBot + BlocklyProp
          • Scribbler 3 Tutorial SeriesScribbler 3
        • Electronics & Programming Series Head tag

          Electronics & Programming Series
          • BS2 Board of Education Tutorial SeriesBS2 Board of Education
          • Propeller C-Language BasicsPropeller C Basics
          • FLiP Try-It Kit C Tutorial SeriesFLiP Try-It Kit + C
          • FLiP Try-It Kit BlocklyProp TutorialsFLiP Try-It Kit + BlocklyProp
          • Badge WX Tutorial SeriesBadge WX
          • Propeller BlocklyProp Basics and ProjectsPropeller BlocklyProp Basics
          • View All Tutorial Series »
        • Browse Tutorials
        • Browse Tutorials

          Individual tutorials sorted by robot or kit, and language.
        • By Robot or Kit
          • ActivityBot
          • SumoBot WX
          • Boe-Bot
          • Shield-Bot
          • cyber:bot
          • Badge WX
          • ELEV-8
          • ARLO
        • By Language
        • By Language

          • Propeller C
          • Arduino
          • BlocklyProp
          • PBASIC
          • Python
          • MakeCode
          • View All Tutorials »
  • Educators
  • Reference
  • Downloads
  • Home
  • All Courses

Remote Control Rock, Talk, and Roll ActivityBot

Curriculum

  • 1 Section
  • 4 Lessons
  • Lifetime
Expand all sectionsCollapse all sections
  • Remote Control Rock, Talk, and Roll ActivityBot
    4
    • 1.0
      Putting the Pieces Together
    • 1.1
      Taking a Test Drive
    • 1.2
      How Does it All Work Together?
    • 1.3
      Do More With This Project

How Does it All Work Together?

Dig Inside the Code

The AB-IR-Remote-WAV application uses the simpletools and abdrive (or abdrive360) libraries, which may be familiar to you already. It also uses the wavplayer library to play the audio files, and sirc to decode the infrared signals received from the remote controller. 

Comments Count!

A detailed comment block (all the lines between /* and */) helps other people know what is needed to use the application code, and what to expect from it in action. 

/*
  AB-IR-Remote-Wav.c
  10/30/2013 version 0.5
  https://learn.parallax.com/activitybot

  ActivityBot plays WAV files on speaker from SD card
  Sensors: IR receiver on P10, touch whiskers on P7 & P8
  Control with Sony-compatible remote (Parallax #020-00001)
  (Brightstar: hold Setup until lit, then enter 605)
  Drive with 5 buttons: Channel+/-, Vol +/-, and mute
  Number keys select WAV files to play
  If whiskers are pressed, robot backs up & stops, plays WAV
*/

#include "simpletools.h"
#include "wavplayer.h"                  // Needs 0.9 or later              
#include "abdrive.h"                    // Needs 0.5.5 or later
#include "sirc.h"             

 

Setup Tasks Get the Hardware Ready

Inside the main routine, there are a few setup tasks.  First, a freqout call lets you know the program is starting, or re-starting if the batteries run low.  Next, drive_speed(0,0) starts the servo/encoder control core, but does not move the motors yet.  Then, a call to drive_setRampStep determines how quickly the robot will move into and out of maneuvers.

int main()                              // Main - execution begins!
{
  freqout(4, 2000, 2000);               // Start beep - low battery reset alarm
  drive_speed(0,0);                     // Start servos/encoders cog
  drive_setRampStep(10);                // Set ramping at 10 ticks/sec per 20 ms
  sirc_setTimeout(50);                  // Remote timeout = 50 ms

  int DO = 22, CLK = 23, DI = 24, CS = 25;  // Declare SD I/O pins
  sd_mount(DO, CLK, DI, CS);                // Mount SD card
  wav_volume(7);                            // Set vol here, 1 - 10 

 

Nested Control Loops

This program has a loop-within-a-loop structure. The outer loop is a simple while(1) that repeats forever.  The inner while loop is conditional, and only repeats if no whisker is pressed.  It translates to “add the input states of P7 and P8, and as long as the answer is equal to 2, repeat the loop.”  Recall that the whisker touch-sensors are “active-low” circuits that return a 1 if not pressed, and a 0 if pressed. So as long as both whisker circuits are reporting a 1, no object collision has been detected.

while(1)                               // Outer loop
  {
    while((input(7) + input(8)) == 2)    // Inner loop while whiskers not pressed
    {

 

Decoding the Remote

The inner loop’s first line is all that is needed to receive information from the IR Remote.  The sirc library’s sirc_button function decodes infrared patterns detected by the IR receiver, and returns the value corresponding to the remote control button.  That value is assigned to the button variable.  (If you want to use a different Propeller I/O pin with the IR receiver, change it here.)

      int button = sirc_button(10);      // check for remote key press

 

Select a Sound

A series of if(button ==… statements comes next, and the one matching the current value of the button variable gets executed.  For values 0-9, the audio file named in the wav_play function call is accessed from the microSD card and the Propeller chip generates the audio signals that are played on the veho360 speaker.  The wavplayer library launches other Propeller cores to handle those tasks, so the audio files keep playing while the core executing the main function keeps the inner and outer loops looping.  

      // Audio responses - if number key pressed, play named WAV file
      if(button == 1)wav_play("hello.wav");               
      if(button == 2)wav_play("follow.wav");   
      if(button == 3)wav_play("byebye.wav");                
      if(button == 4)wav_play("oops.wav");                
      if(button == 5)wav_play("thankyou.wav");                 
      if(button == 6)wav_play("dontknow.wav");                   
      if(button == 7)wav_play("yes.wav");               
      if(button == 8)wav_play("no.wav");                
      if(button == 9)wav_play("maybe.wav");
      if(button == 0)wav_play("electro.wav");       

 

Select a Motion

If the channel up/down, volume up/down, or mute button is pressed, the corresponding drive_rampStep function call sets the wheel speeds to make the robot move in the direction noted in the comment.  

Since these are calls to drive_rampStep and not to drive_speed, a quick tap on the button will set a slower motion, but holding the button down for a moment longer will set a faster motion. Likewise, a quick tap on the mute button will slow down a motion, but you must hold the button down to stop. 

The drive_rampStep function is part of the abdrive library, which uses a separate core to handle the servo motor and encoder control. So, the function call only needs to set the new direction, and the robot will continue on that course until a new IR button press sets a new direction.  And, the core executing the main function is free to continue with the inner and outer while loops.

      // Motion responses - if key pressed, set wheel speeds
      if(button == CH_UP)drive_rampStep(128, 128);   // Forward
      if(button == CH_DN)drive_rampStep(-128, -128); // Backward
      if(button == VOL_DN)drive_rampStep(-128, 128); // Left turn      
      if(button == VOL_UP)drive_rampStep(128, -128); // Right turn
      if(button == MUTE)drive_rampStep(0, 0);        // Stop

 

Dropping Out of the Inner Loop

Recall that the inner loop is conditional – it only repeats if neither one of the whisker touch-sensors is pressed.  But if a whisker IS pressed, the code execution drops out of the inner loop to the code below.  Here, drive_speed functions make the motors stop, back up quickly for 500 milliseconds, and stop again.  Then, a call to wav_play makes the ActivityBot say “Ouch!”.  The robot will not drive again until it receives another IR signal.

    // Sensor response - if a whisker is pressed
    drive_speed(0, 0);                  // Stop driving
    drive_speed(-100, -100);            // Back up 0.5 seconds
    pause(500);
    drive_speed(0, 0);                  // Stop driving
    wav_play("ouch.wav");               // Play named WAV file
    pause(1000);                        // Pause & return to outer loop
  }            
}

 

AB-IR-Remote-Wav Complete Code Listing

Here is the whole code listing at once:

/*
  AB-IR-Remote-Wav.c
  10/30/2013 version 0.5
  https://learn.parallax.com/activitybot

  ActivityBot plays WAV files on speaker from SD card
  Sensors: IR receiver on P10, touch whiskers on P7 & P8
  Control with Sony-compatible remote (Parallax #020-00001)
  (Brightstar: hold Setup until lit, then enter 605)
  Drive with 5 buttons: Channel+/-, Vol +/-, and mute
  Number keys select WAV files to play
  If whiskers are pressed, robot backs up & stops, plays WAV
*/

#include "simpletools.h"
#include "wavplayer.h"                  // Needs 0.9 or later              
#include "abdrive.h"                    // Needs 0.5.5 or later
#include "sirc.h"              


int main()                              // Main - execution begins!
{
  freqout(4, 2000, 2000);               // Start beep - low battery reset alarm
  drive_speed(0,0);                     // Start servos/encoders cog
  drive_setRampStep(10);                // Set ramping at 10 ticks/sec per 20 ms
  sirc_setTimeout(50);                  // Remote timeout = 50 ms

  int DO = 22, CLK = 23, DI = 24, CS = 25;  // Declare SD I/O pins
  sd_mount(DO, CLK, DI, CS);                // Mount SD card
  wav_volume(7);                            // Set vol here, 1 - 10  

  while(1)                               // Outer loop
  {
    while((input(7) + input(8)) == 2)    // Inner loop while whiskers not pressed
    {
      int button = sirc_button(10);      // check for remote key press
 
      // Audio responses - if number key pressed, play named WAV file
      if(button == 1)wav_play("hello.wav");               
      if(button == 2)wav_play("follow.wav");   
      if(button == 3)wav_play("byebye.wav");                
      if(button == 4)wav_play("oops.wav");                
      if(button == 5)wav_play("thankyou.wav");                 
      if(button == 6)wav_play("dontknow.wav");                   
      if(button == 7)wav_play("yes.wav");               
      if(button == 8)wav_play("no.wav");                
      if(button == 9)wav_play("maybe.wav");
      if(button == 0)wav_play("electro.wav");                  
 
      // Motion responses - if key pressed, set wheel speeds
      if(button == CH_UP)drive_rampStep(128, 128);   // Forward
      if(button == CH_DN)drive_rampStep(-128, -128); // Backward
      if(button == VOL_DN)drive_rampStep(-128, 128); // Left turn      
      if(button == VOL_UP)drive_rampStep(128, -128); // Right turn
      if(button == MUTE)drive_rampStep(0, 0);        // Stop
    }

    // Sensor response - if a whisker is pressed
    drive_speed(0, 0);                  // Stop driving
    drive_speed(-100, -100);            // Back up 0.5 seconds
    pause(500);
    drive_speed(0, 0);                  // Stop driving
    wav_play("ouch.wav");               // Play named WAV file
    pause(1000);                        // Pause & return to outer loop
  }            
}

Printer-friendly version
Taking a Test Drive
Prev
Do More With This Project
Next

DISCUSSION FORUMS | PARALLAX INC. STORE

About | Terms of Use | Feedback: learn@parallax.com | Copyright©Parallax Inc. 2024

© 2026 Parallax Learn • Built with GeneratePress