Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/arduino tone notone #177

Merged
merged 6 commits into from
May 8, 2014
Merged

Feature/arduino tone notone #177

merged 6 commits into from
May 8, 2014

Conversation

satishgn
Copy link
Contributor

No description provided.

@tiegz
Copy link

tiegz commented Apr 21, 2014

👍 thanks!

@technobly
Copy link
Member

This looks a lot better than I imagined it being. Great job. I think there needs to be some kind of global way to know if a pin is defined as a PWM, SERVO or TONE output already. That way every time you call the respective function (analogWrite, servo.write or tone) you are just updating the period/duty cycle and not setting up the peripheral again. The resetting of the peripheral will glitch the output. Since this tone feature is audible, you'll more likely notice the glitch. The global setup state will also allow you to know that a pin is already setup as some other peripheral, and if so you'll need to reinitialize it as the new peripheral.

This 3 interrupt driven tone output is really cool, because it can be used to make a sweet 3 voice synthesizer ;-) Something every IoT device needs of course.

@satishgn
Copy link
Contributor Author

@technobly, infact a total of 4 channels of TIM2 + 4 channels of TIM3 + 2 channels of TIM4 = 10 tones can be produced independently.

@technobly
Copy link
Member

Yes, but only 3 independent periods right? Each timer has a fixed period, but maybe independent duty cycles like the PWM. I noticed this when trying to create separate frequency PWM outputs... it seemed limited to 3. Since tone is frequency based, I would say 3 total at once then.

@satishgn
Copy link
Contributor Author

Not 3 from each independent TIM as the way you thought but each TIM can generate four different frequencies(on 4 channels) when used in Output Compare Toggle Mode(TIM_OCMode_Toggle) with Interrupts. When TIM is configured in PWM mode as done in analogWrite case, then each TIM can generate only 1 fixed frequency with four different duty cycle.

@technobly
Copy link
Member

Hmmm, I see. So what's stopping us from getting 10 totally customizeable PWM outputs then? Fixed 50% duty cycle in Output Compare Toggle Mode?

@satishgn
Copy link
Contributor Author

Correct! Fixed 50% duty cycle in OC Toggle Mode with different frequencies@4 channels per each timer(using TIM_OCMode_Toggle) but I don't think it's possible to have 4 PWM outputs(using TIM_OCMode_PWM1) with different frequencies per each timer.

@towynlin towynlin merged commit 1c2f9f6 into master May 8, 2014
@towynlin towynlin deleted the feature/arduino-tone-notone branch May 8, 2014 19:36
@tiegz
Copy link

tiegz commented May 8, 2014

👏 👏 👏

@wesner0019
Copy link

What pins are able to use the tone function?

@technobly
Copy link
Member

@wesner0019 The pins you can use for tone() / noTone() are: D0, D1, A0, A1, A4, A5, A6, A7, RX, TX

Some of those pins are used for SPI, I2C, and Serial1... so if you are using those features the tone() function won't work on those pins. Now that I'm saying this, I'm wondering if SPI really doesn't apply, since it's used on A2, A3, A4, A5. @satishgn can you confirm? I see SPI is part of the safety checks in the tone() method, maybe it doesn't need to be there? Never mind I see I missed A4 - A7 is an available tone() pin.

@wesner0019
Copy link

Thanks. I am using "tone(7,2100)", but I am not getting a response from it. I am also using I2C. Any idea why D7 is not outputting a tone?

@technobly
Copy link
Member

Hi @wesner0019 can you try using some of the other pins to see if it works at all for you?

Also, have you put this line of code in your setup()?

setup() { 
  pinMode(D7,OUTPUT);
}

@wesner0019
Copy link

Found out that pin 7 is not PMW so it can not be used for a tone function. I am currently using A7 and it is partially working like it is skipping a beat here causing a non smooth tone. The only way I hear a smooth tone is when the core is in the first stages of a new OTA updload. It seems like some other delay or other interrupt is causing the bad sound. Wish I could upload sounds.

@wesner0019
Copy link

Found something out. Once I placed the tone function in the setup the generated tone is smooth.

If I add a delay at the end and place the tone in the loop I hear it stop as the start or every loop. It seems like the the tone is getting reinitialized every time the loop starts causing it to stop for a microsecond or so. Any ideas how to fix this?

void setup() {
pinMode(A7,OUTPUT);
}

void loop() {
tone(A7,600);
delay(250);
}

@technobly
Copy link
Member

@wesner0019 tone is indeed being re-initialized every time you call tone(). The is an issue for the analogWrite() as well, but here it is obviously more noticeable as an audible tone. Basically the fix would be if tone is subsequently called after being initialized, and the new frequency is the same as the old frequency, no change is made. It's also possible to just update the PWM register period and duty cycle again (instead of completely re-init'ing) fast enough that no several millisecond glitch is "heard". This should be a pretty simple change when we get some time to implement it. In the mean time if you would like to take a stab at the change yourself we do welcome Pull Requests! :)

A bandaid fix could be to just add a flag in your code to not call tone() again if you have already done so once, and reset the flag when you want to change the tone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants