Arduino Forum

Using Arduino => Audio => Topic started by: teckel on Apr 25, 2014, 04:45 pm

Title: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: teckel on Apr 25, 2014, 04:45 pm
I've already written 3 alternative tone libraries (toneAC (https://bitbucket.org/teckel12/arduino-toneac/wiki/Home), toneAC2 (https://bitbucket.org/teckel12/arduino-toneac2/wiki/Home) & NewTone (https://bitbucket.org/teckel12/arduino-new-tone/wiki/Home)).  However, a user asked for a way to create tones without using any timers as he had conflicts with both timer 1 and timer 2.  This seemed like a perfect opportunity to confuse people further by creating a 4th library that did essentially the same thing, generate sound.  So, I wrote up sample code that evolved into the TimerFreeTone library.  As a bonus, it works with all ATmega/ATtiny AVR microcontrollers as well as the Arduino Due, Teensy 3.x and other ARM-based microcontrollers equally well.  As a second bonus, it allows you to set a volume level per note.

Download TimerFreeTone v1.5 (https://bitbucket.org/teckel12/arduino-timer-free-tone/downloads)

v1.5 - Fixed problem with latest release of the Arduino IDE which caused the library to totally stop functioning. Adjusted note duration to not fail on timer rollover. Now delays for note duration when frequency or volume are zero.

v1.4 Added optional volume parameter.

v1.3 Fixed problem with long tone play durations. Changed the way the note duration is calculated from a suggestion by Paul Stoffregen.

v1.2 calculates duration differently for higher tone accuracy and smaller code size.

v1.1 added a few small changes (after I got around to actually tested the library first-hand with an Arduino).

Code: [Select]
#include <TimerFreeTone.h>

#define TONE_PIN 10 // Pin you have speaker/piezo connected to (be sure to include a 100 ohm resistor).

int melody[] = { 262, 196, 196, 220, 196, 0, 247, 262 };
int duration[] = { 250, 125, 125, 250, 250, 250, 250, 250 };

void setup() {
  for (int thisNote = 0; thisNote < 8; thisNote++) { // Loop through the notes in the array.
    TimerFreeTone(TONE_PIN, melody[thisNote], duration[thisNote]); // Play thisNote for duration.
    delay(50); // Short delay between notes.
  }
}

void loop() {}


TimerFreeTone Library home page (https://bitbucket.org/teckel12/arduino-timer-free-tone/wiki/Home)

Tim
Title: Re: Usefulness of a tone library that doesn't use timers
Post by: robtillaart on Apr 25, 2014, 08:02 pm
imho more choices is a good thing, especially if this new lib is on the same quality level of previous work!
Title: Re: TimerFreeTone Library v1.1 - Generate audio tones without any timer conflicts
Post by: teckel on Apr 30, 2014, 06:44 pm
New version of the Timer FreeTone library released.

Download TimerFreeTone v1.1 (https://docs.google.com/uc?export=download&id=0B_FPiLH_xoIXbW10UFNtSE16VHc)

This release was actually tested on an Arduino, so I'm sure it works now.  I also fixed/changed a few things.  It generates code that's a bit smaller as well.  Let me know how it works for you!

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: evancleary on Jun 21, 2015, 02:50 am
hi Tim,

thanks for the library, I am trying to play a tone before a for loop but when i place it there in the code the tone repeats and the code freezes

any ideas?

Code: [Select]
#include <TimerFreeTone.h>
#include <SevenSeg.h>


SevenSeg disp1(30,31,32,33,34,35,36);
SevenSeg disp2(40,41,42,43,44,45,46);

const int numOfDigits1 = 3;
const int numOfDigits2 = 2;
int digitPins1[numOfDigits1] = {2,3,4};
int digitPins2[numOfDigits2] = {5,6};

void setup() {
  disp1.setDigitPins(numOfDigits1,digitPins1);
  disp1.setDigitDelay(2000);
  disp1.setTimer(1);
  disp1.startTimer();
 
  disp2.setDigitPins(numOfDigits2,digitPins2);
  disp2.setDigitDelay(2000);
  disp2.setTimer(2);
  disp2.startTimer();
 
  disp1.setCommonCathode();
  disp2.setCommonCathode();
 

}

void loop() {
  disp2.write(23);
  TimerFreeTone(13, 500, 500);
 for (int i = 180; i >= 0; i--){
 
            disp1.writeClock(i);
            delay(100);
 }
 
}

ISR(TIMER1_COMPA_vect){
  disp1.interruptAction();
}

ISR(TIMER2_COMPA_vect){
  disp2.interruptAction();
}
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Jun 22, 2015, 05:49 pm
New version of the Timer FreeTone library released.

Download TimerFreeTone v1.1 (https://docs.google.com/uc?export=download&id=0B_FPiLH_xoIXbW10UFNtSE16VHc)

This release was actually tested on an Arduino, so I'm sure it works now.  I also fixed/changed a few things.  It generates code that's a bit smaller as well.  Let me know how it works for you!

Tim
hi Tim,

thanks for the library, I am trying to play a tone before a for loop but when i place it there in the code the tone repeats and the code freezes

any ideas?

Code: [Select]
#include <TimerFreeTone.h>
#include <SevenSeg.h>


SevenSeg disp1(30,31,32,33,34,35,36);
SevenSeg disp2(40,41,42,43,44,45,46);

const int numOfDigits1 = 3;
const int numOfDigits2 = 2;
int digitPins1[numOfDigits1] = {2,3,4};
int digitPins2[numOfDigits2] = {5,6};

void setup() {
  disp1.setDigitPins(numOfDigits1,digitPins1);
  disp1.setDigitDelay(2000);
  disp1.setTimer(1);
  disp1.startTimer();
 
  disp2.setDigitPins(numOfDigits2,digitPins2);
  disp2.setDigitDelay(2000);
  disp2.setTimer(2);
  disp2.startTimer();
 
  disp1.setCommonCathode();
  disp2.setCommonCathode();
 

}

void loop() {
  disp2.write(23);
  TimerFreeTone(13, 500, 500);
 for (int i = 180; i >= 0; i--){
 
            disp1.writeClock(i);
            delay(100);
 }
 
}

ISR(TIMER1_COMPA_vect){
  disp1.interruptAction();
}

ISR(TIMER2_COMPA_vect){
  disp2.interruptAction();
}

So, you're saying if you comment out *JUST* this line: TimerFreeTone(13, 500, 500); it hangs?  Could it be that it's always hanging but you don't realize it?  In other words, the audio indicator is telling you it's hanging, but it's also hanging without TimerFreeTone you just can't tell because there's no audio indication?

TimerFreeTone doesn't use timer interrupts.  But, it does use delayMicroseconds.  If SevenSeg.h messes with the Arduino timer in such a way that it messes up delayMicroseconds, it could cause a problem.

Have you tried contacting the SevenSeg.h authors?  TimerFreeTone is very simple, the entire code is here to review:

https://bitbucket.org/teckel12/arduino-timer-free-tone/src/f56f6255785f167adf28193ac78c1f62f2aa8405/TimerFreeTone.cpp?at=master

It does nothing fancy, sets the pin to output mode, calculates the square wave duration (frequency) and note duration (loops) and runs a "for" statement for however many loops are required to plan the tone for the specified length of time.

My guess is that SevenSeg is messing with the delayMicroseconds command and that's causing the problem.

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: Grumpy_Mike on Feb 26, 2016, 06:06 pm
I am trying to use TimerFreeTone, and while it works it seems to choke on some duration values. I was using a pot to increase the duration and found that certain values produce a much shorter tone than that given in the duration parameter.
I striped down the code to just a fixed values, it is here:-
Code: [Select]
#include <TimerFreeTone.h>
const byte tonePin = 3;
void setup() {
pinMode(tonePin,OUTPUT);
}

void loop() {
  makeStep();
  delay(20);
}

void makeStep(){
  TimerFreeTone(tonePin,440, 400);
}

What happens is that it just outputs two cycles of the tone and then stops short. So the duration of the tone is 3.5mS not the 400 given in the duration parameter.
I have tried IDE 1.6.5 and IDE 1.6.7 with the same results. I used a Uno as well as an ATtiny85 and I still get this choking. Other values work as expected, but some result in this short tone.
Any ideas?
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Feb 27, 2016, 12:08 am
I am trying to use TimerFreeTone, and while it works it seems to choke on some duration values. I was using a pot to increase the duration and found that certain values produce a much shorter tone than that given in the duration parameter.
I striped down the code to just a fixed values, it is here:-
Code: [Select]
#include <TimerFreeTone.h>
const byte tonePin = 3;
void setup() {
pinMode(tonePin,OUTPUT);
}

void loop() {
  makeStep();
  delay(20);
}

void makeStep(){
  TimerFreeTone(tonePin,440, 400);
}

What happens is that it just outputs two cycles of the tone and then stops short. So the duration of the tone is 3.5mS not the 400 given in the duration parameter.
I have tried IDE 1.6.5 and IDE 1.6.7 with the same results. I used a Uno as well as an ATtiny85 and I still get this choking. Other values work as expected, but some result in this short tone.
Any ideas?
I've got a guess.  Try the following beta and let me know if that works:

http://www.leethost.com/link_pics/TimerFreeTone_v1.3BETA.zip

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: pjrc on Feb 28, 2016, 02:26 am
Tim, will this create inaccurate (lower) frequencies if a significant number of interrupts occur during the delayMicroseconds() calls?

For example, someone could use Serial.print() right before calling TimerFreeTone().  Or they could have another library like Servo or FreqMeasure running, which is constantly servicing interrupts from the timers.  In fact, if they need this timer-free code, it's a safe bet they probably have a project already doing something useful with all the timers, which often involves interrupts.

Wouldn't it be better to read micro() at the beginning, and then in busy loops for the delays, so you can automatically adapt to interrupts consuming CPU time?
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Feb 28, 2016, 10:21 pm
Tim, will this create inaccurate (lower) frequencies if a significant number of interrupts occur during the delayMicroseconds() calls?

For example, someone could use Serial.print() right before calling TimerFreeTone().  Or they could have another library like Servo or FreqMeasure running, which is constantly servicing interrupts from the timers.  In fact, if they need this timer-free code, it's a safe bet they probably have a project already doing something useful with all the timers, which often involves interrupts.

Wouldn't it be better to read micro() at the beginning, and then in busy loops for the delays, so you can automatically adapt to interrupts consuming CPU time?
That may work better in certain conditions for sure, but with additional overhead.  This library is by no means accurate in frequency nor duration if there's a lot of other interrupts happening.  I guess it's designed to simply "work" but with the understanding that accuracy is out.

I would use this library for simple "beep" indications when all timers are used.  Not really good no matter how the duration is calculated if the user is trying to play a melody while other interrupts are triggering.  The length may be a bit more accurate with your suggestion, but the frequency will still be off.

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Feb 29, 2016, 03:02 pm
Tim, will this create inaccurate (lower) frequencies if a significant number of interrupts occur during the delayMicroseconds() calls?

For example, someone could use Serial.print() right before calling TimerFreeTone().  Or they could have another library like Servo or FreqMeasure running, which is constantly servicing interrupts from the timers.  In fact, if they need this timer-free code, it's a safe bet they probably have a project already doing something useful with all the timers, which often involves interrupts.

Wouldn't it be better to read micro() at the beginning, and then in busy loops for the delays, so you can automatically adapt to interrupts consuming CPU time?
Thanks for the suggestion.  I did some testing and the overhead is lower in a "while" loop checking millis() than a "for" loop.  I figured it would be the other way around.  Anyway, I'll probably take your advice and change the way the note duration is calculated and looped.

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: GCMan on Jul 14, 2016, 05:40 am
Hi Tim,

I have this error while compiling for ATtiny13A in Arduino 1.6.9:


error: 'portModeRegister' was not declared in this scope

   uint8_t *portMode = (uint8_t *) portModeRegister(digitalPinToPort(pin));             // Get the port mode register for the pin.

exit status 1
Error compiling for board Attiny 13A standalone 9.6Mhz.

No issue when I compile for Arduino Uno.

Can this library run on Attiny13A?

Thanks.

GC
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Jul 14, 2016, 06:27 pm
Can this library run on Attiny13A?
Sounds like whatever core you're using to compile for the ATtiny13A doesn't support port register calls.  My library will work on the ATtiny13A if the core includes port register compatibility (which it appears to not).

I tried to duplicate it, but I can't find in the Arduino IDE board manager where you load the ATtiny13A core.  Probably because it's not officially supported by Arduino.  So, what core are you using for the ATtiny13A?

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: spicajames on Aug 04, 2016, 08:17 pm
I've been using this lib and it's great, I'm using it together with a servo and rgb leds.

I'm wondering if we could control volume by software?
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Aug 04, 2016, 11:14 pm
I'm wondering if we could control volume by software?
A single-channel digital potentiometer would work.  Or, you could try this beta release of TimerFreeTone

TimerFreeTone v1.4 (https://bitbucket.org/teckel12/arduino-timer-free-tone/downloads) - Added optional volume parameter

It's untested, but my guess is that it will work.  The syntax for setting the volume is simple, just add another parameter at the end of TimerFreeTone with a volume range of 0 to 10 (0=off, 10=full volume).  Below are the details:

SYNTAX:
  TimerFreeTone( pin, frequency, duration [, volume ] ) - Play a note on pin at frequency in Hz for duration in milliseconds.
    Parameters:
      * pin        - Pin speaker is wired to (other wire to ground, be sure to add an inline 100 ohm resistor).
      * frequency  - Play the specified frequency (should work fairly well in the 100 to 15000 Hz range).
      * duration   - Set the duration to play in milliseconds. Range: 0 to 65535 (65.5 seconds).
      * volume     - Optionally set the tone volume level (from 0 to 10), defaults to full volume (10).


Let me know if and how it works!


Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: spicajames on Aug 05, 2016, 05:42 pm
Yes, it works great!

Thanks.
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Aug 05, 2016, 05:54 pm
Yes, it works great!

Thanks.
I did some testing last night and changed the volume array in TimerFreeTone.cpp so it works a bit better.  The line you should change in the beta is this:

uint8_t _tft_volume[] = { 255, 200, 150, 125, 100, 87, 50, 33, 22, 2 }; // Duty for linear volume control.


I'll be releasing v1.4 today so you can also download it which will include this modification.

Tim
Title: Re: TimerFreeTone Library v1.1: Play tones without timers and therefore no conflicts
Post by: teckel on Aug 06, 2016, 12:15 am
TimerFreeTone v1.4 was released adding an optional volume parameter.  Get it here:

TimerFreeTone v1.4 (https://bitbucket.org/teckel12/arduino-timer-free-tone/downloads)

Tim
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: mexus on Sep 12, 2016, 03:02 pm
TimerFreeTone v1.4 and the example doesn't work for me. No compile errors.
No sound at all. Using one of your other libs or standart tone works.
I need no timer sound, or using timer0 (pins 5 or 6) without breaking time functions.
I need pins 9,10 and 3,11 for high frequency PWM
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: teckel on Sep 12, 2016, 06:08 pm
TimerFreeTone v1.4 and the example doesn't work for me. No compile errors.
No sound at all. Using one of your other libs or standart tone works.
I need no timer sound, or using timer0 (pins 5 or 6) without breaking time functions.
I need pins 9,10 and 3,11 for high frequency PWM
You can't use timer 0 without breaking time functions, so your only option is using TimerFreeTone.  Are you using the example sketch and not getting sound output?  Have you tried using a different pin (A0 is a good one to try).  The example is using pin 10, which you should avoid as you're doing something with the PWM.

Anyway, my guess would be a timer conflict, and simply using a different pin would work.  But, I'd need to see your sketch as well as a description of how you have things connected.  I'll verify everything works later today, but I believe the example sketch works without a problem.

Tim
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: teckel on Sep 13, 2016, 06:29 am
TimerFreeTone v1.4 and the example doesn't work for me. No compile errors.
No sound at all. Using one of your other libs or standart tone works.
I need no timer sound, or using timer0 (pins 5 or 6) without breaking time functions.
I need pins 9,10 and 3,11 for high frequency PWM
Seems that something changed in the latest release of the Arduino IDE that caused TimerFreeTone to totally fail.  I've updated it to version 1.5 which corrects the problem.

Let me know if there's any issues.

Tim
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: mexus on Sep 13, 2016, 11:24 am
Thank you, Tim!
Now it works. It doesn't break my timers and PWM outputs :).
Great, just what I've needed for my project.
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: mexus on Sep 13, 2016, 02:24 pm
Shouldn't unsigned int duration be unsinged long duration?
I replaced it in your lib. So that it can work even TCCR0B = TCCR0B & B11111000 | B00000001.
Setting clock 0 to this makes one second last 64000 instead of 1000 millis. This causes your function to overflow. If you are working with millis() than you should use unsigned long not unsigned int.
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: teckel on Sep 13, 2016, 06:17 pm
Shouldn't unsigned int duration be unsinged long duration?
I replaced it in your lib. So that it can work even TCCR0B = TCCR0B & B11111000 | B00000001.
Setting clock 0 to this makes one second last 64000 instead of 1000 millis. This causes your function to overflow. If you are working with millis() than you should use unsigned long not unsigned int.
Duration is set to unsigned int because a note duration of up to 65.5 seconds seemed acceptable, reduces the while loop execution time, and it saves a few bytes of programming space.  It's only looking at duration for the comparison of millis()-startTime, so it should never roll over in real-world situations.

If you're messing with clock 0, all kinds of wacky stuff could happen.  unsigned int is plenty long (65.5 seconds).  If you're changing how long a second is, you should probably not use any libraries as all will assume certain standards exist (like a second is 1000 millis).

I see no reason to change it to unsigned long as it would slow down the while loop.  Also, no one should ever be messing with timer 0 anyway and 65.5 seconds is plenty long for a note to play.

Tim
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: neutralvibes on Oct 02, 2016, 04:37 pm
Hi, this is good stuff. I have been using on an ESP8266  and I thought you may appreciate my minor additions for a new version if of any use.

As I understand it current recommendations state portions of code that may last longer than 20 millis require a yield() or delay(0) within, to allow the ESP8266 to perform housekeeping tasks for Wifi safely.

With the above in mind I offer you a potential solution below. This does affect tonal quality but makes the library safer to use on this platform.

Code: [Select]

 while(millis() - startTime < duration) { // Loop for the duration.
 
 #ifdef __AVR__
 *pinOutput |= pinBit;    // Set pin high.
 delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
 *pinOutput &= ~pinBit;   // Set pin low.
 #elif defined(ESP8266)
 GPOS = (1 << pin); // Set pin high.
 delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
 GPOC = (1 << pin); // Set pin low
 yield();
 #else
 digitalWrite(pin,HIGH);  // Set pin high.
 delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
 digitalWrite(pin,LOW);   // Set pin low.
 #endif
 delayMicroseconds(frequency - duty); // Square wave duration (how long to leave pin low).
 
 }


Cheers
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: teckel on Oct 03, 2016, 07:03 pm
Hi, this is good stuff. I have been using on an ESP8266  and I thought you may appreciate my minor additions for a new version if of any use.

As I understand it current recommendations state portions of code that may last longer than 20 millis require a yield() or delay(0) within, to allow the ESP8266 to perform housekeeping tasks for Wifi safely.

With the above in mind I offer you a potential solution below. This does affect tonal quality but makes the library safer to use on this platform.

Code: [Select]

 while(millis() - startTime < duration) { // Loop for the duration.
 
 #ifdef __AVR__
 *pinOutput |= pinBit;    // Set pin high.
 delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
 *pinOutput &= ~pinBit;   // Set pin low.
 #elif defined(ESP8266)
 GPOS = (1 << pin); // Set pin high.
 delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
 GPOC = (1 << pin); // Set pin low
 yield();
 #else
 digitalWrite(pin,HIGH);  // Set pin high.
 delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
 digitalWrite(pin,LOW);   // Set pin low.
 #endif
 delayMicroseconds(frequency - duty); // Square wave duration (how long to leave pin low).
 
 }


Cheers

I would't think that would be required in this case as it's not doing anything that would prevent the normal WiFi interrupts in the middle of a tone being generated.  I understand when that could be useful, but I don't think it's useful in this context.  Does communications still work even when a note is playing?

Tim
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: parateam on Nov 22, 2016, 10:26 am
Hello, my first post here....

Thanks for your work on this libary

I have a Project on an Feather M0 BLE board and have change the 1.5 Libary: The Piezo is connectet to two pins and the Status for high / low is rversed on the pins to get a louder level. Thie first impression was fine. I removed also unused code. What do you think about that?

A Question: Does this libary play the sound in background? I mean, does the code works on while a Sound is playing?

Thanks, Peter



Code: [Select]

// ---------------------------------------------------------------------------
// Created by Tim Eckel - teckel@leethost.com
// Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl-3.0.html
//
// See "TimerFreeTone.h" for purpose, syntax, version history, links, and more.
// ---------------------------------------------------------------------------

#include "TimerFreeTone.h"

uint8_t _tft_volume[] = { 255, 200, 150, 125, 100, 87, 50, 33, 22, 2 }; // Duty for linear volume control.

void TimerFreeTone(uint8_t pin1, uint8_t pin2, unsigned long frequency, unsigned int duration, uint8_t volume) {
if (frequency == 0 || volume == 0) { // If frequency or volume are zero, just wait duration and exit.
delay(duration);
return;
}
frequency = 1000000 / frequency;                              // Calculate the square wave length (in microseconds).
uint32_t duty = frequency / _tft_volume[min(volume, 10) - 1]; // Calculate the duty cycle (volume).
pinMode(pin1, OUTPUT);                                                       // Set pin to output mode.
pinMode(pin2, OUTPUT);

uint32_t startTime = millis();           // Starting time of note.
while(millis() - startTime < duration) { // Loop for the duration.
digitalWrite(pin1,HIGH);  // Set pin high.
digitalWrite(pin2, LOW);
delayMicroseconds(duty); // Square wave duration (how long to leave pin high).
digitalWrite(pin1,LOW);   // Set pin low.
digitalWrite(pin2, HIGH);   // Set pin low.
delayMicroseconds(frequency - duty); // Square wave duration (how long to leave pin low).
}
}
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: teckel on Nov 22, 2016, 03:41 pm
You kind of combined TimerFreeTone with my toneAC library.  The purpose of TimerFreeTone is to not use timers, so no, it doesn't play in the background.  To do that, you must use timers.

I'm guessing you found my TimerFreeTone library because you can't use typical libraries that use timers with the ARM processor on the Feather M0 board.  This is one of the reasons I don't purchase these off boards.  Sure, they can do simple things, but you really can't use most Arduino libraries as they haven't made them very compatible.  They support the basics, but nothing else.

This is why I suggest to only purchase Arduino AVR boards or if you want more speed/features to get a Teensy 3.x board.  Not only is the Teensy 3.x platform very fast, very inexpensive, and capable of doing all sorts of things, Paul Stoffregen spends the time to make them VERY compatible with most Arduino libraries or works with the library authors to make them compatible.

The other problem using ARM-based platforms is that the voltage is 3.3v instead of 5.  While this is the direction of modern devices, there's lots of legacy stuff that uses 5v.  Also, in the case of a speaker, 3.3v isn't much.  It's probably best to build an amp for the speaker instead of what you're doing.  Then, look into the timers of your chip to see if there's a library you can use to interface with it to create sound.  Seriously, it would probably be easier to do Bluetooth and sound playing in the background easier with an Arduino Uno that with the Feather M0 board.

Also, I wouldn't suggest anyone using an Arduino AVR to use your code, it's too slow so you'll have a long time with both pins high going to the piezo.  My library uses shift registers which are MUCH faster to almost totally avoid this problem.

I'll release a TimerFreeToneAC which will do what you want but also be safer for Arduino AVR boards.

Tim
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: spicajames on Nov 22, 2016, 03:56 pm
@parateam
You could see this example http://forum.arduino.cc/index.php?topic=407152.msg2800952#msg2800952 it uses teckel TimerFreeTone, delays are removed and can play in the background.
Title: Re: TimerFreeTone Library v1.4: Play tones without timers and therefore no conflicts
Post by: teckel on Nov 22, 2016, 04:17 pm
But then there's no point in using the library.  If you're just toggling two pins and not using port registers nor volume, there's little point of using my library.  Basically, it's a simple process to just spin your own and not use libraries at all for something this easy.

Tim
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: zgubidan on Feb 18, 2018, 10:45 pm
Hi, I stumbled upon your tone libraries and they are great, but both I tested after playing a melody left humming sound in a speaker.
With toneAC I solved it, with one noToneAC() afterwards, but this one I like better because it uses no timers - a part of bigger project, I need my timers... :o)
So, this library has no command to turn sound off (right?), and I tried writing low digitally, (you can see it), it didn't help, so, what happens is:
after playing a tune speaker buzzes quite low in frequency, and for some 10 seconds, then it goes silent for my delay of 2 seconds, starting all over.
Any idea why this buzzing and why so long?

The code:



#include <TimerFreeTone.h>

#define TONE_PIN 10                                                           // Pin you have speaker/piezo connected to (be sure to include a 100 ohm resistor).



int melody[] = {277,415,415,370,349,370,349,311,311,277,311,349,311,349,370,349,277,349,311,277,415,415,370,349,370,349,311,311,277,311,349,311,349,370,349,277,415};
int noteDurations[] = {320,320,320,160,160,160,160,320,320,160,160,320,160,160,320,160,160,320,1280,320,320,320,160,160,160,160,320,320,160,160,320,160,160,320,160,160,1280};


void setup() {}

void loop() {
  for (int thisNote = 0; thisNote < 38; thisNote++) {                          // Loop through the notes in the array.
    TimerFreeTone(TONE_PIN, melody[thisNote], noteDurations[thisNote]);        // Play melody[thisNote] for duration[thisNote].
    delay(50);                                                                 // Short delay between notes                                               
  }
  digitalWrite(TONE_PIN, LOW);
  delay(2000);
}
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: teckel on Feb 22, 2018, 12:41 am
Hi, I stumbled upon your tone libraries and they are great, but both I tested after playing a melody left humming sound in a speaker.
With toneAC I solved it, with one noToneAC() afterwards, but this one I like better because it uses no timers - a part of bigger project, I need my timers... :o)
So, this library has no command to turn sound off (right?), and I tried writing low digitally, (you can see it), it didn't help, so, what happens is:
after playing a tune speaker buzzes quite low in frequency, and for some 10 seconds, then it goes silent for my delay of 2 seconds, starting all over.
Any idea why this buzzing and why so long?
It will only hold the note for the duration specified.  There's no reason to do anything to end the note as it always ends the note when complete.  What hardware are you running on?

Tim
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: carlsopa on May 23, 2018, 03:29 pm
I came across your library while looking for a way to both play a buzzer and flash a neopixel.  Your library is well done.  What I would like to do is be able to take your library, but play my own song.  For example my project I want to play Happy Birthday.  I was attempting to use the following code:
https://create.arduino.cc/projecthub/trduunze/piezo-happy-birthday-7ea362

They are of course going about it in a complete different way then you.  But I was thinking that taking their melody notes, and putting them in to replace your melody notes, would work.  However, that gave me a song that was not Happy Birthday.

Would I be right in thinking that it comes down to you dividing the notes by 1,000,000 and then a volume?  This is what I see in your .h file. 

Any suggestions, or help would be greatly appreciated.

Paul
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: teckel on May 23, 2018, 05:06 pm
I came across your library while looking for a way to both play a buzzer and flash a neopixel.  Your library is well done.  What I would like to do is be able to take your library, but play my own song.  For example my project I want to play Happy Birthday.  I was attempting to use the following code:
https://create.arduino.cc/projecthub/trduunze/piezo-happy-birthday-7ea362

They are of course going about it in a complete different way then you.  But I was thinking that taking their melody notes, and putting them in to replace your melody notes, would work.  However, that gave me a song that was not Happy Birthday.

Would I be right in thinking that it comes down to you dividing the notes by 1,000,000 and then a volume?  This is what I see in your .h file. 

Any suggestions, or help would be greatly appreciated.

Paul
The example script shows how you would play a melody:

https://bitbucket.org/teckel12/arduino-timer-free-tone/wiki/Home#!example

The molody[] array is the frequency in Hz of the note, the duration[] array is the time in ms to play the note.  A frequency of 0 would be a pause.  There's no dividing of 1,000,000 and no volume at all.  Nothing to change in the .h file whatsoever.  Just take the example script and change the arrays.  You'll need some knowledge of music and note frequency, but it's not rocket science.

Tim
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: carlsopa on May 23, 2018, 05:43 pm
Thanks for the quick response Tim! 

I made a simple mistake, by putting the wrong tone frequencies in.  After I found a reference to the frequencies, I was able to correct it, and works like I wanted.

Paul
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: jirm on Sep 28, 2018, 10:17 pm
Good day.

I`m a happy user that your nice TimerFreeTone libray for years with several esp8266 projects, but now I need to update ESP core to lastest 2.4.2 release and your library seems have issues to compile propperly.
When I try to compile arduino IDE raise several errors about it:

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp: In function 'void TimerFreeTone(uint8_t, long unsigned int, unsigned int, uint8_t)':

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:18:56: error: no matching function for call to 'min(uint8_t&, int)'

  uint32_t duty = frequency / _tft_volume[min(volume, 10) - 1]; // Calculate the duty cycle (volume).

                                                        ^

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:18:56: note: candidates are:

In file included from c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\algorithm:62:0,

                 from C:\Users\IEUser\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266/Arduino.h:255,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.h:59,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:8:

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4226:5: note: template<class _Tp, class _Compare> _Tp std::min(std::initializer_list<_Tp>, _Compare)

     min(initializer_list<_Tp> __l, _Compare __comp)

     ^

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4226:5: note:   template argument deduction/substitution failed:

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:18:56: note:   mismatched types 'std::initializer_list<_Tp>' and 'unsigned char'

  uint32_t duty = frequency / _tft_volume[min(volume, 10) - 1]; // Calculate the duty cycle (volume).

                                                        ^

In file included from c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\algorithm:62:0,

                 from C:\Users\IEUser\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266/Arduino.h:255,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.h:59,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:8:

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4221:5: note: template<class _Tp> _Tp std::min(std::initializer_list<_Tp>)

     min(initializer_list<_Tp> __l)

     ^

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4221:5: note:   template argument deduction/substitution failed:

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:18:56: note:   mismatched types 'std::initializer_list<_Tp>' and 'unsigned char'

  uint32_t duty = frequency / _tft_volume[min(volume, 10) - 1]; // Calculate the duty cycle (volume).

                                                        ^

In file included from c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\algorithm:61:0,

                 from C:\Users\IEUser\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266/Arduino.h:255,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.h:59,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:8:

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:239:5: note: template<class _Tp, class _Compare> const _Tp& std::min(const _Tp&, const _Tp&, _Compare)

     min(const _Tp& __a, const _Tp& __b, _Compare __comp)

     ^

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:239:5: note:   template argument deduction/substitution failed:

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:18:56: note:   deduced conflicting types for parameter 'const _Tp' ('unsigned char' and 'int')

  uint32_t duty = frequency / _tft_volume[min(volume, 10) - 1]; // Calculate the duty cycle (volume).

                                                        ^

In file included from c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\algorithm:61:0,

                 from C:\Users\IEUser\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266/Arduino.h:255,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.h:59,

                 from C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:8:

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:193:5: note: template<class _Tp> const _Tp& std::min(const _Tp&, const _Tp&)

     min(const _Tp& __a, const _Tp& __b)

     ^

c:\users\ieuser\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:193:5: note:   template argument deduction/substitution failed:

C:\Users\IEUser\Documents\Arduino\libraries\TimerFreeTone\TimerFreeTone.cpp:18:56: note:   deduced conflicting types for parameter 'const _Tp' ('unsigned char' and 'int')

  uint32_t duty = frequency / _tft_volume[min(volume, 10) - 1]; // Calculate the duty cycle (volume).

                                                        ^

I dont know if you have any way to solve it, because I like so much your library and always had worked like a charm.

Thank you
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: teckel on Sep 29, 2018, 05:06 pm
Good day.

I`m a happy user that your nice TimerFreeTone libray for years with several esp8266 projects, but now I need to update ESP core to lastest 2.4.2 release and your library seems have issues to compile propperly.
When I try to compile arduino IDE raise several errors about it:
Sounds like you don't have something setup correctly with the 2.4.2 release as TimerFreeTone isn't doing anything complicated that would fail almost totally like that.

Tim
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: jirm on Sep 29, 2018, 11:30 pm
Tim, so many thanks for your quick reply.

OK, but all my others sketches (some of them with tons of other libraries) are compiled without issues, but maybe you are right and I now I have some trouble on my arduino IDE setup, this in that moment is a upgrade from other esp old core setups.

I give again a try with some clean arduino IDE and esp core install, and I report what I have, because I want maintain use your nice TimerFreeTone library.

Best regards

Jose.
 
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: polymorph on Sep 30, 2018, 05:23 am
Always start with the first error. All the other errors may flow from that first error.
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: Nuno_Lima on Oct 11, 2019, 02:26 am
hi..
im new at this, so sorry if im doing a lot of stupid questions..
im doing a project where i use 2 shift registers to control 14 LEDs and i also want to play a song using a buzzer but when i try to do that at the same time, it just plays the song and only then the LEDs work. I tried to use your library because i thought it could be because of timers but it doesnt work anyway.. what can i do ?   
Title: Re: TimerFreeTone Library v1.5: Play tones without timers and therefore no conflicts
Post by: Grumpy_Mike on Oct 11, 2019, 09:57 am
Quote
what can i do ?   
Start a new thread and post your code in it.

It sounds like you have not written your software correctly. Nothing to do with the Tone library.