Добрый день, запутался, не хватает тяму) прошу помочь. Есть два вращающихся вала, которые из за разных масс (инерций) вращаются с небольшой разницей в угловых скоростях. Между собой валы соединены блокиратором с двумя ступенями свободы:
Сигнала нет - полностью распущены
Сигнал есть - полностью соединены.
Блокиратор при поступлении сигнала на блокирование вначале блокирует валы на 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блокировать.
Набор переменных нужно составлять, исходя из задачи. А то у Вас много переменных, которые непонятно, для чего нужны и, соответственно, не используются. Итак, у Вас есть:
два состояния внешнего сигнала (должна быть одна булева переменная),
три состояния блокиратора: 0%, 25%, 100% (одна целая переменная),
фактор времени (одна длинная целая переменная, одна константа и millis().
Теперь Вам надо составить таблицу переходов между состояниями. Ну а по таблице переходов уже пишется код.
Благодарю, не претендую на отсутствие избыточности и правильности кода, только учусь, ввел флаг как Вы написали и все получилось. Хотя неделю ровно этим же и занимался. Ну… правильно сформулированное объяснение, есть залог успеха. Сигнал появился, происходит частичная блокирование, через заданное время блокирование плавно достигает 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% при изменении уровня флага
}
}
у тебя ну очень плохо с логикой
Оно, конечно, попадет на 35 - только это абсолютно ни на что не влияет, поскольку сигнал у нас и так 255.
Я об этом тебе сразу написал, еще три поста назад.