Проблема с работой прерывания и отсутствием отключения шаговика

Снимаю шляпу!)

#include <Wire.h>
#include <iarduino_RTC.h>
#include <Stepper.h>
#define STEPS 2048
Stepper stepper(STEPS, 4, 6, 5, 7);

iarduino_RTC watch(RTC_DS1302, 12, 10, 11);

volatile int TT = 0;
volatile int X = 0;

void setup() 
{
  watch.begin(); 
  pinMode (2 , INPUT_PULLUP);
  attachInterrupt (0 , JOHOHO_ITS_TIME_MASHINE, FALLING);
  pinMode (9 , OUTPUT);
  pinMode (13, OUTPUT);
}




void loop() 
{
   int STT; //INICIALISATION ```````````````````````````````````````````````````````````````````````````````````````
  int NT;
  watch.gettime();
  uint8_t hours24 = watch.hours;
  uint8_t minutes = watch.minutes;
  STT = (60*hours24+minutes);
  NT = (60*hours24+minutes);
  TT = (NT-STT);

    stepper.setSpeed(10);
    stepper.step(2048*4); 
    digitalWrite(9 , HIGH);
delay(2000);
digitalWrite(9 , LOW);


while(TT<11) // SPORT PARTICLE ````````````````````````````````````````````````````````````````````````````````````````
{
watch.gettime();
  uint8_t hours24 = watch.hours;
  uint8_t minutes = watch.minutes;
  NT = (60*hours24+minutes);
  TT = (NT-STT-X);
  delay(1000);
}
    stepper.setSpeed(10);
    stepper.step(2048*4); 
    /*digitalWrite(A2 , LOW);
    digitalWrite(A3 , LOW);
    digitalWrite(A4 , LOW);
    digitalWrite(A5 , LOW);*/
digitalWrite(9 , HIGH);
delay(2000);
digitalWrite(9 , LOW);

while(TT<32) // SCIENCE PARTICLE ```````````````````````````````````````````````````````````````````````````````````````
{
watch.gettime();
  uint8_t hours24 = watch.hours;
  uint8_t minutes = watch.minutes;
  NT = (60*hours24+minutes);
  TT = (NT-STT-X);
  delay (1000);
}
    stepper.setSpeed(10);
    stepper.step(2048*4); 
digitalWrite(9 , HIGH);
delay(2000);
digitalWrite(9 , LOW);
delay(2000);
digitalWrite(9 , HIGH);
delay(2000);
digitalWrite(9 , LOW);
while(TT<38) // REMEMBER SCIENCE PARTICLE ```````````````````````````````````````````````````````````````````````````````
{
watch.gettime();
  uint8_t hours24 = watch.hours;
  uint8_t minutes = watch.minutes;
  NT = (60*hours24+minutes);
  TT = (NT-STT-X);
  delay (1000);
}
    stepper.setSpeed(10);
    stepper.step(2048*4); 
digitalWrite(9 , HIGH);
delay(1000);
digitalWrite(9 , LOW);
delay(1000);
digitalWrite(9 , HIGH);
delay(1000);
digitalWrite(9 , LOW);

while(TT<69) // RECREATION PARTICLE ``````````````````````````````````````````````````````````````````````````````````````
{
watch.gettime();
  uint8_t hours24 = watch.hours;
  uint8_t minutes = watch.minutes;
  NT = (60*hours24+minutes);
  TT = (NT-STT-X);
  delay (1000);
}
    stepper.setSpeed(10);
    stepper.step(2048*4); 
digitalWrite(9 , HIGH);
delay(1000);
digitalWrite(9 , LOW);
delay(1000);
digitalWrite(9 , HIGH);
delay(3000);
digitalWrite(9 , LOW);

while(TT<79) // FINISH PARTICLE ```````````````````````````````````````````````````````````````````````````````````````````
{
watch.gettime();
  uint8_t hours24 = watch.hours;
  uint8_t minutes = watch.minutes;
  NT = (60*hours24+minutes);
  TT = (NT-STT-X);
  delay (1000);
}
    stepper.setSpeed(10);
    stepper.step(2048*4); 
digitalWrite(9 , HIGH);
delay(500);
digitalWrite(9 , LOW);
delay(500);
digitalWrite(9 , HIGH);
delay(500);
digitalWrite(9 , LOW);
delay(500);
digitalWrite(9 , HIGH);
delay(500);
digitalWrite(9 , LOW);
delay(500);
digitalWrite(9 , HIGH);
delay(500);
digitalWrite(9 , LOW);
}

int JOHOHO_ITS_TIME_MASHINE () //INTERRUPTION ```````````````````````````````````````````````````````````````````````````````````````````
{
  switch (TT)
  {
    case 0 ... 10: digitalWrite(13 , HIGH); digitalWrite(13 , LOW); X = TT; TT = 0; break;
    /*case 11 ... 31: TT = 11; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 11+X; delay (2000); break;  
    case 32 ... 38: TT = 32; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 32+X; delay (2000); break;
    case 39 ... 68: TT = 39; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 39+X; delay (2000); break;
    case 69 ... 79: TT = 69; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 69+X; delay (2000);  break;*/
  }
}

Посмотрите в сторону алгоритмов с неблокирующими (параллельными) задачами. Например, посмотреть как бывает можно тут

Хм, выглядит перспективно, посмотрю!

На этот раз удалось вставить без емок
Будем считать что случился пролаг сайта :smiling_face_with_tear:

Видимо, не того года, который вы нам тут выложили. Попробуйте взять код из своего сообщения и скомпилировать.

