реле поворотов, вопрос реализации прерываний.

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

Доброго всем дня, вот возникла такая необходимость.

Задачка: включение поворотника раздельными кнопка(право лево) выключение при нажатии на любую, при нажатии больше 500мс на обе включение аварийки, отключение поворота через 3 сек после начала или в движении
Вроде всё работает, но вот реализовать выключение через 3 сек после начала движения никак не могу победить.
думаю так: подключение датчика холла от спидометра для определения наличия движения, работа через прерывание, и добавить функцию проверки времени в код прерывания или программы.
Столкнулся с такой штукой, при работе программы в порт при нажатии кнопки поворота bt1 или bt2 летит и "0" и слово "time" которое должно появиться только после хотя-бы одного срабатывания прерывания, если нажать кнопку на ножке прерывания в течении секунды видим только "time" что верно, но потом снова чередующиеся 0 time

никак не могу понять где ошибся может кто подскажет?! не судите строго только начинаю разбираться.
 

001#include "button.h"
002button bt1(PD3); //кнопка левого поворота
003button bt2(PD4); //кнопка правого поворота
004const int tr = PD6; //поворот на лево
005const int tl = PD7; //поворот на право
006unsigned long pt_time = 0;
007unsigned long interval = 350;
008unsigned long lastmillis = 0;
009unsigned long time_off = 0;
010unsigned long pt_time_off = 0;
011volatile bool flag = false;
012 
013void setup()
014{
015  Serial.begin(9600);
016  pinMode (tl, OUTPUT);
017  pinMode (tr, OUTPUT);
018  digitalWrite(tr, LOW);
019  digitalWrite(tl, LOW);
020  pinMode(PD2, INPUT);
021  attachInterrupt(0,Speed,FALLING);
022}
023 
024void Speed()
025{
026  lastmillis=millis();
027  flag=!true;
028  Serial.println(flag);
029}
030 
031void loop()
032{
033  if (bt1.hold() && bt2.hold())
034  {
035    for(;;)
036      {
037       unsigned long currentMillis = millis();
038       if(currentMillis - pt_time > interval)
039        {
040          pt_time = currentMillis;
041          digitalWrite(tr, !digitalRead(tr));
042          digitalWrite(tl, !digitalRead(tl));
043        }
044       if(bt1.click() || bt2.click())
045        {
046          digitalWrite(tr, LOW);
047          digitalWrite(tl, LOW);
048          break;
049        }
050      }   
051  }
052   
053  if (bt1.click())
054  {
055    for(;;)
056      {
057        if ((millis()-lastmillis)>1000)
058       {
059         flag = false;
060         Serial.println(flag);
061       }
062        unsigned long currentMillis = millis();
063        if(currentMillis - pt_time > interval)
064        {
065          pt_time = currentMillis;
066          digitalWrite(tl, !digitalRead(tl));
067        }
068        if (flag = true)
069        {
070           Serial.println("time");
071        }
072        if(bt1.click() || bt2.click())
073        {
074          digitalWrite(tl, LOW);
075          flag==false;
076          break;
077        }
078      }
079  }
080  
081  if (bt2.click())
082  {
083      for(;;)
084      {
085        if ((millis()-lastmillis)>1000)
086       {
087         flag = false;
088         Serial.println(flag); 
089       }
090        unsigned long currentMillis = millis();
091        if(currentMillis - pt_time > interval)
092        {
093          pt_time = currentMillis;
094          digitalWrite(tr, !digitalRead(tr));
095        }                
096        if(flag = true)
097        {
098           Serial.println("time");
099        }
100        if(bt1.click() || bt2.click())
101        {
102          digitalWrite(tr, LOW);
103          break;
104        }
105      }
106  }
107}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Таймеры тебе нужны, а не вот это вот всё. 

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

спасибо погляжу!

Но тут то тоже интересно разобраться, почему оно так работает?!

Upper
Offline
Зарегистрирован: 23.06.2020

Алгоритм довольно путанный для не подготовленного пользователя. (я не понял).

К тому же вы путаете == и = , 
027  flag=!true;  Это ошибка или так и задумано.

Напишите, какая строка выполняется не в то время, и по каким условиям она должна выполняться. Проверьте нет ли там путаницы с =  ==  !=

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Может не знает как false пишется?))

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

с !flag ошибка! 

За = и == спасибо! разобрался, поправил, работает как нужно!

Morroc
Offline
Зарегистрирован: 24.10.2016

Morfeantyri пишет:

отключение поворота через 3 сек после начала или в движении

это зачем такое ?

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

