Выполнение части скетча

Добрый день, запутался, не хватает тяму) прошу помочь. Есть два вращающихся вала, которые из за разных масс (инерций) вращаются с небольшой разницей в угловых скоростях. Между собой валы соединены блокиратором с двумя ступенями свободы:
Сигнала нет - полностью распущены
Сигнал есть - полностью соединены.
Блокиратор при поступлении сигнала на блокирование вначале блокирует валы на 10% (в скетче скважность ШИМ равна 25) в течении 1.5 секунды. В это время образно говоря проходит плавное уравновешивание угловых скоростей между собой. Далее, через 1.5 сек, после уравновешивания блокиратор плавно дожимает блокировку до 100%.

Проблема в том, что не хватает ума как сделать, чтоб когда блокиратор схлопнется на 100% при неизменном сигнале на блокирование не выполнялась та часть где идет уравновешивание валов. Вроде задача не сложная, но неделю уже ощущаю себя тупым)

#define PWR 10           // Вывод ШИМ
#define BLOCK 2          // Вход сигнала блокиратора
#define TIME 1500        // Время уравновешивания угловых скоростей, мс
uint32_t blockTime = 0;  // Таймер блокиратора
bool blockState = false; // Состояние блокиратора
bool pwrState = false;   // Состояние ШИМ
bool blockFlag = false;  // флаг блокиратора
bool Corrent = false;
bool Last = true;

void setup()
{
  pinMode(PWR, OUTPUT);  // ШИМ выход
  pinMode(BLOCK, INPUT); // Вход сигнала на блокиратор
}

void loop()
{
  blockState = digitalRead(BLOCK); // Читаем вход блокиратора, блок принимаем = 1
  if (blockState && !blockFlag)    // если блок = 1, флаг = 0
  {
    blockFlag = true;     // флаг = 1
    analogWrite(PWR, 25); // ШИМ 25
    blockTime = millis(); // Обновляем таймер сигнала блокиратора
  }
  if (blockState && blockFlag && millis() - blockTime >= TIME) // если блок = 1, флак = 1, время <= времени требуемого для уравновешивания валов
  {
    for (int i = 25; i <= 255; i++) // задаем параметры min max скважности ШИМ
    {
      analogWrite(PWR, i); // изменение скважности ШИМ на выходе
// задержка, изменить на варианты в зависимости от инерции клапана блокиратора: 1 вар - Плавное изменение плюс millis (15-25) между изменениями "i" .  или    2 вар - вместо for сделать 5 ступеней плюс millis (130-185)между ними 
      delay(15);           
      if (blockState = !digitalRead(BLOCK))
        break; // выход из цикла "for" при внезапном исчезновении сигнала блокиратора ("внезапное" считать исчезновение сигнала во время уравновешивания валов)
    }
  }
  if (!blockState && blockFlag) // Сигнал на блокиратор отключен
  {
    blockFlag = false; // Флаг = 0

    analogWrite(PWR, 0);
  }
}

Заранее спасибо!

чушь какая-то с точки зрения физики

Заведите переменную-флаг, которая означала бы, что уравновешивание уже выполнено. При поступлении сигнала на блокировку, проверяете сначала, не установлен ли уже флаг, если нет - выставляйте флаг в true. И оставляйте true, пока не придет сигнал ра3блокировать.

1 лайк

в этой строке вы что-то не то делаете…
Может вы имели в виду != - но у вас совсем другое

1 лайк

Набор переменных нужно составлять, исходя из задачи. А то у Вас много переменных, которые непонятно, для чего нужны и, соответственно, не используются. Итак, у Вас есть:

  • два состояния внешнего сигнала (должна быть одна булева переменная),
  • три состояния блокиратора: 0%, 25%, 100% (одна целая переменная),
  • фактор времени (одна длинная целая переменная, одна константа и millis().
    Теперь Вам надо составить таблицу переходов между состояниями. Ну а по таблице переходов уже пишется код.
2 лайка

он висит в цикле более 3 секунд, это реакция на кнопку СТОП видимо

Благодарю, не претендую на отсутствие избыточности и правильности кода, только учусь, ввел флаг как Вы написали и все получилось. Хотя неделю ровно этим же и занимался. Ну… правильно сформулированное объяснение, есть залог успеха. Сигнал появился, происходит частичная блокирование, через заданное время блокирование плавно достигает 100%, затем держит это значение. При исчезновении сигнала блокирование -0%. Из цикла так же вываливается в 0. Огромное спасибо))
Теперь следующая задача избавиться от delay ибо данный код часть основного и там delay совсем не нужен. Но это позже

Итоговый код

#define PWR 10
#define BLOCK 2
#define TIME 1500
uint32_t blockTime = 0;
bool blockState = false;
bool pwrState = false;
bool blockFlag = false;
int flag = false;  // флаг уровня сигнала

void setup() {
  pinMode(PWR, OUTPUT);
  pinMode(BLOCK, INPUT);
}
void loop() {
  blockState = digitalRead(BLOCK);

  if (blockState && flag == false) {  // проверка  уровня флага
    if (blockState && !blockFlag) {
      blockFlag = true;
      analogWrite(PWR, 25);
      blockTime = millis();
    }
    if (blockState && blockFlag && millis() - blockTime >= TIME) {
      for (int i = 25; i <= 255; i++) {
        analogWrite(PWR, i);
        delay(15);
        if (i == 255) {
          flag = true;  // установка текущего состояния флага
        }
        if (blockState != digitalRead(BLOCK))
          break;
      }
    }
  }
  if (blockState && flag) {  // ШИМ 100% при неизменности уровня флага
    analogWrite(PWR, 255);
  }
  if (blockState != digitalRead(BLOCK) && blockFlag) {
    blockFlag = false;  // При отсутсвии сигнала блокирования изменяем уровень флага
    flag = false;
    analogWrite(PWR, 0);  // ШИМ 0% при изменении уровня флага
  }
}

Исправил

Благодарю! К сожалению стыду и прочему уже мозги не молоды, тяжело новое дается. Обязательно найду время облегчить код от лишнего мусора)

код с двумя (как минимум) ошибками, да процент попадания на одну из них менее 0,5% но вместо СТОП имеем полное включение

1 лайк

Интересно, уточните для понимания, спасибо)

дак я не “настоящий сталевар”, может заблуждаюсь, сейчас настоящие подтянутся и озвучат…

смотрим с 27 строки и проговариваем, что будет если цикл открутился и пришел сигнал стоп

ничего не будет. Если цикл открутился, там и так полное включение.

1 лайк

а надо выполнить команду отставить

строка 38

и будет оно щёлкать…строка 35…

нет, строка 39

это каким оно чудным образом попадет на 39 минуя 35?

у тебя ну очень плохо с логикой :slight_smile:
Оно, конечно, попадет на 35 - только это абсолютно ни на что не влияет, поскольку сигнал у нас и так 255.
Я об этом тебе сразу написал, еще три поста назад.

у меня логика простая, вернуть всё в исходное состояние надо в момент обнаружения смены режима, ты со станками дело имел когда?