Проблемы с старт-стоп

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Помогите разобраться,

void start() // Подпрограмма запуска ДВС
{
if(digitalRead(6)==HIGH) // если кнопка нажата, то ....
{    
digitalWrite(9,LOW); // выключаем acc
digitalWrite(10,HIGH); // включаем ing 1
digitalWrite(11,HIGH); // включаем ing 2
delay(2000);
digitalWrite(12,HIGH); 
}        
if(digitalRead(7)==LOW&&digitalRead(8)==HIGH) // если есть сигнал с генератор(+12V) или отпущенн тормоз
{ 
digitalWrite(12,LOW); // выключаем стартер
digitalWrite(9,HIGH); // включаем ACC
}
}

Отрывок из моего скетча,не могу понять что делаю не так,по условию при нажатии на кнопку включается зажигание ждем пару сек запускаем стартер и не выключаем пока не получим сигнал с генератора или не отпустим тормоз,а по-факту зажигание включается,стартер включается но при подаче сигнала с генератора или отпускания тормоза стартер не отключается,в чем может быть ошибка,и как в этом месте избавиться от delay?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В строке 11 в комментарии написано ИЛИ, а в программе условие И. Т.е. Вы требуете чтобы было и то, и другое.

Но, хрустальный шао показывает, что дело даже не в этом, думаю, что если поступит сигнал с генератора И Вы отпустите тормоз - один хрен не сработает. Так? Если так, то, скорее всего дело в том как эта функция вызывается, а этого Вы не показали.

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Вы правы по-поводу ИЛИ,исправил стала гаснуть при отпушенном тормозе но если секунд пять не отпускать тормоз а потом отпустить то условие не срабатывает и стартер продолжает работать,думаю возможна проблема в delay Вот полный скетч

unsigned long last_time;
 


int regim=1; // переменная для выбора нескольких режимов, типа что то выбора меню
int flag=0; // переменная состояния нажатия или отжатия кнопки

//-------------- для выполнения какого либо действия по истечению заданого времени после нажатия кнопки ---------------
int val=0; // задаем переменную для счетчика
long previousMillis=0; // зададим начальное значение счетчика millis
long TimePush=200; // время нажатия на кнопку 500= 8секунд
//---------------------------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------

//--------------- задержка для включеня стартера и ACC ---------------------
int previousMillis2=0;
int interval2=50;
//--------------------------------------------------------------------------


void setup()
{
pinMode(6, INPUT); // Вход button (кнопка start-stop)(-)
pinMode(7, INPUT); // Вход педаль тормоза (+12V)
pinMode(8, INPUT); // Вход сигнал генератора (+)
pinMode(9, OUTPUT); // Выход ACC (Акссесуары)(+)
pinMode(10, OUTPUT); // Выход ING 1 (зажигание)(+)
pinMode(11, OUTPUT); // Выход ING 2 (зажигание)(+)
pinMode(12, OUTPUT); // Выход STARTER (стартер)(+)
}

//=============================== Начало основного кода программы ================================================== ===============

void loop()
{

/***** Сам код программы Авто и Ручного пуска ДВС *****/ 

if(digitalRead(6)==HIGH&&flag==0) // если кнопка нажата и переменная flag равна 0, то ....
{
if(digitalRead(7)==LOW) // "ТОРМОЗ" НЕ НАЖАТ
{
regim++; // это нужно для того что бы с каждым нажатием кнопки
flag=1; // происходило только одно действие
// плюс защита от дребезга 100%

if(regim>3) // ограничим количество режимов 
{
regim=1; // так как мы используем только одну кнопку,
// то переключать режимы будем циклично
}
}
}
//================================ Режим Автопуска ДВС ================================================== =
if(digitalRead(7)==HIGH) // если тормоз нажат, то ...
{
start(); // включаем автопуск
regim=0; // обнуляем все режимы(отключаем ручной запуск)
} 
//================================================== ================================================== ====

if(digitalRead(6)==LOW&&flag==1) // проверяем нажата ли кнопка если да, то ... см.ниже
{
flag=0; // обнуляем переменную "кнопка" 
} 

if(regim==1) // первый режим
{
digitalWrite(9,LOW); // выключаем ACC
digitalWrite(10,LOW); // выключаем ING 1
digitalWrite(11,LOW); // выключаем ING 2
digitalWrite(12,LOW); // выключаем STARTER
// ВСЕ ВЫКЛЮЧАЕМ
}


if(regim==2) // второй режим
{
digitalWrite(9,HIGH); // включаем ACC
}
if(regim==3) // третий режим
{
digitalWrite(10,HIGH); // включаем ING 1
digitalWrite(11,HIGH); // включаем ING 2
if(digitalRead(6)==HIGH&&digitalRead(7)==HIGH&flag==0) // если нажата кнопка, нажат "ТОРМОЗ",
{
digitalWrite(12,HIGH); // включаем стартер
digitalWrite(9,LOW); // выключаем ACC
}

if(digitalRead(6)==LOW) // проверяем отпушенна ли кнопка 
{
digitalWrite(12,LOW); // выключаем STARTER
digitalWrite(9,HIGH); // включаем ACC
}

}
/***** Конец кода программы Авто и Ручного пуска ДВС *****/

//====================================== Конец основного кода программы ================================================== ======

} 


