Lesson 13: miniAuto Secondary Development

Library Files, RGB Control, and Music Programming

🔧 Advanced programming with custom libraries and hardware control

🎯 Learning Objectives

Programming Skills:

  • Understand and use custom Arduino libraries
  • Control RGB LEDs with button input
  • Program musical sequences with buzzers

Hardware Control:

  • Ultrasonic sensor library functions
  • FastLED library for RGB control
  • Tone library for music generation

📚 Section 6.1: Secondary Development Library File Introduction

Understanding Arduino Libraries

During development, you can simplify programming by using various library files, including official Arduino libraries like Servo and Tone, as well as custom libraries such as Ultrasound and FastLED. This section focuses on explaining the custom libraries that will be used in miniAuto projects.

🔗 Ultrasound Library Functions

The "Ultrasound" library manages the glowing ultrasonic module, allowing you to set RGB LED colors and retrieve distance measurements using I2C communication.

  • Ultrasound::Color(r1, g1, b1, r2, g2, b2) - Controls RGB LED colors on left and right sides
  • Ultrasound::GetDistance() - Returns measured distance from ultrasonic sensor
  • I2C Communication - Uses wireWriteDataArray and wireReadDataArray functions

⚙️ Library Usage Example

Here's how to create an ultrasound object and use its functions:

Ultrasound ul; // Create ultrasound object
ul.Color(0,0,255,0,0,255); // Set both LEDs to blue
int distance = ul.GetDistance(); // Get distance reading

🌈 Section 6.2: RGB Control

Button-Controlled RGB LED

In this lesson, you'll learn how to read the status of the onboard buttons on the Arduino expansion board to control the color of the RGB LED. The three colors—red, green, and blue—can be individually controlled to produce various colorful display effects.

🎮 Program Behavior

  • Default State: RGB LED lights up red
  • Button Pressed (KEY1): LED changes to white
  • Button Released: LED returns to red
  • FastLED Library: Used for precise color control
// RGB Control with Button Input
#include "FastLED.h"

const static uint8_t ledPin = 2;    // RGB LED pin
const static uint8_t keyPin = 3;    // Button pin
static CRGB rgbs[1];                // RGB LED object
bool keyState;                      // Button state detection

void setup() {
  Serial.begin(9600);               // Initialize serial communication
  pinMode(keyPin, INPUT);           // Configure button as input
  FastLED.addLeds<WS2812, ledPin, GRB>(rgbs, 1);  // Initialize RGB LED
  Rgb_Show(255, 0, 0);              // Set initial color to red
}

void loop() {
  keyState = analogRead(keyPin);    // Read button state
  if(keyState) 
    Rgb_Show(255, 0, 0);            // Button released: red
  else 
    Rgb_Show(255, 255, 255);        // Button pressed: white
  delay(100);
}

// RGB Control Function
void Rgb_Show(uint8_t rValue, uint8_t gValue, uint8_t bValue) {
  rgbs[0].r = rValue;               // Set red value
  rgbs[0].g = gValue;               // Set green value  
  rgbs[0].b = bValue;               // Set blue value
  FastLED.show();                   // Display the color
}

🎵 Section 6.3: Play Music

Button-Controlled Buzzer Music

In this lesson, you'll learn how to use the onboard buttons on the Arduino expansion board to control the buzzer and play music. The onboard buzzer is a 5V passive buzzer capable of producing different tones by varying the frequency of the output PWM signal.

🎵 Music Behavior

  • Power On: Robot is ready, buzzer is silent
  • KEY1 Button Pressed: Buzzer plays Super Mario melody (98 notes)
  • Melody Features: Uses note arrays and timing for realistic music
  • Tone Library: Controls frequency and duration of each note

🎬 Demo Video

Buzzer Music Demo

Press KEY1 to play Super Mario theme song

/**
 * @file buzzer_test.ino
 * @brief 音乐播放(Play music)
 * @author Anonymity(Anonymity@hiwonder.com)
 * @version V1.0
 * @date 2024-04-23
 *
 * @copyright Copyright (c) 2024
 *
 */

