Вопрос по прерыванию и сбросу кода на начало

Добрый день. Подскажите, пожалуйста. У меня есть определенная задача:
“Работа с прерываниями. Подключить пьезо-пищалку и кнопку к ардуино. Запрограммировать играть музыку на пьезо-пищалке. По нажатию кнопки музыка должна прерываться и начинаться заново.”
Я вроде как выполнил всё, но мне ещё необходимо сделать сброс кода на начало. Пытался меткой, но её нужно использовать в одном “Loop”, также пытался сделать и через:

void(* resetFunc) (void) = 0;  //объявляем функцию reset с адресом 0
resetFunc();  //вызываем reset 

Но всё равно не работает. Подскажите, как можно решить данную проблему. Исходный код прикрепляю к теме:

volatile int buttonState = 0;
void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), blink, CHANGE);
}

bool flag = false;
uint32_t btnTimer = 0;
void loop()
{
  
  bool btnState = !digitalRead(2);

  if (btnState && !flag && millis() - btnTimer > 200) {
    flag = true;
    btnTimer = millis();
  }
  if (!btnState && flag && millis() - btnTimer > 200) {
    flag = false;
    btnTimer = millis();
  }
  digitalWrite(13, buttonState);
  
}

void blink()
{
 buttonState = !buttonState;
}

Я новичок и выполняю подобные задания на эмуляторе от Tinkercad. Застрял на данном задании.

Где же тут музыка на пьезопищалке?

1 лайк

Я использую стандарт звук, который идет при включении пьезопищалке. Мне не нужна музыка. Меня интересует, как выполнить сброс кода на начало.

где она вызывается в коде?

тебе же надо не на начало, а на начало музыки, а это разные вещи

1 лайк

Я убрал данный способ решения. Т.к. он не работает.
Данную строчку я прописывал до setup

void(* resetFunc) (void) = 0;  //объявляем функцию reset с адресом 0

Указывал в blink

resetFunc();  //вызываем reset

Если честно не знаю. Мой преподаватель говорит, что мне необходимо сделать сброс на 0 строку, хотя это не логично, и я это сам понимаю. В любом случае, сброс у меня не выполняется, к сожалению.

не знаю…
это работает

int led = 13;

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void(* resetFunc) (void) = 0;

void loop() {

  digitalWrite(led, HIGH); // включаем светодиод
  Serial.println("on");
  delay(1000); // ждем секунду

  digitalWrite(led, LOW); // отключаем светодиод, подавая команду LOW
  Serial.println("off");
  delay(1000); // ждем одну секунду

  Serial.println("resetting");
  delay(100);

  resetFunc(); //вызываем reset

  Serial.println("never happens");

}
1 лайк

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

Я использую такое подключение:

ты уверен что у тебя кнопка правильно подключена?

А почему нет?
По нажатию происходит прерывание. Вроде как она работает и выполняет свою функцию, которая прописана в коде.

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

Это что? Вы понимаете, что говорите? Если понимаете, то объясните, что это такое. А если не понимаете, то не говорите.

Если бы Вы что-то понимали, этой темы бы не было. так что, давайте, выкладывайте свой полный код, а не надейтесь, что его кто-то за Вас напишет.

Я не просил за меня писать код. Я попросил подсказать. Пятым сообщением указал куда прописывал функцию reset с адресом 0.

volatile int buttonState = 0;
void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), blink, CHANGE);
}

bool flag = false;
uint32_t btnTimer = 0;
void(* resetFunc) (void) = 0; 
void loop()
{
  
  bool btnState = !digitalRead(2);

  if (btnState && !flag && millis() - btnTimer > 200) {
    flag = true;
    btnTimer = millis();
  }
  if (!btnState && flag && millis() - btnTimer > 200) {
    flag = false;
    btnTimer = millis();
  }
  digitalWrite(13, buttonState);
  
}

void blink()
{
 buttonState = !buttonState;
  resetFunc();
}

Простите, Вы здоровы?

Вас никто не просил “указывать”, Вас просили привести код, как он есть. Вы разницу понимаете?

Не вызывайте resetFunc() в обработчике прерывания.

1 лайк

Видно не особо здоров.

А как тогда его указать?
У меня Arduino идёт как модуль по одному из предметов. К сожалению, приходится быдлокодить и пытаться на ходу находить решение. Преподаватель указывал мне на то, что мне необходимо прописать сброс на начало именно в обработчике прерывания.

А просто goto *0; не работает?
В прерывании не проверял, в обычном коде работает

1 лайк

Вместе с прерыванием нет.

Проверил, в отладчике Atmel Studio 7 в прерывании таймера работает, переходит на 0 адрес.

1 лайк