// ----------------------- Подпрограмма Автопуска ДВС, в одно касание кнопки -1----------------------------------------------

void start() // Подпрограмма запуска ДВС
{
if(digitalRead(6)==HIGH) // если кнопка нажата, то ....
{    
digitalWrite(9,LOW); // выключаем acc
digitalWrite(10,HIGH); // включаем ing 1
digitalWrite(11,HIGH); // включаем ing 2
delay(2000);
digitalWrite(12,HIGH); 
}        
if(digitalRead(7)==LOW||digitalRead(8)==HIGH) // если есть сигнал с генератор(+12V) или отпущенн тормоз
{ 
digitalWrite(12,LOW); // выключаем стартер
digitalWrite(9,HIGH); // включаем ACC
}
}
//------------------------------------------------2----------------------------------------------------------------------- 
/***** Подпрограмма для сработки кнопки или от чего нибудь,через заданное время *****/

 void pushtime() 
{
if(digitalRead(7)==HIGH) // если педаль или кнопка или что то нажато-включенно, то 
{
if(millis()-previousMillis>=1&&digitalRead(6)==HIGH) // начинаем считать время нажатия
{
previousMillis=millis();
val++; // с каждой милисекундой увеличиваем значение valBut
} 
}
else // если кнопку отпустили, то valBut становится равным 0
{ // это необходимо для защиты от срабатывания при частых
// и многократных нажатиях
val=0;
} 
if(val>=TimePush) // как только значение valLed становиться равным TimtPush
{
regim=0;

//upr(); // запускаем третий режим, т.е. включаем зажигание
val=0; // устанавливаем valBut=0
}
}
//------------------------------------------------2------------------------------------------------------------------------

 

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Вы пишите что неправильно вызывается ф-ция,а как нужно правильно ее вызывать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, нечто подобное я и предполагал.

Вот смотрите, функция start вызывается в строке 59 всегда, когда нажат тормоз. Никаких других условий нет. Притормозили перед ямкой – вызвалась функция start. Если тормоз держим долго, то функция start вызывается постоянно.

Идём дальше.  Допустим, Вы вошли в функцию старт, и условие в строке 111 сработало, через 2 секунды в строке 117 включился стартёр. Разумеется машина не заведётся за доли микросекунды, потому условие в строке 119 будет пока ложным и из функции Вы выйдете. При следующем проходе loop Вы в неё снова войдёте и скорее всего кнопка ещё не будет отпущена, поэтому вместо того. чтобы ждать когда заведётся, Вы начнёте заводить снова.

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

Сейчас Вам надо не от делэя избавляться, а чётко продумать логику автомата и переписать скетч под неё.

mixailovsky
Offline
Зарегистрирован: 23.08.2017

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Выпишите логику начисто простыми словами. А как выпишите, просто напишите под неё новый скетч.

b707
Offline
Зарегистрирован: 26.05.2017

У вас в функции start() неверная логика. Вы в строке 117 включаете стартер и сразу же, в строке 119 - проверяете, не появился ли сигнал с генератора. Между этими событиями в программе проходит несколько микросекунд, поэтому не удивительно, что сигнала с генератора еще нет и стартер не выключается. Вам надо в этой процедуре сделать условием выхода выключение стартера, а пока он работает - крутится в цикле и ждать.

update - Евгений уже все навписал

Squb
Offline
Зарегистрирован: 12.09.2016

