Программа дежурного режима для усилителя

Доброго времени суток! Задался написанием программы для авто включения и выключения усилителя при подаче аудио сигнала на вход усилителя. Я новичок, писать толком не умею…) Писал несколько вариантов программы, кое что удалось, но не получается оборвать цикл проверки сигнала на входе, сбросив счетчик в 0, при наличии на входе звука. Прошу помочь в написании программы.
Алгоритм таков:

  1. Подаем питание, при отсутствии сигнала на входе, реле не включаем, до тех пор пока не будет подан сигнал превышающий определенный порог.
  2. Сигнал подан, ждем (к примеру 10 сек) и потом, по истечении 60 проверок. с интервалом в секунду, удостоверяемся, что сигнал есть или нет.
  3. Если есть, то сбрасываем счетчик и так по кругу пока сигнал не исчезнет.
  4. если сигнала нет и счетчик дошел до 60, то отключаем реле и возвращаемся в начало и ждем сигнала.

Скетч:

#define PIN_RELAY 10

#define AUDIO A0

int x=0;

int y=0;

void setup() {

  pinMode(PIN_RELAY, OUTPUT);

  digitalWrite(PIN_RELAY, LOW);

}

void loop() {

int val = analogRead(AUDIO);

if (val>300) {

  digitalWrite(PIN_RELAY, HIGH);

  delay(10000);

  for (int x = 0; x<60; x++) {

    digitalWrite(val, x);

    if (val>300) {

    y=y+1;

    delay(1000);

    } else {

      x=0;

    }

  }

if (y>59 && val>300) {

  digitalWrite(PIN_RELAY, LOW);

  x=0;

  y=0;

} else {

  digitalWrite(PIN_RELAY, HIGH);

  x=0;

  y=0;

}

}

}

не пойму как сбросить счетчик если сигнал есть и начать цикл заново, прошу помочь

А где схема? Ты ее вообще составлял, или подключил сигнал переменного тока к однополярному АЦП и ждешь чудес?

Это что вообще? Вроде, там, по условию, val>300. У Вас на плате 300+ цифровых пинов?

Да, кстати, вставьте код нормально - читать невозможно.

Схема собрана на ОУ и пиннает только постоянный ток не более 5В. Чудес нет… Но скетч не работает как мне требуется. Для облегчения задачи, подаю вручную лог 1 и засекаю время.

Пожалуйста, оформите вставку кода правильно. Используйте кнопку <\> в верхней строчке формы редактирования сообщения.
И лучше вставлять код новым сообщением, а не редактировать старое.

Лучше сделать на миллис() с использованием двух булевых переменных…
приблизительно так (ход мысли) код не проверялся, логические ошибки могут быть


#define PIN_RELAY 10
#define AUDIO A0

uint32_t oldm;
bool is_on;
bool is_off;

void setup() {
  pinMode(PIN_RELAY, OUTPUT);
  digitalWrite(PIN_RELAY, LOW);
}

void loop() {
  int val = analogRead(AUDIO);
  if (val > 300) {
    if (!is_on) {
      oldm = millis();
      is_on = true;
      is_off = false;
    }
    if (is_on && millis() - oldm >= 10000) {
      digitalWrite(PIN_RELAY, HIGH);
    }
  }
  if (val < 300 && is_on && !is_off){
    is_off = true;
    is_on = false;
    oldm = millis();
  }
  if (val < 300 && is_off && millis() - oldm >=60000){
    digitalWrite(PIN_RELAY, LOW);
    is_off = false;
  }
}

Если это ответ на мой вопрос (привыкайте цитировать на что отвечаете), то я Вас ещё раз спрашиваю, что означает Ваше строка:

digitalWrite(val, x);

Вы можете просто самому себе ответить, что именно делает эта строка?