// Musical note frequencies (Hz) - Standard Arduino definitions
#define NOTE_C4   262
#define NOTE_D4   294
#define NOTE_DS4  311
#define NOTE_E3   165
#define NOTE_E4   330
#define NOTE_F4   349
#define NOTE_FS4  370
#define NOTE_G3   196
#define NOTE_G4   392
#define NOTE_GS3  208
#define NOTE_A3   220
#define NOTE_AS3  233
#define NOTE_B3   247
#define NOTE_C5   523

/* 超级玛丽(Super Mary) */
static int song[98] = {
  NOTE_E4, NOTE_E4, NOTE_E4, NOTE_C4, NOTE_E4, NOTE_G4, NOTE_G3,
  NOTE_C4, NOTE_G3, NOTE_E3, NOTE_A3, NOTE_B3, NOTE_AS3, NOTE_A3, NOTE_G3, NOTE_E4, NOTE_G4, NOTE_A3, NOTE_F4, NOTE_G4, NOTE_E4, NOTE_C4, NOTE_D4, NOTE_B3,
  NOTE_C4, NOTE_G3, NOTE_E3, NOTE_A3, NOTE_B3, NOTE_AS3, NOTE_A3, NOTE_G3, NOTE_E4, NOTE_G4, NOTE_A3, NOTE_F4, NOTE_G4, NOTE_E4, NOTE_C4, NOTE_D4, NOTE_B3,
  NOTE_G4, NOTE_FS4, NOTE_E4, NOTE_DS4, NOTE_E4, NOTE_GS3, NOTE_A3, NOTE_C4, NOTE_A3, NOTE_C4, NOTE_D4, NOTE_G4, NOTE_FS4, NOTE_E4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_C5, NOTE_C5,
  NOTE_G4, NOTE_FS4, NOTE_E4, NOTE_DS4, NOTE_E4, NOTE_GS3, NOTE_A3, NOTE_C4, NOTE_A3, NOTE_C4, NOTE_D4, NOTE_DS4, NOTE_D4, NOTE_C4,
  NOTE_C4, NOTE_C4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4, NOTE_A3, NOTE_G3, NOTE_C4, NOTE_C4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4,
  NOTE_C4, NOTE_C4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4, NOTE_A3, NOTE_G3
};

/* 节拍(rhythm) */
static int noteDurations[98] = {
  8,4,4,8,4,2,2,
  3,3,3,4,4,8,4,8,8,8,4,8,4,3,8,8,3,
  3,3,3,4,4,8,4,8,8,8,4,8,4,3,8,8,2,
  8,8,8,4,4,8,8,4,8,8,3,8,8,8,4,4,4,8,2,
  8,8,8,4,4,8,8,4,8,8,3,3,3,1,
  8,4,4,8,4,8,4,8,2,8,4,4,8,4,1,
  8,4,4,8,4,8,4,8,2
};

const static uint8_t buzzerPin = 3;    ///< 按键状态检测(detect button status)
const static uint8_t keyPin = A3;
bool keyState;                         ///< 按键状态检测(detect button status)
bool taskStart = 0;

void setup() {
  pinMode(keyPin, INPUT);
  Serial.begin(9600);
  // 设置串行端口读取数据的超时时间(Set the timeout for serial port data reading)
  Serial.setTimeout(500);
}

void loop() {
  keyState = analogRead(keyPin);  //检测按键状态(detect button status)
  if (!keyState) taskStart = 1;
  if (taskStart)
  {
    tune_task();    // 播放音乐(Play music)
    taskStart = 0;
  }
}

void tune_task(void) {
  for (int thisNote = 0; thisNote < 98; thisNote++)
  {
    int noteDuration = 1000/noteDurations[thisNote];// 计算每个节拍的时间,以一个节拍一秒为例,四分之一拍就是1000/4毫秒,八分之一拍就是1000/8毫秒(Calculate the time for each beat, assuming one beat per second, a quarter note is 1000/4 milliseconds, and an eighth note is 1000/8 milliseconds)
    tone(buzzerPin, song[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.10; //每个音符间的停顿间隔,以该音符的130%为佳(The pause interval between each note, 130% of the duration of this note is recommended)
    delay(pauseBetweenNotes);
    noTone(buzzerPin);
  }
}
← Previous: Lesson 12
Course Overview
Next: Lesson 14 - Obstacle Avoidance →