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

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

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

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

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

#include "button.h"
button bt1(PD3); //кнопка левого поворота
button bt2(PD4); //кнопка правого поворота
const int tr = PD6; //поворот на лево
const int tl = PD7; //поворот на право
unsigned long pt_time = 0;
unsigned long interval = 350;
unsigned long lastmillis = 0;
unsigned long time_off = 0;
unsigned long pt_time_off = 0;
volatile bool flag = false;

void setup()
{
  Serial.begin(9600);
  pinMode (tl, OUTPUT);
  pinMode (tr, OUTPUT);
  digitalWrite(tr, LOW);
  digitalWrite(tl, LOW);
  pinMode(PD2, INPUT);
  attachInterrupt(0,Speed,FALLING);
}

void Speed()
{
  lastmillis=millis();
  flag=!true;
  Serial.println(flag);
}

void loop()
{
  if (bt1.hold() && bt2.hold())
  {
    for(;;)
      {
       unsigned long currentMillis = millis();
       if(currentMillis - pt_time > interval) 
        {
          pt_time = currentMillis; 
          digitalWrite(tr, !digitalRead(tr));
          digitalWrite(tl, !digitalRead(tl));
        }
       if(bt1.click() || bt2.click())
        {
          digitalWrite(tr, LOW);
          digitalWrite(tl, LOW);
          break;
        }
      }    
  }
  
  if (bt1.click())
  {
    for(;;)
      {
        if ((millis()-lastmillis)>1000)
       {
         flag = false;
         Serial.println(flag);
       }
        unsigned long currentMillis = millis();
        if(currentMillis - pt_time > interval) 
        {
          pt_time = currentMillis; 
          digitalWrite(tl, !digitalRead(tl));
        }
        if (flag = true)
        {
           Serial.println("time");
        }
        if(bt1.click() || bt2.click())
        {
          digitalWrite(tl, LOW);
          flag==false;
          break;
        }
      } 
  }
 
  if (bt2.click())
  {
      for(;;)
      {
        if ((millis()-lastmillis)>1000)
       {
         flag = false;
         Serial.println(flag);  
       }
        unsigned long currentMillis = millis();
        if(currentMillis - pt_time > interval) 
        {
          pt_time = currentMillis; 
          digitalWrite(tr, !digitalRead(tr));
        }                 
        if(flag = true)
        {
           Serial.println("time");
        }
        if(bt1.click() || bt2.click())
        {
          digitalWrite(tr, LOW);
          break;
        }
      } 
  }
}

 

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

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

#include "button.h"
button bt1(PD3); //кнопка левого поворота
button bt2(PD4); //кнопка правого поворота
const int tr = PD6; //поворот на лево
const int tl = PD7; //поворот на право
unsigned long pt_time = 0; // переменная для работы мигания.
unsigned long interval = 350; //интервал мигания поворота
unsigned long lastmillis = 0; // переменная для определения стоим или едем
unsigned long pt_time_off = 0; // переменная для работы таймера отключения по времени
volatile bool flag = false; // флаг едем или нет
bool _turn = false; // флаг была ли нажата кнопка поворота.

void setup()
{
  pinMode (tl, OUTPUT);
  pinMode (tr, OUTPUT);
  digitalWrite(tr, LOW);
  digitalWrite(tl, LOW);
  pinMode(PD2, INPUT);
  digitalWrite(PD2, LOW);
  attachInterrupt(0,Speed,FALLING);
}

void Speed() //функция флага едем или нет.
{
  lastmillis=millis();
  flag=true;
}

void turn(byte side) // функция обработки мигания поворота
{
  for(;;)
      {
        if ((millis()-lastmillis)>1000) // проверяем если не едем 1 сек то флаг в 0.
       {
         flag = false;
       }
        unsigned long currentMillis = millis();
        if(currentMillis - pt_time > interval) 
        {
          pt_time = currentMillis; 
          digitalWrite(side, !digitalRead(side));
        }
        if (flag == true)
        {
           if(millis() - pt_time_off > 10000) // таймер отключения через 10 сек, после начала движения или в движении.
           {
            digitalWrite(side, LOW);
            _turn = false;
            pt_time_off = 0;
            break;
           }
        }
        if(bt1.click() || bt2.click())
        {
          digitalWrite(side, LOW);
          _turn = false;
          pt_time_off = 0;
          break;
        }
      } 
}

void loop()
{
// аварийка если зажаты 2 кнопки одновременно
  if (bt1.hold() && bt2.hold())
  {
    for(;;)
      {
       unsigned long currentMillis = millis();
       if(currentMillis - pt_time > interval) 
        {
          pt_time = currentMillis; 
          digitalWrite(tr, !digitalRead(tr));
          digitalWrite(tl, !digitalRead(tl));
        }
       if(bt1.click() || bt2.click())
        {
          digitalWrite(tr, LOW);
          digitalWrite(tl, LOW);
          break;
        }
      }    
  }
  
  if (bt1.click()) // проверяем нажат ли левый поворот
  {
    _turn = true;
    pt_time_off=millis();
    turn(tl);
  }
 
  if (bt2.click()) // проверяем нажат ли правый поворот
  {
    _turn = true;
    pt_time_off=millis();
    turn(tr);
  }
}

 

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 пишет:

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

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