Просто, посмотрите на свой код из сообщения. Вы видите там комментарий? Видимо, видите. Но, его там нет.

1 лайк

Да, это был мой косяк, я перизалил код четырьмя сообщениями выше
Благодарю за помощь

Судя по всему сайт заглючило когда загружал пост
После этого ни у меня ни у других эти эмки не возникали

@AsmodeusCure, судя по Вашей реакции, Вы пренебрегли советом @Мишутк избавиться от прерываний. А между тем он прав: Ваша задача не требует аппаратных прерываний. Здесь это явно лишняя сущность. Перепишите код без них - будет намного проще. И, самое главное, - правильнее.

1 лайк

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

Браво, я пока не до конца понимаю как, но тебе удалось решить проблему с неотключающимся движком!

Правда, проблему с неработающим Х (поправки через аттач интеррапт) всё равно не работают


(тестил зажимая нулевой контакт через 5 минут после старта работы, к сожалению он по-прежнему срабатывает через 11…)

Тогда тем более не следует использовать их не по назначению. Прерывания - ограниченный ресурс.

Возможно это будет дилетнтский взгляд, но я собираюсь сделать их своего рода будильником для основной программы
То есть есть источники сигнала - приёмники от других роботов, клавиатуры, датчиков звука, датчиков расстояния каждый из них одновременно подаёт сигнал на интеррапт и поднимает флаг
Основной код просыпается, действует исходя из новых реалий, подстраивая под них основной код и снова уходит в бесконечный цикл до следующего прерывания

Насколько оптимален будет такой вариант?

это не я, это ЫЫ решил проблему! вот может будет полезно
NT - текущее время в минутах (hours60 + minutes)
STT - начальное время при старте цикла
X - коррекция
Проблема возникает когда:
X становится слишком большим (больше, чем NT - STT)
При переполнении суток (если цикл переходит через полночь)
Пример:
Начало цикла в 10:00 (STT = 10
60 = 600)
Текущее время 10:30 (NT = 630)
Без коррекции: TT = 630 - 600 - 0 = 30 мин
Но если было несколько прерываний и X = 40:
TT = 630 - 600 - 40 = -10 → отрицательное значение!


//Ограничение X:
void JOHOHO_ITS_TIME_MASHINE() {
// ... существующий код ... 
// После изменения X добавить проверку
if (X > 78) X = 78; // Максимальная коррекция - длина цикла
}

//    Защита в расчёте TT:
TT = max(0, NT - STT - X); // Не даём TT стать отрицательным
//переход через полночь:
int calculateTT(int current, int start, int correction) {
int diff = current - start;
if (diff < 0) diff += 1440; // Добавляем 24 часа в минутах
return max(0, diff - correction);
}

// Использование:
TT = calculateTT(NT, STT, X);
//исправленный обработчик прерывания
void JOHOHO_ITS_TIME_MASHINE() {
digitalWrite(13, HIGH);
delay(300);
digitalWrite(13, LOW);
// Коррекция времени с защитой от переполнения
if (TT >= 0 && TT <= 10) {
X = min(TT, 78); // Не больше длины цикла
TT = 0;
} 
else if (TT <= 31) {
X = min(X + (TT - 11), 78);
TT = 11;
}
else if (TT <= 38) {
X = min(X + (TT - 32), 78);
TT = 32;
}
else if (TT <= 68) {
X = min(X + (TT - 39), 78);
TT = 39;
}
else if (TT <= 79) {
X = min(X + (TT - 69), 78);
TT = 69;
} delay(2000);
}

Знаю, но от этого предохраняют 2 вещи

  1. Использование интеррапта происходит когда пользователь не успевает начать событие вовремя, после чего он проводит прерывание и немедленно приступает к выполнению события
    Иными словами прерывание может быть вызвано только 1 раз за событие и оно всегда будет меньше чем время затраченное на это событие, а значит мы не провалимся ниже нуля
    Это же кстати защищает от дребезга контактов - поспольку ТТ обнуляется он не может быть повторно вычтен

  2. Даже если мы уйдём в отрицательные ТТ, то мы продолжим подпадать под цикл где ТТ < 11 и код не сломается

Кажется так?

не знаю как остальные, но дальнейшие ответы с меня только если вы в другой стране, и после того как меня усыновите!))))

1 лайк
int JOHOHO_ITS_TIME_MASHINE () //INTERRUPTION ```````````````````````````````````````````````````````````````````````````````````````````
{
  switch (TT)
  {
    case 0 ... 10: digitalWrite(13 , HIGH); digitalWrite(13 , LOW); X = X - TT; TT = 0; break;
    /*case 11 ... 31: TT = 11; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 11+X; delay (2000); break;  
    case 32 ... 38: TT = 32; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 32+X; delay (2000); break;
    case 39 ... 68: TT = 39; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 39+X; delay (2000); break;
    case 69 ... 79: TT = 69; digitalWrite(13 , HIGH); delay(300); digitalWrite(13 , LOW); X = TT - 69+X; delay (2000);  break;*/
  }
}

Ааххахаха
Лан, всё равно спасибо за помощь)
Благодаря тебе я по крайней мере имею 50% проблем, причём тех, которые можно решить если отказаться от идеи с интерраптом

Интерап надо пользовать пральна, просто выставляете в нем флаг, что он произошел, а в основной программе обрабатывает его и скидываете его.

Без него в вашем коде с наличием немеренных кол-ва длинных делай, пропустить нажатие кнопки, как сдрасте)

2 лайка