-
-
Notifications
You must be signed in to change notification settings - Fork 19.3k
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
New feature: Non blocking tone queue #3962
New feature: Non blocking tone queue #3962
Conversation
@@ -60,19 +60,34 @@ | |||
#define PS_ON_PIN 81 // External Power Supply | |||
|
|||
#if ENABLED(BQ_LCD_SMART_CONTROLLER) // Most similar to REPRAP_DISCOUNT_SMART_CONTROLLER |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking this block should just move to pins_RAMPS_14.h
with the rest of the LCD controller pins. Then we don't need the #undef
lines, and this controller will be usable on regular RAMPS setups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will submit a specific PR for this one.
It all seems like it should work, but are you saying that if the buffer is too small, then it will play multiple tones incorrectly? For example, with a 4-tone buffer size, I can only play 4 tones before adding new tones will overwrite tones that haven't been played yet? If so, perhaps it makes sense to actually block inside the I posted a few comments on the code. If you could make a few tweaks then it can be merged. (Don't worry about making the classes We should probably add |
No override, the tones get ignored if queue is full, but of course as soon as one slot on the buffer queue gets free you may inject more tones to the tail. |
@jbrazio Well that's no good. GCode files are distributed that contain nothing but music. This change would break the ability to play those files. If the queue simply blocks, then it would be just like the old behavior, basically, since |
@thinkyhead Maybe I did not understand your second part of the comment.. but it is non-blocking as tones not fitting the queue are "just" discarded, Marlin will not stop anything when the ring buffer is full. I can improve this since
Will do. |
We cannot use What I would like is for nothing to ever be discarded, so that |
Something like this ? void tone(uint16_t const &duration, uint16_t const &frequency = 0) {
while(!this->buffer.enqueue((tone_t) { duration, frequency })) delay(10);
} |
@jbrazio |
That won't work, because the buffer won't be getting processed. (Unless it's being processed in an ISR.) [edit] Right. What @Blue-Marlin said… |
Or I could call |
I think this may be better: while (this->buffer.isFull()) { this->tick(); delay(10); }
this->buffer.enqueue((tone_t) { duration, frequency }); |
Right. It would be more useful to do idles, but we are in danger to get a memory overflow when the next commands are all consecutive M300's. On the other side we really want to update the heaters. (G2/G3 problem) |
c28d0e1
to
0db8fe7
Compare
Note to self: Never use macros with Pronterface, they're buggy as hell. |
As long as there are no excessively long beeps (several seconds) then it should be ok. |
@Blue-Marlin @thinkyhead we're limiting the max beep to 5S ( |
5 seconds? Good luck with the watchdog. |
* @param frequency Frequency of the tone in hertz | ||
*/ | ||
void tone(uint16_t const &duration, uint16_t const &frequency = 0) { | ||
while (buffer.isFull()) this->tick(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please call thermalManager.manage_heater();
here.
What's wrong with the watchdog, this is a non-blocking |
Unblocking until the buffer is full and you are blocking here for up to 5 seconds. The Watchdog will give its alarm after 4. |
@jbrazio In case it's not obvious, calling this keeps the watchdog alive also. So perhaps when the queue is full, call |
Inline comments on the BEEPER_PINT was causing the compiler to barf: pins_RAMPS_14.h:221: error: pasting "/* Beeper on AUX-4*/" and "_RPORT" does not give a valid preprocessing token
e433ef8
to
63f10eb
Compare
@thinkyhead ready to merge. |
This PR fixes #3913 by rewriting from scratch the existing
buzzer.cpp
to be non-blocking, introducing a tone queue. The length of the tone queue is set atbuzzer.h
with a default of#define TONE_QUEUE_LENGTH 8
, I haven't added it to any of theConfiguration.h
files because I don't believe it will require to be changed for standard Marlin operation, in fact we could even lower the default to4
.Of course if you want to play the Imperial March
I advise you touse the following G-Code as a macro on#define TONE_QUEUE_LENGTH 35
andPronterface(edit: macros are buggy, use Repetier Host instead). You will require aSPEAKER
and not aBUZZER
.The timing is a bit "wavy" due to the low priority and non periodic call to
tick()
, this is specially noticeable on the higher pitch notes which have a smaller period thus require more precise timing.There is a "untouched" feature of the old
buzzer.cpp
which isLCD_USE_I2C_BUZZER
, I don't have hardware to test it and from my research thebuzzer()
is delegated into theLCD
object defined byLiquidCrystal_I2C.h
-- Please comment bellow if you have more information about this topic.