Здравствуйте, проверьте логику работы программы ещё раз, и ошибки в условиях If-ов (например, строка 87).

Ваша функция: что-то делает, ничего не делает 2 сек., что-то включает и сразу проверяет условие всего один раз, и если на тот момент ничего не произошло - выходит...

Можно дожидаться условия в цикле.

В while можно хоть бесконечно его ждать).

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

несколько микросекунд 

Гораздо меньше. Там же между включение стартёра и проверкой нет ничего, так что речь идёт только о самой проверке - думаю, что максимум 0,25 - 0,5 микросекунды.

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Логика вроде простая-должно быть три режима если не нажата педаль тормоза 1) все выключено 2)включено зажигание 1 3)включено зажигание 2 и если еще раз нажать на кнопку и нажать педаль тормоза то включаем стартер до тех пор пока не будет сигнала с генератора или пока не будет отпущена кнопка.Запуск в одно касание-если нажата педаль тормоза нет сигнала генератора,включаем зажигание 1и2 ждем 2 секунды,включаем стартер пока не поступит сигнал с генератора или не отпущена педаль тормоза и все,вроде ничего сложного но получается ерунда какая-то.

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Здравствуйте,с while согласен буду пробывать,а в чем ошибка в 87 if немного не понял?если нажата кнопка и нажат тормоз и флаг 0

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Это не логика, это набор слов. Так Вы ничего не запрграммируете.

Разработка автомата делится на следующие этапы:

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

Затем

4. составляется таблица. По горизонтали выписываются все сигналы, по вертикали все состояния. В клетках (пересечениях состояния и поступившего сигнала) записываются две вещи:

1) действие, которое должно быть выполнено если автомат находится в данном состоянии и поступил данный управляющий сигнал.
2) новое состояние, в которое автомат должен перейти после выполнения действия.

После того, как Вы нарисуете такую таблицу, программирование окажется примитивным процессов. Нужно будет просто сделать switch по состояниям и в каждом case проверять поступление управляющих сигналов. Как только выяснится, что какой-то поступил - вполнять действие и переходить в новое состояние записанные в таблице на пересечении текущего состояния и поступившего сигнала. И так постоянно в бесконечном цикле.

Заметьте, при таком подходе не нужно бороться с delay - он тут нигде не появляется сам по себе.

Я понятно обяснил?

Squb
Offline
Зарегистрирован: 12.09.2016

Выходит есть какая-то кнопка и педаль тормоза?

Отбросив на время педаль тормоза, получается, что по каждому нажатию кнопки мы переходим циклично по режимам их всего 3 (пока всё просто, только от дребезга избавиться надо не только флагом, а то будет "рулетка", а не кнопка, если код выполняется быстрее чем проходит дребезг).

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

И пятый режим? Опять только педалью тормоза?

Ошибка в 87, забыли один &

 

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Кнопка притянута к массе,есть 3 режима без нажатия тормоза,и автоматический пуск в одно касание при нажатой педали тормоза.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Как только Вы поймёте этот пример, Вы увидите насколько он похож на то, что я Вам писал выше и, самое главное, Вы с удивлением обнаружите, что такой подход делает тривиальным программирование практичски любого "умного девайса" - практически любого. Потому что с таким подходом можно любой девайс программировать одинаково (так, как я описал парой постов выше с длинным switch и безо всяких делэев).

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

Изучите, не поленитесь - это будет такая прокачка Вашего скиллза - потом будете меня искать, чтобы коньяком напоить.

mixailovsky
Offline
Зарегистрирован: 23.08.2017

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

mixailovsky
Offline
Зарегистрирован: 23.08.2017

Прочитал,не понял вообще ничего...

mixailovsky
Offline
Зарегистрирован: 23.08.2017

А не могли бы вы привести пример while в данном скетче?

Squb
Offline
Зарегистрирован: 12.09.2016

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

http://arduino.ru/Reference/While

Про логику работы: Педаль тормоза из любого режима срабатывает или из определенного?

Что будет если несколько раз нажимать на тормоз? Если мотор уже работает, то зачем его заводить?

Для отладки: добавте себе в ключевых местах вывод в последовательный порт (Serial), входные данные, и режим в котором находится программа, очень иногда помогает...

mixailovsky
Offline
Зарегистрирован: 23.08.2017

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