How to Run an ANC PID Control Program at Boot on a Raspberry Pi

Protonest IoT
6 min readNov 7, 2024

--

In this article, we’ll guide you through the process of setting up an ANC (Active Noise Cancellation) PID control program to run automatically on a Raspberry Pi at boot. The ANC algorithm was developed with cpp and tested with Raspberry Pi using two microphones and and speaker setup.

Running an audio-related program at boot requires careful handling of environment variables, ensuring access to audio devices, and configuring a service to manage the startup process.

Components Needed

Here are the components we used in the project,

  1. INMP441 Omnidirectional Microphone Module I2S Interface MEMS -2
  2. Raspberry Pi 4–4GB (Kit)
  3. Jumper Wires — (Male head, female JST, 3 pin, 30 cm)
  4. Breadboard
  5. Speaker

First you need to install the sound card on the raspberry Pi by following the below article,

The circuit diagram we used for the ANC system is as below,

Out of the two mics, left channel is the noise mic and the right channel is the feedback mic.

Connect the speakers for 3.5mm port on raspberry pi.

The ANC algorithm was implemented in C++.

You can download the codes from the below repo,

https://github.com/udarabs-1/ANC/

Add the codes to a suitable directory, and navigate to the directory through the terminal.

Setting Up the ANC Code

Installing the PortAudio Library

Now, you need to install PortAudio Library through the following commands,

sudo apt-get install libasound-dev
cd portaudio
./configure
make

Before the implementation of the ANC algorithm, initial tests can be conducted to verify the mics and the speaker by running playback.cpp.

g++ playback.cpp -o playback -lportaudio -lm
./playback

Execute the simple proportional implementation by executing the simple.cpp. The variable called “GAIN” can be adjusted manually to tune the gain. This implementation verifies the basic ANC by manual tuning of the gain.

g++ simple.cpp -o simple -lportaudio -lm
./simple

Execute the PID.cpp for PID tuning of the gain.

g++ PID.cpp -o PID -lportaudio -lm
./PID

The PID controller for the gain can be tuned by following these steps. After each modification, compile and run the code using the above two commands.

PID Tuning

Step 1: Set Initial Values

Before starting, set Ki and Kd to 0, and focus on Kp first. This isolates the proportional control, making it easier to tune before adding the other terms.

  • Kp: Start with a small value, such as 0.1, and gradually increase it until you see a fast response, but not too fast or unstable.
  • Ki: After tuning Kp, introduce Ki to eliminate steady-state errors and ensure the noise is fully canceled over time.
  • Kd: Once Kp and Ki are set, fine-tune Kd to reduce oscillations and prevent overshooting.

Step 2: Tune Kp (Proportional Gain)

  • Increase Kp gradually until the system starts reacting quickly to noise but without oscillations or instability.
  • If Kp is too low: The system will respond slowly, and the noise cancellation will be weak or ineffective.
  • If Kp is too high: The system will react too aggressively, causing oscillations, instability, or even amplifying the noise.

Step 3: Tune Ki (Integral Gain)

  • Ki eliminates steady-state errors by accounting for the accumulated error over time.
  • Increase Ki gradually to make sure any residual noise (long-term errors) is canceled out.
  • If Ki is too low: Residual noise won’t be fully canceled, and the system may take too long to converge.
  • If Ki is too high: The system will become sluggish and may introduce overshooting or oscillations.

Step 4: Tune Kd (Derivative Gain)

  • Kd helps predict future errors by looking at the rate of change of the error signal, providing damping to reduce oscillations.
  • Increase Kd slowly to smooth out the system’s response and prevent overshooting.
  • If Kd is too low: The system will oscillate and may overshoot.
  • If Kd is too high: The system will react sluggishly and might not converge to the desired level.

Step 5: Fine-Tuning

  • After you’ve set reasonable values for Kp, Ki, and Kd, you can fine-tune them by testing the system’s response to varying noise levels. Make small adjustments to see if you can improve response time or reduce oscillations further.

Running the code on Boot

Understand the Environment and Audio Setup

Before configuring your ANC program, you need to ensure that your Raspberry Pi can recognize the correct audio hardware. This involves using ‘aplay’ and ‘arecord’ to list available playback and capture devices.

aplay -l
arecord -l

