Случай RESET и RESUME в коде Arduino mega 2560 (КНОПКА КАК ПРЕРЫВАНИЕ)

Я работаю над Arduino Mega 2560, которая управляет четырьмя шаговыми двигателями с драйвером BT6560, шестью кнопками и четырьмя концевыми выключателями.

Я хочу закодировать Arduino таким образом, чтобы при нажатии кнопки RESET (не говоря уже о кнопке RESET на Arduino) Arduino запускала код заново с самого начала.

И когда я нажимаю кнопку RESUME, Arduino должен запустить код с того момента, как я нажал кнопку RESET (как будто возобновляется воспроизведение любой песни).

Как я могу это сделать?

Ниже приведен код, над которым я работаю:

int dirH_T1 = 3;
int steppin_T1 = 4;
int dirpin_F1 = 5;
int dirH_F1 = 6;
int steppin_F1 = 7;
int dirpin_T2 = 8;
int dirH_T2 = 9;
int steppin_T2 =10;
int dirpin_F2 = 11;
int dirH_F2 = 12;
int steppin_F2 =13;
int PB17ACW=23;
int PB17ACCW=22;
int PB17BCW=25;
int PB17BCCW=24;
int S01 = 34; // ВХОДЫ ДАТЧИКА
int S02 = 35;
int S03 = 36;
int S04 = 37;

void setup()
{
    pinMode(dirpin_T1, OUTPUT);
    pinMode(dirH_T1, OUTPUT);
    pinMode(steppin_T1, OUTPUT);
    pinMode(dirpin_F1, OUTPUT);
    pinMode(dirH_F1 , OUTPUT);
    pinMode(steppin_F1, OUTPUT);

    pinMode(dirpin_T2, OUTPUT);
    pinMode(dirH_T2, OUTPUT);
    pinMode(steppin_T2, OUTPUT);
    pinMode(dirpin_F2, OUTPUT);
    pinMode(dirH_F2 , OUTPUT);
    pinMode(steppin_F2, OUTPUT);

    pinMode(PB17ACW,INPUT_PULLUP);
    pinMode(PB17ACCW,INPUT_PULLUP);
    pinMode(PB17BCW,INPUT_PULLUP);
    pinMode(PB17BCCW,INPUT_PULLUP);

    pinMode(S01,INPUT);
    pinMode(S02,INPUT);
    pinMode(S03,INPUT);
    pinMode(S04,INPUT);

}
void loop()
{
    if(digitalRead(PB17ACW)==LOW &&  digitalRead(PB17ACCW)==LOW) {
// ОСТАНОВИТЬ ДВИГАТЕЛЬ, ЕСЛИ НЕ НАЖАТА НИ ОДНА КЛАВИША
    }

// ДЛЯ ФИЛАМЕНТНОЙ НИТИ 1 ПРЯМОЙ ПОДАЧИ
    if(digitalRead(PB17ACW)==HIGH &&  digitalRead(PB17ACCW)==LOW) {
        digitalWrite(dirpin_T1, LOW);      // Задаем направление.
        digitalWrite(dirH_T1, LOW);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T1, LOW);  // Это изменение с LOW на HIGH создает
            digitalWrite(steppin_T1, HIGH); // "Нарастающий фронт", чтобы easydriver знал, что
            when to step.
            delayMicroseconds(50);
        }

        digitalWrite(dirpin_F1, LOW);      // Задаем направление.
        digitalWrite(dirH_F1, LOW);
        delay(1000);

        do {
            digitalWrite(steppin_F1, LOW);  // Это изменение с LOW на HIGH создает

            digitalWrite(steppin_F1, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);

        } while(digitalRead(S01)==LOW);

        delay(1000);

        digitalWrite(dirpin_T1, LOW);      // Задаем направление.
        digitalWrite(dirH_T1, HIGH);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T1, LOW);  // Это изменение с LOW на HIGH создает
            digitalWrite(steppin_T1, HIGH); // "Нарастающий фронт", чтобы easydriver знал, что
            when to step.
            delayMicroseconds(50);

        }
    }

