Can You Play Do-Re-Mi While Line Following? – Task Management in C

by AfrelEdTech in Circuits > Robots

42 Views, 0 Favorites, 0 Comments

Can You Play Do-Re-Mi While Line Following? – Task Management in C

サムネイル.png

Robotics competitions often require robots to perform multiple tasks at the same time — like moving while playing a sound, or detecting something while keeping balance. This tutorial explores one such challenge using a simple, classic test:

Can a robot play Do-Re-Mi-Fa-So-La-Ti-Do while smoothly following a line?

We’ll demonstrate how different the results can be when task separation is handled properly in C — and why basic task management techniques are essential even for simple robots.


Objective

Compare two implementations:

  1. Single-task version – sound and motion are in one loop
  2. Multitask version – sound playback is handled in a cyclic handler

Supplies

  1. LEGO SPIKE Prime (or compatible device) with a color sensor and speaker
  2. 1 PC with Windows 10 or 11 operating system


Hardware Setup

The robot is a simple two-wheeled line follower with a color sensor facing down and mounted near the front center.

  1. Right motor : Port A
  2. Left motor : Port B
  3. Color sensor : Port C
  4. Speaker : Built-in

Single-Task Implementation

In the first version, we write a single task that:

  1. Follows the line
  2. Plays each musical note
pup_motor_t *motorR; // Variable for using motor A
pup_motor_t *motorL; // Variable for using motor B
pup_device_t *ColorSensor; // Variable for using color sensor

void Main(intptr_t exinf)
{
// Initialize motors and sensors
motorR = pup_motor_init(PBIO_PORT_ID_A, PUP_DIRECTION_CLOCKWISE);
motorL = pup_motor_init(PBIO_PORT_ID_B, PUP_DIRECTION_COUNTERCLOCKWISE);
ColorSensor= pup_color_sensor_get_device(PBIO_PORT_ID_C);

// Set the volume
hub_speaker_set_volume(100);

// Musical scale C4~C5
double tone[8] = {
NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};

int8_t i = 0;
while(1){
hub_speaker_play_tone(tone[i], 200);
dly_tsk(200000);
if(pup_color_sensor_reflection(ColorSensor) > 50){
pup_motor_set_speed(motorR, 400);
pup_motor_set_speed(motorL, 150);
}else{
pup_motor_set_speed(motorR, 150);
pup_motor_set_speed(motorL, 400);
}
i++;
if (i >= sizeof(tone) / sizeof(tone[0])) {
i = 0; // repeat
}
}
}


Observation:

  1. While the robot is playing sound, it can’t monitor the line.
  2. As a result, it drifts off the line before finishing the melody.


Task-Separated Implementation (With Cyclic Handler)

In this version, the music is played using a cyclic handler (a periodic task), while the main task continuously handles line tracing.

.c

pup_motor_t *motorR; // Variable for using motor A
pup_motor_t *motorL; // Variable for using motor B
pup_device_t *ColorSensor; // Variable for using color sensor

int8_t i = 0;

// Musical scale C4~C5
static const double tone[8] = {
NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};

void Main(intptr_t exinf)
{
// Initialize motors and sensors
motorR = pup_motor_init(PBIO_PORT_ID_A, PUP_DIRECTION_CLOCKWISE);
motorL = pup_motor_init(PBIO_PORT_ID_B, PUP_DIRECTION_COUNTERCLOCKWISE);
ColorSensor= pup_color_sensor_get_device(PBIO_PORT_ID_C);
// Set the volume
hub_speaker_set_volume(100);
// Start beep_task
sta_cyc(CYC_HDR);

while(1){
if(pup_color_sensor_reflection(ColorSensor) > 50){
pup_motor_set_speed(motorR, 400);
pup_motor_set_speed(motorL, 150);
}else{
pup_motor_set_speed(motorR, 150);
pup_motor_set_speed(motorL, 400);
}
}
}

// Called every 400 ms: Play tone
void beep_task(intptr_t exinf)
{
hub_speaker_play_tone(tone[i], 200);
i++;
if (i >= sizeof(tone) / sizeof(tone[0])) {
i = 0; // repeat
}
}


.cfg

INCLUDE("tecsgen.cfg");

#include "beep_task.h"
CRE_TSK(MAIN_TASK, { TA_ACT, 0, Main, MAIN_PRIORITY + 1, STACK_SIZE, NULL });
CRE_TSK(BEEP_TASK, { TA_NULL, 0, beep_task, MAIN_PRIORITY, STACK_SIZE, NULL });
CRE_CYC(CYC_HDR, { TA_NULL, { TNFY_ACTTSK, BEEP_TASK }, 400*1000, 0 });


Observation:

  1. The robot follows the line smoothly.
  2. Sound plays without interrupting motion.
  3. Each function runs in its own timing = better control.

Comparison Video

Concurrent task part1

Why It Matters

Task separation is more than just a coding technique — it’s a strategic advantage in robotics competitions.

Even a simple challenge like “play Do-Re-Mi while following a line” becomes much harder without proper task handling.

In a single-task version, we use dly_tsk(200000) inside the main while loop to play each note.

While the robot is playing a sound, it pauses its line sensing, which leads to:

  1. Missed line position during playback
  2. Delayed reaction and drifting off the line

By splitting the music and movement into separate tasks, the robot can monitor the line while playing the melody — resulting in smoother and more reliable behavior.


Even a basic challenge can benefit from task separation. Especially in real-world environments like robotics competitions, it brings:

  1. Improved responsiveness
  2. Cleaner, more readable code
  3. A design that’s easier to expand and maintain


Summary

Single-task : Robot drifts off the line during playback

Multitask (cyclic handler) : Smooth line following and uninterrupted sound playback

What's Next?

We’ll handle a more practical challenge:

Drive, Detect, React Line follow + wall detection + emergency stop with resume.

Stay tuned!

【Free Trial】Start C Language Programming With Afrel's Educational Materials

Are you intrigued by the idea of programming your SPIKE™ Prime with C? Did you know that Afrel is a key information provider for SPIKE™ Prime?


To meet the demand of those who want to "learn more about SPIKE™ Prime " and "try programming in C," Afrel has developed and sells educational materials for learning C language programming with SPIKE™ Prime.

Stepping up from Python to C is an excellent opportunity to further enhance your programming skills. Learning C will give you a deeper understanding of how computers work and enable more advanced control.


Afrel's C language materials are designed for beginners, ensuring a smooth learning experience. Why not take this chance to discover the joy of controlling SPIKE™ Prime with C and expand your programming horizons?


If you're ready to tackle C language programming, click the link below for more details.


Learn more about SPIKE™ Prime C Language Programming Materials here