регистрация событий millis

vinipuh
Offline
Зарегистрирован: 03.12.2017

Здравствуйте

Реализую управление через акселерометр adxl 335: при установке акселерометра в определенном положении (угол по X=40…45 град и угол по Y=5…10 град) и задержкой в положении от 2 до 4 сек, сервопривод принимает положение 1, при повторном положение в положение 2, затем в 1 и т.д.

При реализации  флаг Zabr меняет значения циклично (0,1,0 …) без выполнения условия.

   unsigned long time; // время начала события
   boolean Zabr=0;     //флаг изменения события

    x=analogRead(A0); //снимаем данные акселерометра по оси X 
    y=analogRead(A1); //снимаем данные акселерометра по оси Y

   if (600<x<700 && 200<y<3000) { // условие для нужного положения акселерометра
             time=millis(); // время начала события
   if (2000<(millis()-time<4000) { // условие правильности
             Zabr=!Zabr;
            }
          }
     switch (Zabr) {
     case 0: servo1.write(50);
     case 1: servo1.write(100);
       }

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

    if (600<x<700 && 200<y<3000) { // условие для нужного положения акселерометра
             time=millis(); // время начала события
   while (600<x<700 && 200<y<3000) { // условие правильности
             T=millis()-time; // длительность события
   If (T>4000) { // условие ошибки
              break; // вход из цикла
                 }
            }
    }
   If (2000<T<4000) { // условие для правильного собтия
              Zabr=!Zabr;
            }
             T=0; // сброс значения
    }

Значения флага Zabr  также меняются (0,1,0 ..)

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

запись типа

if (100 < x < 500) {
}

делает совсем не то, что вы думаете, так значение на диапазон не проверяют

 

Вообще, за два года знакомства с ардуино уж синтаксис языка Си можно было выучить, нет?

vinipuh
Offline
Зарегистрирован: 03.12.2017

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

  if ( 600<x && x < 700) // так получше

Не совсем понятно почему при неверном условии цикла while, вполняется вход в цикл. 

Поясните мои измышления на счет реализации данного прримера через while. Если далее по тексту программы будут заданы другие условия, то возможна нестабильная работа по учету промежутков (программа ведь выполняется последовательно).

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

vinipuh пишет:

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

  if ( 600<x && x < 700) // так получше

Так не "получше", а именно так и надо реализовывать проверку на интервал.

Цитата:
Не совсем понятно почему при неверном условии цикла while, вполняется вход в цикл.

И какое именно условие и в каком цикле?

vinipuh
Offline
Зарегистрирован: 03.12.2017

Условие в самом цикле while (600<х<700), при значении х и y равным 0 происходит изменение Zabr на 0,1,0,1.

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

vinipuh пишет:
Условие в самом цикле while (600<х<700), при значении х и y равным 0 происходит изменение Zabr на 0,1,0,1.

Виннипух, вам уже два человека сказали, что это условие так записывать нельзя! Или вы думаете, что это только к оператору if относилось? - в while то же самое

Kakmyc
Offline
Зарегистрирован: 15.01.2018

А вариант, который "так получше", должен быть записан так:

if((x>600&&x<700)&&(y>200&&y<3000)) {//действие}

vinipuh
Offline
Зарегистрирован: 03.12.2017

Спасибо за разьяснения

vinipuh
Offline
Зарегистрирован: 03.12.2017

Уважаемые гуру поясните отсчёт промежутков времени события можно реализовать через вкладки ветвление условий if или циклом while который отсчитает длительность и проверит условие наступления события. Вопрос такой, если код выполняется построчно внутри цикла loop, то при вычислении промежутка вида 2000<(millis()- time)<4000 программа будет несколько раз крутится просматривая код ниже т.е если был сбой, условие не выполнится. Если вычисляется внутри цикла while, то игнорируется код ниже пока не выйдет из цикла т.е. отслеживание промежутка более стабильно?
И ещё маленькое уточнение, для отсчёта промежутка от 2 до 4 секунд есть ли смысл использовать фильтр для данных с акселерометра?

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

vinipuh - попробуйте задать вопрос более ясно. Пока очень мало что понятно.

Единственное что могу сказать - да, код ниже цикла while выполняется только после того, как программа выйдет из цикла...

Удивительно, но это так.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

vinipuh пишет:
при вычислении промежутка вида 2000<(millis()- time)<4000 программа будет

.. плакали, кололись, но продолжали есть кактус...

Еще раз - запись типа

if (100<x<200)
или
while (100<x<200)

хоть и является допустимой с точки зрения синтаксиса языка С/С++ но делает совсем не то, что вам представляется. Для срабатывания условия на интервал надо писать 

while (100<x && x<200)

 

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

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

vinipuh
Offline
Зарегистрирован: 03.12.2017

Уважаемые гуру сорян за неправильное задание диапазона, это просто пояснение к моему вопросу. Да я полено но буратино спрашивает у папы Карло: "акселерометром реализуется несколько команд, через фиксацию положения акселерометра на определенное время. Если условие выполняются то изменяются флажки. На основе значений которых даются команды сервоприводам. Соответственно:
1 если реализовать через if то можно выполнять несколько команд одновременно - это так или я полено?
2 если реализовывать через while только последовательно, одну команду за другой -это так или нет и я большое полено (при условии что после цикла даётся команда сервоприводу)?
И если наконец, время фиксации положения акселерометра от 2 до 4 секунд, нужна стабилизация данных через фильтр или возможны случайные значения требующие фильтра или сокращения диапазона времени удержания датчика.
Да это глупые вопросы для гуру, но куда бегут электроны хз, ведь спрашивают гугу потому что не понимают. Где обьясняют, что происходит конкретно при записи if (600 Без обид, спасибо за уделённое мне время.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ардуино физически не умеет выполнять несколько комманд одновременно, независимо в if это или while или просто так. Все делается строго одна за одной. Команды ветвления лишь определяют какие именно команды   буду выполнены следующими.

 

Про "время фиксации положения акселерометра от 2 до 4 секунд" вообще не очень понятно. Акселерометр не может фиксировать положение, он только дает значение ускорения. Время же чтения данных ускорения это милисекунды, а то и меньше. 

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

vinipuh пишет:
Соответственно: 1 если реализовать через if то можно выполнять несколько команд одновременно - это так или я полено? 2 если реализовывать через while только последовательно, одну команду за другой -это так или нет и я большое полено (при условии что после цикла даётся команда сервоприводу)?

Если нужно "параллельное" выполнение - не ждите наступление события в цикле как в вашем коде, пусть код крутится по всему loop(), соберите все нужные условия в if, как они выполнятся - сделайте что вам нужно + сделайте так чтобы не влететь тут же в этот if снова (что нибудь обнулите, присвойте новое значение millis какой то переменной и т.п.) и крутите дальше loop(). (читать про конечные автоматы)

vinipuh
Offline
Зарегистрирован: 03.12.2017

Спасибо за разъяснения.