// ДЛЯ ФИЛАМЕНТНОЙ НИТИ 1 ОБРАТНЫЙ ПОДАЧИК
    if(digitalRead(PB17ACW)==LOW &&  digitalRead(PB17ACCW)==HIGH) {
        digitalWrite(dirpin_T1, LOW);      // Задаем направление.
        digitalWrite(dirH_T1, LOW);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T1, LOW);  // Это изменение с LOW на HIGH создает
            digitalWrite(steppin_T1, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);

        }

        digitalWrite(dirpin_F1, LOW);      // Задаем направление.
        digitalWrite(dirH_F1, HIGH);
        delay(1000);

        do {
            digitalWrite(steppin_F1, LOW);  // Это изменение LOW на HIGH создает
            digitalWrite(steppin_F1, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);
        } while(digitalRead(S02)==LOW);

        delay(1000);
        digitalWrite(dirpin_T1, LOW);      // Задаем направление.
        digitalWrite(dirH_T1, HIGH);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T1, LOW);  // Это изменение с LOW на HIGH создает
            digitalWrite(steppin_T1, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);
        }
    }

    // ДЛЯ ФИЛАМЕНТНОЙ НИТИ 2 ПРЯМОЙ ПОДАЧИ
    if(digitalRead(PB17BCW)==HIGH &&  digitalRead(PB17BCCW)==LOW) {
        digitalWrite(dirpin_T2, LOW);      // Задаем направление.
        digitalWrite(dirH_T2, LOW);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T2, LOW);  // Это изменение LOW на HIGH создает
            digitalWrite(steppin_T2, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);
        }

        digitalWrite(dirpin_F2, LOW);      // Задаем направление.
        digitalWrite(dirH_F2, LOW);
        delay(1000);

        do {
            digitalWrite(steppin_F2, LOW);  // Это изменение с LOW на HIGH создает
            digitalWrite(steppin_F2, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);
        } while(digitalRead(S03)==LOW);

        delay(1000);

        digitalWrite(dirpin_T2, LOW);      // Задаем направление.
        digitalWrite(dirH_T2, HIGH);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T2, LOW);  // Это изменение LOW на HIGH создает
            digitalWrite(steppin_T2, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);

        }
    }

// ДЛЯ ФИЛАМЕНТНОЙ НИТИ 2 ОБРАТНЫЙ ПОДАЧИК
    if(digitalRead(PB17BCW)==LOW &&  digitalRead(PB17BCCW)==HIGH) {
        digitalWrite(dirpin_T2, LOW);      // Задаем направление.
        digitalWrite(dirH_T2, LOW);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T2, LOW);  // Это изменение LOW на HIGH создает
            digitalWrite(steppin_T2, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);
        }

        digitalWrite(dirpin_F2, LOW);      // Задаем направление.
        digitalWrite(dirH_F2, HIGH);
        delay(1000);

        do {
            digitalWrite(steppin_F2, LOW);  // Это изменение с LOW на HIGH создает
            digitalWrite(steppin_F2, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);

        } while(digitalRead(S04)==LOW);

        delay(1000);

        digitalWrite(dirpin_T2, LOW);      // Задаем направление.
        digitalWrite(dirH_T2, HIGH);
        delay(1000);

        for(int i = 0; i<32767; i++) {      // Итерация для 4000 микрошагов.(32767)
            digitalWrite(steppin_T2, LOW);  // Это изменение LOW на HIGH создает
            digitalWrite(steppin_T2, HIGH); // "Нарастающий фронт", чтобы easydriver знал, когда делать шаг.
            delayMicroseconds(50);
        }
    }
}

, 👍1

Обсуждение

Я думаю, вы хотите реализовать свой код как [конечный автомат](https://hackingmajenkoblog.wordpress.com/2016/02/01/the-finite-state-machine/), где «сброс» — это лишь одно из многих состояний, в которых может находиться автомат., @Majenko

да, и в настоящее время я сосредоточен на простой кнопке, но у нее есть проблема с дребезгом, так что если вы можете предложить какой-либо другой переключатель, он сделает все идеально и эффективно., @Sonali_B


1 ответ


2

Чтобы выполнить «спящий» режим в общем виде, вам необходимо:

  1. Захватите соответствующее состояние всей системы (Arduino + модули). Это включает регистры, стек и все переменные в вашей программе.
  2. Запишите его на какой-нибудь носитель информации (EEPROM, SD, что угодно).
  3. При возобновлении восстановите регистры, стек, переменные и повторно инициализируйте все модули (датчики, реле, ...)

Arduino этого сделать не может.

Единственная альтернатива — использовать, как говорит @Majenko, конечный автомат и самостоятельно позаботиться о восстановлении выполнения до точки, в которой была нажата кнопка.

,

На самом деле, Arduino *может* делать все это, и, возможно, гораздо лучше и проще, чем ваш типичный настольный компьютер. Но, вероятно, было бы более реалистично оставить ОЗУ включенной для сохранения содержимого и просто приостановить большую часть часов и динамической логики, обесточить внутренние и внешние периферийные устройства и т. д. На самом деле, многие ноутбуки имеют микроконтроллер, мало чем отличающийся от Arduino, который обрабатывает ключевые части логики спящего режима и питания., @Chris Stratton