реле поворотов для постройки кастома. пульты и всё остальное может быть любым и работать должно при всяких итерациях. 

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

Поправил и свернул в функцию обработку нажатия кнопки поворота. В таком виде, на макетке, вроде работает как надо.
получилось как-то так. 
Буду рад критике ибо без неё не видно что можно улучшить.

001#include "button.h"
002button bt1(PD3); //кнопка левого поворота
003button bt2(PD4); //кнопка правого поворота
004const int tr = PD6; //поворот на лево
005const int tl = PD7; //поворот на право
006unsigned long pt_time = 0; // переменная для работы мигания.
007unsigned long interval = 350; //интервал мигания поворота
008unsigned long lastmillis = 0; // переменная для определения стоим или едем
009unsigned long pt_time_off = 0; // переменная для работы таймера отключения по времени
010volatile bool flag = false; // флаг едем или нет
011bool _turn = false; // флаг была ли нажата кнопка поворота.
012 
013void setup()
014{
015  pinMode (tl, OUTPUT);
016  pinMode (tr, OUTPUT);
017  digitalWrite(tr, LOW);
018  digitalWrite(tl, LOW);
019  pinMode(PD2, INPUT);
020  digitalWrite(PD2, LOW);
021  attachInterrupt(0,Speed,FALLING);
022}
023 
024void Speed() //функция флага едем или нет.
025{
026  lastmillis=millis();
027  flag=true;
028}
029 
030void turn(byte side) // функция обработки мигания поворота
031{
032  for(;;)
033      {
034        if ((millis()-lastmillis)>1000) // проверяем если не едем 1 сек то флаг в 0.
035       {
036         flag = false;
037       }
038        unsigned long currentMillis = millis();
039        if(currentMillis - pt_time > interval)
040        {
041          pt_time = currentMillis;
042          digitalWrite(side, !digitalRead(side));
043        }
044        if (flag == true)
045        {
046           if(millis() - pt_time_off > 10000) // таймер отключения через 10 сек, после начала движения или в движении.
047           {
048            digitalWrite(side, LOW);
049            _turn = false;
050            pt_time_off = 0;
051            break;
052           }
053        }
054        if(bt1.click() || bt2.click())
055        {
056          digitalWrite(side, LOW);
057          _turn = false;
058          pt_time_off = 0;
059          break;
060        }
061      }
062}
063 
064void loop()
065{
066// аварийка если зажаты 2 кнопки одновременно
067  if (bt1.hold() && bt2.hold())
068  {
069    for(;;)
070      {
071       unsigned long currentMillis = millis();
072       if(currentMillis - pt_time > interval)
073        {
074          pt_time = currentMillis;
075          digitalWrite(tr, !digitalRead(tr));
076          digitalWrite(tl, !digitalRead(tl));
077        }
078       if(bt1.click() || bt2.click())
079        {
080          digitalWrite(tr, LOW);
081          digitalWrite(tl, LOW);
082          break;
083        }
084      }   
085  }
086   
087  if (bt1.click()) // проверяем нажат ли левый поворот
088  {
089    _turn = true;
090    pt_time_off=millis();
091    turn(tl);
092  }
093  
094  if (bt2.click()) // проверяем нажат ли правый поворот
095  {
096    _turn = true;
097    pt_time_off=millis();
098    turn(tr);
099  }
100}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Это ты сам писал?

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

когда то в институте изучал С но это забылось давно не работаю с ним.
Тут посмотрел уроки по реализации функций.
как избавиться от delay ибо тормозить процессор не правильно.
реализация и программный фильтр дребезга контактов через millis (хотя в реале один фиг разведу на плате через резюк на минус :))
обработка кнопок в классе!(это позаимствовал, хотя можно было и основном файле написать обработчик). 
как реализовать прерывания.
дальше как свернуть в функцию поглядел синтаксис.

вроде ничего сложного но как показала практика детские ошибки типа = и == случаются :(

теперь это всё надо будет ещё перенести на ATTINY(там я так понял свои способы по реализации прерываний, но для начала почитать и попробовать а там видно будет) и будет хорошо.  

Morroc
Offline
Зарегистрирован: 24.10.2016

Morfeantyri пишет:

Тут посмотрел уроки по реализации функций.
как избавиться от delay ибо тормозить процессор не правильно.

Но добавили бесконечные циклы. От них тоже надо избавляться тогда уж.

Morfeantyri
Offline
Зарегистрирован: 10.06.2022

Morroc пишет:

Но добавили бесконечные циклы. От них тоже надо избавляться тогда уж.

В данной реализации это не имеет значения, а так да... буду читать дальше.