Tone on 2 pins simultaneously

Hi
It is possible to have simultaneously tone on 2 pins ?


void setup()
{
  tone(A2, 2000);
  tone(A3, 2000);
}
void loop()
{
}

google says it is possible if microcontroller has more than 1 timer but doesn't show how to do it.

Arduino uno, I am interested in tone, it is making program simple.

I did a google search and found this forum article from gasp 10 years ago.

It might still be a good starting point though…..
Interesting project….
One question:
Why two piezos/speakers?

//Edit
I forgot to put the link in….. oops’

Also interesting, A revised one.

Make your own function, twoTone(), and have it drive 2 pins using micros timers. One pin making 2 mixed tones... more complicated.

1 Like

6581 has three voices.

3 Likes

The SID chip also does ADSR sound envelope (attack, decay, sustain, release) that is way beyond digital bloops and bleeps.

1 Like

Yes. It was my playground a few years ago. Boops and beeps, too.

2 Likes

the same tone on two pins

Then use two wires coming from the same pin.

3 Likes

Thanks
Ok

All that tone does is turn a pin ON and OFF at some frequency.
You can do the same with very close timing using micros().

Check with member xfpd who likely has done this before.

I dunno about getting a SID chip these days but I have wondered about an AVR driving an ISA soundcard like Ensonique! The PCXT clocked at 4.some megahertz, it served video rasters IIRC.

I know that the OP has probably decided to drive both piezo with one pin but I am curious on how to make a program for running a tone like function that can tone on multiply pins.....
Any recommended reading?

I assume by LED you mean the piezo?
Won't the pitch change if I do that?
By modulating between two of the tones?

If that is the case, it seems easy enough,
I might write a bit of code in a bit…..

Ok,
Here is a wokwi,

Here is the program.
I am not sure if it is working properly or not.
I can’t really hear the differences……
Have not tested on real hardware.
Need to clean up code.
Here is the code, it can probably be improved.


/*
  Two Tones at once test.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int piezoPinOne = LED_BUILTIN;  // the number of the LED pin
const int piezoPinTwo = 12;

// Variables will change:
int ledState = LOW;  // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMicros = 0;  // will store last time LED was updated

// constants won't change:
const long interval = 10;  // interval at which to blink (microseconds)
//10 microseconds see: https://www.arduino.cc/reference/en/language/functions/time/micros/ 
// accuracy 4-8 depending on board.


void setup() {
  // set the digital pin as output:
  pinMode(piezoPinOne, OUTPUT);
  pinMode(piezoPinTwo, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMicros= micros();

  if (currentMicros - previousMicros >= interval) {
    // save the last time you blinked the LED
    previousMicros = currentMicros;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
      noTone(piezoPinTwo);
      noTone(piezoPinOne);
      tone(piezoPinOne, 783.99);
      Serial.println("Playing on pin 13");
      
    } else {
      ledState = LOW;
      noTone(piezoPinOne);
      noTone(piezoPinTwo);
      tone(piezoPinTwo, 523.25);
      Serial.println("Playing on pin 12");

    }

    // set the LED with the ledState of the variable:
    
  }
}




Sounds pretty good.
Note, the wokwi is not the same code…..
The code here is slightly better…… i think…

1 Like

Hello tom321

Consider:

//https://forum.arduino.cc/t/tone-on-2-pins-simultaneously/1193203
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "Tone on 2 pins simultaneously"
#define NotesOnRelease "A"
// -- some useful text replacements used because I'm lazy with typing --
#define equ ==
#define view(x) Serial.print(x)
#define viewLn(x) Serial.println(x)
// make names
enum TimerEvent {NotExpired, Expired};
// make variables
constexpr uint8_t Pins[] {9, 10};
constexpr uint32_t Frequencies[] {1, 2};
// make structures
struct TIMER
{
  uint32_t interval;
  uint32_t now;
  uint8_t expired(uint32_t currentMicros)
  {
    uint8_t timerEvent = currentMicros - now >= interval;
    if (timerEvent equ Expired) now = currentMicros;
    return timerEvent;
  }
};
struct MYTONE
{
  uint8_t pin;
  TIMER timer;
  void run(uint32_t currentMicros)
  {
    if (timer.expired(currentMicros) equ Expired) digitalWrite(pin, digitalRead(pin) ? LOW : HIGH);
  }
  void make(uint8_t pin_, uint32_t frequency)
  {
    pin = pin_;
    pinMode(pin,OUTPUT);
    timer.interval = 2 * (1000000 / frequency);
    view("tone @ "), view(pin), view(" with "), view(frequency), viewLn(" Hertz");
  }
} myTones[sizeof(Pins)];
// make support
void heartBeat(const uint8_t LedPin, uint32_t currentMillis)
{
  static bool setUp = false;
  if (setUp == false) pinMode (LedPin, OUTPUT), setUp = true;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
// make application
void setup()
{
  Serial.begin(115200);
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  uint8_t element = 0;
  for (auto &myTone : myTones)
  {
    myTone.make(Pins[element], Frequencies[element]);
    element++;
  }
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  uint32_t currentMillis = millis();
  uint32_t currentMicros = micros();
  heartBeat(LED_BUILTIN, currentMillis);
  for (auto &myTone : myTones) myTone.run(currentMicros);
}

Have a nice day and enjoy coding in C++.

3 Likes

Search on Direct Port Manipulation

2 Likes

Thanks, guys, for support, I know about blink without delay.