Closed melkati closed 7 months ago
@Coscolin
To make the buzzer code non-blocking and eliminate delays, you can utilize the millis()
function for timing and avoid using delay()
. Below is the modified code:
uint64_t buzzerStartTime = 0;
uint64_t buzzerStopTime = 0;
void buzzerRedRange() {
Serial.println("[BUZZ] Buzzer RED range");
tone(BUZZER_PIN, toneBuzzerBeep + co2, durationBuzzerBeep);
buzzerStopTime = millis() + durationBuzzerBeep * 1.3;
}
void buzzerOrangeRange() {
Serial.println("[BUZZ] Buzzer ORANGE range");
tone(BUZZER_PIN, toneBuzzerBeep + co2, durationBuzzerBeep);
buzzerStopTime = millis() + durationBuzzerBeep * 1.3;
}
void buzzerLoop() {
if (!activeBuzzer)
return;
if (inMenu) { // Inside Menu stop BEEPING
noTone(BUZZER_PIN);
return;
}
if ((millis() - lastTimeBuzzerBeep >= timeBetweenBuzzerBeep * 1000) || (lastTimeBuzzerBeep == 0)) {
lastTimeBuzzerBeep = millis();
if (co2 > co2RedRange) {
if (belowRedRange || repeatBuzzer) {
wakeUpDisplay();
buzz.once(0, buzzerRedRange);
belowRedRange = false;
}
return;
} else if (co2 < (co2RedRange - BUZZER_HYSTERESIS)) {
belowRedRange = true;
noTone(BUZZER_PIN); // Stop buzzing when below the range
}
if (co2 > co2OrangeRange) {
if (belowOrangeRange || repeatBuzzer) {
wakeUpDisplay();
buzz.once(0, buzzerOrangeRange);
belowOrangeRange = false;
}
return;
} else if (co2 < (co2OrangeRange - BUZZER_HYSTERESIS)) {
belowOrangeRange = true;
noTone(BUZZER_PIN); // Stop buzzing when below the range
}
}
// Stop buzzing after the specified duration
if (millis() >= buzzerStopTime) {
noTone(BUZZER_PIN);
}
}
In this modified code:
This approach allows the main loop to continue executing while the buzzer functions play without introducing delays.
This is untested code but I think you can get the idea to complete it.
Please, test this (as I don't have a buzzer connected) and if it's working fine, we can change the code.
@Coscolin,
I think there is something missing related to the buzzer PIN initialization.
When the buzzer sounds for the first time (just in the first loop) there is an error:
09:46:07.083 > [BUZZ] Buzzer RED range
09:46:07.084 > E (73634) ledc: ledc_get_duty(740): LEDC is not initialized
Later the error disappears:
09:47:01.830 > -->[SENS] CO2: 1748 CO2humi: 58.83 CO2temp: 22.63 H: 0.00 T: 0.00
09:47:07.107 > [BUZZ] Buzzer RED range
09:47:11.871 > -->[SENS] CO2: 1748 CO2humi: 59.09 CO2temp: 22.54 H: 0.00 T: 0.00
This is with the actual code in feature-buzzer branch.
@Coscolin
What buzzer type is it intended to use? I want to include it in the documentation and also for my own use so I can do some testing.
I have used a passive buzzer that I reused from an old CO2 meter. I have order in AliExpress this one for complete my others CO2Gadget:
2,02€ | Zumbador pasivo de uso común para Arduino, minizumbadores piezoeléctricos de 10 piezas, CA de 12MM x 8,5 MM, resistencia de 12085 42R, 3V, 5V, 9V, 12V https://a.aliexpress.com/_EIv4KoN
That kind of buzzer can have a power consumption higher than the maximum current an ESP32 can supply on one pin.
I just tested one and at 3.3V it consumes up to 74mA.
Better to use a buzzer module with a driver transistor, as this one:
https://s.click.aliexpress.com/e/_DFCiiLT
Also, this permits the buzzer to be powered by Vin (USB or LiPo power) to power the buzzer without loading the onboard 3.3V LDO.
The ESP32 datasheet is a little cryptic about that but the maximum current on one pin in ESP32 is 40mA and the datasheet states that as more pins are supplying current it can go down to 10mA. CO2 Gadget uses more than one pin with current consumption (LEDs for example) so is better to be safe than sorry.
If anyway you need to use that kind of buzzer, without a driving transistor, at least connect a current limiting resistor in series (probably 220 to 470Ohm, better to test and measure).
@melkati you can remove " Remove references to beep on orange" from "Code to drive the buzzer" in task list.
Can we tick task "Include board specific data in platformio.ini" as done or is there anything left to include?
The only lines added to platformio.ini are this ones: -DBUZZER_PIN=13 ; ESP32 pin GPIO13 connected to piezo buzzer -DBUZZER_HYSTERESIS=50 ; Hysteresis PPM to avoid BUZZER ON and OFF continuously if repeat is once -DSUPPORT_BUZZER ;
I think it's not necessary to include any more. Even SUPPORT_BUZZER is not used at all.
We must move the buzzer GPIO to another PIN, as GPIO is reserved (preferably) for serial sensors as is this table:
Board model | TX | RX | Notes |
---|---|---|---|
ESP32GENERIC | 1 | 3 | ESP32 Pio defaults |
TTGOT7 / ESP32DEVKIT / D1MINI / NODEFINED | 16 | 17 | CanAirIO devices ** |
TTGO_TDISPLAY | 12 | 13 | |
M5COREINK | 14 | 13 | |
TTGO TQ | 18 | 13 | |
HELTEC | 18 | 17 | |
WEMOSOLED | 15 | 13 | |
ESP32PICOD4 | 3 | 1 |
No problem for me. Choose the one you prefer or think is best. I put pin 13 because I saw it was available in both T-Display and S3 and it was not used by any part of the actual code.
No problem for me. Choose the one you prefer or think is best. I put pin 13 because I saw it was available in both T-Display and S3 and it was not used by any part of the actual code.
It's used by CO2 Gadget in TTGO T-Display to connect the serial sensors (as Senseair S8 LP, MH-Z19, etc): https://emariete.com/en/co2-meter-gadget/#Pines_utilizados_por_CO2_Gadget_GPIO
As we have more precompiled versions (the precompiled flavours) we will have to think of a well thought table of used GPIOs. It will be better if we can use the same pins on most of the boards (if possible). It's not an easy task with so many moving gears!
I have tried to add the GPIO used to the menu (for user notice), but I have not succeeded.
#define BUZZER_MENU_TITLE "Buzzer: (GPIO" BUZZER_PIN ")" // TO-DO: Add buzzer pin to menu
MENU(buzzerConfigMenu, BUZZER_MENU_TITLE, doNothing, noEvent, wrapStyle
,SUBMENU(timeBetweenBuzzerBeepMenu)
,SUBMENU(toneBuzzerBeepMenu)
,SUBMENU(durationBuzzerBeepMenu)
,EXIT("<Back"));
#endif
I already moved BUZZER_PIN to GPIO 02
I will leave:
_To finish and before publishing into the release, unify it with the led, relays, Neopixels, and other "Outputs" stuff, in order to remove the code that is scattered everywhere, and rename it as CO2_GadgetOutputs.h.
For after the release. I don't want to delay it any longer just for this reason (it would take a short time to do it but it involves a lot of testing afterwards)...
So I think it's ready for release...
Thanks @Coscolin is willing to contribute with this feature.
As with most new features, the tasks necessary to implement this are (open to change WIP):