ARDUINO Звуковое оповещение об ошибках

Rofl92

✩✩✩✩✩✩✩
3 Авг 2021
3
0
Здравствуйте.
Есть бесконечный цикл такого плана:

Основной цикл:
void loop() {
    drawInterface();
    readErrors();
    readParameters();
}
Есть необходимость сделать звуковое оповещение об ошибках.
Звуковые оповещения могут быть разными. Они имеют три параметра:
1. Количество сигналов в порции сигналов
2. Длина сигнала (паузы)
3. Интервал между порциями сигнала
Например: 0.7 сек(2) - 3 сигнала(1), интервал 10 сек(3). Это значит, что каждые 10 сек воспроизводятся три сигнала длиной 0.7 сек и паузой в 0.7 сек, пока не исчезнет ошибка.

Мне пока приходит только такая реализация описанная у Гивера в разделе алгоритмы

C++:
int alarmCounter = 0;
uint32_t alarmTimer = 0;   
uint32_t alarmToneTimer = 0; 
#define ALARM_PERIOD 10000 
#define ALARM_TONE_PERIOD 700
#define ALARM_COUNT 3 
#define TONE_PIN 8

void loop() {
    if (millis() - alarmTimer >= ALARM_PERIOD) {
        if (millis() - alarmToneTimer >= ALARM_TONE_PERIOD) {
            alarmToneTimer = millis();
            digitalToggle(TONE_PIN);
            alarmCounter++;
        } 
        if (alarmCounter == ALARM_COUNT*2)
        {
            alarmCounter = 0; 
            alarmTimer = millis();
        }
    }
}
Проблема в том, что оповещения могут быть разные с разными параметрами и заводить 3 переменных и определять три дефайна для каждого типа оповещений мне не кажется удобным. К тому же для каждого типа оповещений должен быть подобный обработчик в коде.
Быть может есть более лаконичный и удобный способ реализовать данную задумку?
 

bort707

★★★★★★✩
21 Сен 2020
3,061
912
Проблема в том, что оповещения могут быть разные с разными параметрами и заводить 3 переменных и определять три дефайна для каждого типа оповещений мне не кажется удобным.
Если три оповещения должны иметь каждое свои параметры - без трех комплектов переменных никак не обойтись. А код может быть общим.

Если этот вариант "не кажется удобным" - придумайте свое.Правда, судя по вашему вопросу, мне кажется. что вы и такого бы сами не написали. не будь этого примера.
 

poty

★★★★★★✩
19 Фев 2020
3,229
940
А чем tone не устраивает? Работает по прерыванию, интуитивно понятен.
Приведённый код будет работать только если задержки в остальной части кода будут небольшие и прогнозируемые.
Для оптимизации кода сделайте класс, в который поместите таблицу кодов и вызывайте метод "озвучка" только с номером ошибки. В этом случае вообще можно сделать озвучку нескольких кодов, случившихся одновременно. Тут пригодятся советы @Старик Похабыч , по "кодировке" последовательностей.
 
Изменено:
  • Лойс +1
Реакции: Rofl92

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Я когда то делал нечто подобно, но световой индикацией. Было несколько типов мигания. Быстрое или короткое. Длинное, а так же плавное включение и выключение (не помню по отдельности или нет). 1 тип - одна функция. Так вот когда мне надо было сделать 3 коротких вспышки, 3 длинных , 3 коротких (для примера) я 9 раз вызывал нужные функции, что то типа :
C++:
S_Blink();
S_Blink();
S_Blink();
L_Blink();
L_Blink();
L_Blink();
S_Blink();
S_Blink();
S_Blink();
Можно сделать циклы, можно сделать функцию, которая по битовой маске будет выдавать нужное.
 
  • Лойс +1
Реакции: Rofl92

Rofl92

✩✩✩✩✩✩✩
3 Авг 2021
3
0
@Старик Похабыч, правильно я понимаю? В реализации S_Blink() и L_Blink() происходил весь процесс включения и отключения светодиода и занимало какое-то время?

@poty, tone() в целом меня устраивает, но тут в любом случае придётся отсчитывать время, пока молчит динамик выше описанным способом. За предложение по оптимизации спасибо)

@bort707, вам кажется.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Да, мне там не надо было заморачиваться с многозадачностью, все мигания были в начальном коде и показывали либо какие то ошибки, либо нормальное включение. А делее был долгий цикл измерения температуры , в котором тоже могло быть (если задано) короткое мигание.
Но переделать на Многозадачность тоже можно и не сложно.
 
  • Лойс +1
Реакции: Rofl92

poty

★★★★★★✩
19 Фев 2020
3,229
940

@Rofl92, всё верно, только Вы не учитываете, что для того, чтобы сделать звук с частотой, допустим, 1кГц, нужно попадать в ветку с toggle 2000 раз в секунду. Во-первых, этого уже не сделать с millis, нужно переходить на micros. Во вторых, любая задержка в коде - и тон поплывет. В-третьих, такая частая проверка оставляет значительно меньше времени на остальные действия.
В принципе, то, о чём суть Вашего вопроса, делается с помощью процедур (функций), но если Вас раздражает множество define в основном коде, то можно сделать ещё один шаг вперёд и спрятать всё в класс.
 

Rofl92

✩✩✩✩✩✩✩
3 Авг 2021
3
0
@poty, извиняюсь, я не уточнил, что используется активная пищалка, пищит при подаче 12в.
В целом я уже получил удовлетворяющий меня ответ. Оберну все в класс, с кодами ошибок.
Всем спасибо.