This will show you the available playback and capture hardware on your Raspberry Pi. In this example, we were using a Google voiceHAT for audio input and output.

Identify Necessary Environment Variables

We need the correct environment variables for the program to work in the same way it does when executed manually. Run the ‘printenv’ command to list all environment variables. For example:

printenv

The key environment variables for our scenario were,

  • ‘DISPLAY’: Required for X11-based applications.
  • ‘XAUTHORITY’: Needed for graphical session authentication.
  • ‘XDG_RUNTIME_DIR’: Ensures access to audio devices and user-specific directories.

Test the Program Manually

We first tested the program by setting the necessary environment variables in a single command. The command that worked was:

sudo -u Protonest bash -c "export DISPLAY=:0 && export XAUTHORITY=/home/Protonest/.Xauthority && export XDG_RUNTIME_DIR=/run/user/1000 && cd /home/Protonest/ANC_Test && ./PID"

This command,

  • Switches to the ‘Protonest’ user.
  • Exports the necessary environment variables.
  • Changes the working directory to where the program is located.
  • Executes the ANC PID program.

Once this command worked, we knew it could be used in a service to run at boot.

Set Up a Systemd Service for Auto Start at Boot

To make the program run at boot, we created a ‘systemd’ service.

  1. Create a new systemd service file
sudo nano /etc/systemd/system/anc_service.service

2. Add the following content to the service file,

[Unit]
Description=ANC PID Control Service
After=network.target sound.target

[Service]
Type=simple
User=Protonest
WorkingDirectory=/home/Protonest/ANC_Test/
ExecStart=/bin/bash -c "export DISPLAY=:0 && export XAUTHORITY=/home/Protonest/.Xauthority && export XDG_RUNTIME_DIR=/run/user/1000 && ./PID"
Restart=on-failure
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/Protonest/.Xauthority
Environment=XDG_RUNTIME_DIR=/run/user/1000

[Install]
WantedBy=multi-user.target

This service,

  • Specifies the ‘User’ as ‘Protonest’.
  • Sets the working directory.
  • Ensures the environment variables are available to the program.
  • Uses ‘Restart=on-failure’ to automatically restart if the service fails.

Note: You need to change these according to your setup

3. Reload the systemd configuration

sudo systemctl daemon-reload

4. Enable the service to run at boot

sudo systemctl enable anc_service.service

5. Start the service manually to verify it works

sudo systemctl start anc_service.service

6. Check the status of the service

sudo systemctl status anc_service.service

This command will let you know if the service started correctly or if there were any issues.

Ensure Audio Access and Permissions

To ensure that the ‘Protonest’ user had proper access to audio devices, we needed to add the user to the ‘audio’ group:

sudo usermod -aG audio Protonest

Then, we confirmed that the PulseAudio system was running,

sudo -u Protonest pulseaudio - kill # Kill any running instances
sudo -u Protonest pulseaudio - start # Start PulseAudio for the user

Reboot and Verify

Once everything was set, we rebooted the Raspberry Pi,

sudo reboot

After rebooting, the ANC PID control program started automatically at boot, capturing audio from the microphones and providing active noise cancellation through the speakers.

Conclusion

By carefully managing environment variables, configuring system permissions, and setting up a systemd service, we successfully ran the ANC PID control program at boot on the Raspberry Pi. This setup can be adapted for other applications that require specific environment settings and device access.

By following these steps, you can ensure that your ANC program runs reliably and without manual intervention after each reboot.

Hope you enjoyed the article. Please comment below or send us an email to info@protonest.co, if you face any issues when implementing.

We’ve launched the IoT System Design Tool by Protonest to help you build complete IoT systems, with resources along the way.

Use it for your next IoT project and streamline your design process!

https://iot-system-design-tool.protonest.co

Contact us for any consultations or projects related to IoT and embedded systems.

Email: info@protonest.co

Protonest for more details.

Protonest specializes in transforming IoT ideas into reality. We offer prototyping services from concept to completion. Our commitment ensures that your visionary IoT concepts become tangible, innovative, and advanced prototypes.

Our Website: https://www.protonest.co/

Cheers!

--

--

Protonest IoT
Protonest IoT

Written by Protonest IoT

We make your IoT ideas a reality

No responses yet