Simultaneous tone() output and PID output possible with Arduino Uno?

Thanks for reading! I'm trying to use an Arduino Uno to simultaneously control a temperature PID loop and output a sweeping tone() signal to a buzzer. I have tried many things but all result in only one of the functions working at once. Is this a limitation of the Arduino/processor to only be able to do one at a time?

See relevant code excerpts below:

#include <PID_v1.h>

void loop(void) {

if (heater_run == true) {      //set from from RasPi Serial connection
  myPID.SetMode(AUTOMATIC);
  Inputt = steinhart;         //temperature of heater
  myPID.Compute();
  analogWrite(3,Outputt);
  }

if (acoustic_mix==true) {   //set from from RasPi Serial connection
  frequency_out = frequency_out + sweep_increment;
  if (frequency_out <= freq_start || frequency_out >= freq_end) {
    sweep_increment = -sweep_increment;
  }
  tone(output_pinn,frequency_out,1050);
  Serial.print("freq:");
  Serial.println(frequency_out);
  //delay(delay_val);
   }

  delay(1000);
}

Things I've tried without success:

  • Instead of Tone(), used analogwrite() to output frequency to buzzer- Didn't make correct frequency sound and couldn't operate with PID loop simultaneously.
  • Used "protothreading" TimedAction.h library to try to do seperate threads to have both actions work simultaneously. Buzzer and PID loop still operated sequentially.
  • Tried using a non-PWM digital Arduino pin to output the freq signal to the buzzer via tone() but it still won't work simultaneously.

Thanks for reading. Please let me know if you have any suggestions!

You are right. The Arduino processor can only do one thing at a time but it can do multiple things in such quick succession that they appear to be happening at the same time

A primary cause of problems in doing this is to use a function that blocks operation of the rest of the code until it is complete. A classic cause of this is the delay() function and the problem is often compounded by using it in a for loop() or even worse by using a while loop

With that in mind, what is that delay() command doing in loop() ?

1 Like

Thanks for your response, Bob! I will experiment with minimizing and removing that delay. I don't remember exactly why that's there but I believe that was put in for either the Serial connection or to slow down the PID loop from outputting every cycle.

It is fairly easy to arrange that some things in the loop run once every N milliseconds, while the rest of the loop runs very much more frequently.

You can find pre-written solutions, but this is really something that should be done and understood without the help libraries.

The IDE "blink without delay" example shows the technique in its simplest form.

Google

Arduino blink without delay

I just did and quickly turned up a good article discussing it thoroughly and gently enough.

HTH

a7

What is the purpose of the "sweeping tone"? Just build a 555 circuit for the tone and turn it on or off from any Arduino output pin.

https://www.instructables.com/Frequency-Sweep-With-555-Timer/

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.