Это означает что если считывается сигнал со входа более 300, ( у ардуино 10 бит разрядность на аналоговых входах, значит 5В/1024=0,00488В, 300*0,00488=1,464В - порог срабатывания в условии по входному сигналу) то в цикл добавляется 1 шаг, полсе 60 шагов он должен завершиться, или при подачи сигнала более 1,464 - обнулиться и начать заново отсчитывать

большое спасибо, сейчас ознакомлюсь и просмотрю

Вы читаете вход как цифровой и можете получить в ответ только ноль и единицу. какие 10 бит разрядность?

Вы никак не можете услышать вопроса. Конкретно, что делает эта строка? Эта, а не весь код! Что вообще делает digitalWrite?

Вы спрашиваете, что не так с кодом, я Вас пытаюсь навести на мысль, что в этой строке написан бред сивой кобылы. Но, чтобы это понять, попробуйте всё-таки просто ответить на вопрос что делает именно эта строка. В ней нет никаких “если”, а потому не используйте этого слова.

2 лайка

В том и дело что это бред, спасибо за помощь в наталкивании к истине, но вчера открыв ардуино и пытаясь написать код, да, конечно, мне не понять свой же бред, собирая информацию в виде отдельных примеров и кусочков никак не пересекающихся с моей темой. Подобного скетча в инете нет, может хоть кому то пригодится, если все же, с Вашей помощью и других людей ее получится решить.
Вопрос слышен, мне не ясно как записать полученное значение в один шаг и прибавить его в цикле или же обнулить. Услышьте меня пожалуйста изначально, мне нужна помощь, а не “стоя у доски” выслушивать наставления как в “первом классе”. Для Вас это проще простого, для меня попытка реализовать идею.

int val = analogRead(AUDIO);
if (val > 300)

читаю как аналоговый

А я, простите, что делаю? Я показываю Вам на ошибку и задаю наводящий вопрос “что вообще делает digitalWrite?”. Надеюсь, что Вы уже прочитали её описание и теперь знаете что она делает, и почему то, что у Вас написано - бред.
В моём понимании, это и есть помощь - помочь Вам узнать что-то и разобраться в чём-то. Если Вы под помощью понимаете что-то другое, так напишите что Вам нужно - сделать за Вас? Просто пожелать удачи? Или что?

1 лайк

Да, понимаю, что здесь что-то не так. Понимание функции есть, в этом месте переписывал код несколько раз… как разберусь до конца отпишусь о результатах. спасибо.

digitalWrite(val, x);
убрал это…
Для меня не понятно как обнулить счетчик в начальное состояние по появлению сигнала. Можете помочь?

А что именно в вашем коде является счетчиком?
Чтобы не листать, вот ваш код:

#define PIN_RELAY 10
#define AUDIO A0

int x = 0;
int y = 0;

void setup() {
  pinMode(PIN_RELAY, OUTPUT);
  digitalWrite(PIN_RELAY, LOW);
}

void loop() {
  int val = analogRead(AUDIO);
  if (val > 300) {
    digitalWrite(PIN_RELAY, HIGH);
    delay(10000);
    for (int x = 0; x < 60; x++) {
      digitalWrite(val, x);
      if (val > 300) {
        y = y + 1;
        delay(1000);
      } else {
        x = 0;
      }
    }
    if (y > 59 && val > 300) {
      digitalWrite(PIN_RELAY, LOW);
      x = 0;
      y = 0;
    } else {
      digitalWrite(PIN_RELAY, HIGH);
      x = 0;
      y = 0;
    }
  }
}

Сразу хочется спросить:

  1. Зачем убрали?
  2. А зачем добавляли?
  3. На вопрос Евгения Петровича так и не ответили?

Здесь хотел сбросить “x” если хотя бы один раз появится сигнал

DM86, почему вы так делаете? Или по другому - ЗАЧЕМ вы так делаете?
Ведь что я, что Евгений Петрович задаем конкретные вопросы, а вы отвечаете на какие-то свои (причем даже не озвучив их)! Перестаньте, пожалуйста!