Перейти к содержанию

Управление кнопкой, функция pulseIn.


Рекомендуемые сообщения

Не могу понять как сделать управлением кнопкой. Реализую вход в меню программирования готового устройства на базе ардуино. Код взят с сайта амперка для ознакомления и прототипирования на бред-борде. Необходимо считать время нажатой кнопки и если оно находиться в определенном пределе по времени то моргнуть светодиодом 4 раза, если нет то просто зажечь светодиод. Пытался использовать функцию millis(), но столкнулся с трудностями понимания её работы. Прошу сильно не пинать, только осваиваю данную платформу. 

#define BUTTON_PIN  8
#define LED_PIN     13
unsigned long level;
 
boolean buttonWasUp = true;  // была ли кнопка отпущена?
boolean ledEnabled = false;  // включен ли свет?
 
void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}
 
void loop()
{
  // определить момент «клика» несколько сложнее, чем факт того,
  // что кнопка сейчас просто нажата. Для определения клика мы
  // сначала понимаем, отпущена ли кнопка прямо сейчас...
  boolean buttonIsUp = digitalRead(BUTTON_PIN);
 
  // ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
  if (buttonWasUp && !buttonIsUp) {
    // ...может это «клик», а может и ложный сигнал (дребезг),
    // возникающий в момент замыкания/размыкания пластин кнопки,
    // поэтому даём кнопке полностью «успокоиться»...
    delay(10);
    // ...и считываем сигнал снова
    buttonIsUp = digitalRead(BUTTON_PIN);
    if (!buttonIsUp) {  // если она всё ещё нажата...
      // ...это клик! Переворачиваем сигнал светодиода
      // ledEnabled = !ledEnabled;
      level = pulseIn(digitalRead(BUTTON_PIN), HIGH);
      if (level >=5000 || level <=10000)
      {
        digitalWrite(LED_PIN, HIGH);
        delay(500);
        digitalWrite(LED_PIN, LOW);
        delay(500);
        digitalWrite(LED_PIN, HIGH);
        delay(500);
        digitalWrite(LED_PIN, LOW);
        delay(500);
        digitalWrite(LED_PIN, HIGH);
        delay(500);
        digitalWrite(LED_PIN, LOW);
        delay(500);
        digitalWrite(LED_PIN, HIGH);
        delay(500);
        digitalWrite(LED_PIN, LOW);
        delay(500);
      }
      else
      {
        digitalWrite(LED_PIN, HIGH);
        delay(500);
      }
      //digitalWrite(LED_PIN, ledEnabled);
    }
  }
 
  // запоминаем последнее состояние кнопки для новой итерации
  buttonWasUp = buttonIsUp;

  
}

 

Ссылка на комментарий
Поделиться на другие сайты

Привет.

Строка  level = pulseIn(digitalRead(BUTTON_PIN), HIGH);

Должно быть  level = pulseIn(BUTTON_PIN, HIGH);

И еще level  в пределах от 5000 мкс до 10000 мкс. это в пределах от 5 до 10 секунд. Палец устанет давить!!!

и вроде по умолчанию можно до 1 секунды. Без умолчания можно до 180 секунд.

Но тогда должно быть  level = pulseIn(BUTTON_PIN, HIGH,30000); //поставил ограничение  30 секунд

Изменено пользователем Сергей_Харьков
Ссылка на комментарий
Поделиться на другие сайты

Какие длинные микросекунды, однако. Может от 5 до 10 милисекунд? http://arduino.ru/Reference/PulseIn

 

48 минут назад, Сергей_Харьков сказал:

И еще level  в пределах от 5000 мкс до 10000 мкс. это в пределах от 5 до 10 секунд. 

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Виноват, после праздников перепутал

миллисекунды с микросекундами. ( 0.005 с и 0.01 с, Тогда слишком быстро, фиг успеешь попасть)

Тогда просто   level = pulseIn(BUTTON_PIN, HIGH);

Изменено пользователем Сергей_Харьков
Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

А так ли важно определить именно  момент клика? Частота ардуино довольно большая и мне кажется, что определения того, что кнопка сейчас нажата вполне достаточно. Если будет известно, что в предыдущей итерации кнопка была не нажата, а в текущей итерации нажата, то погрешности там будут миллисекунды (если конечно код не очень большой с кучей delay()). Писал я как-то код для модуля джойстика с кнопкой

/* Код предназначен для джойстика и кнопки. Выпоняет следующий алгоритм: при нажатии кнопки и удержании ее в течении 2 секунд, открывается прим данных с джойстика.
 *  Если перемещение джойстика прекращается и не начинается в течении 5 секунд, то прием данных закрывается и программа ожидает следующего нажатия на кнопку.
 */

int axis_X = A0; // Ось Х
int axis_Y = A1; // Ось Y
int button = 2; // Кнопка

int vaule_X = 0; //Текущее значение оси Х
int vaule_Y = 0; //Текущее значение оси Y
int vaule_XP; //Предыдущее значение оси Х
int vaule_YP; //Предыдущее значение оси Y

unsigned long timeout = 10000000; // таймаут функции 10 сек
unsigned long TIME = 0;
unsigned long n_time = 2000000; // условное время начала према данных (мкс)
int k_time = 5000; // условное время закрытия приема (мс)

int nT = 0; // Переменные для отсчитывания времени бездействия
int kT = 0;

int condition_1 = 0; //условие начала приема данных
int condition_2 = 0; //условие, определяющее бездействие

void setup() {
  Serial.begin(9600); //настройка КОМ - порта
  pinMode(axis_X, INPUT); // оси и кнопка это входы
  pinMode(axis_Y, INPUT);
  pinMode(button, INPUT);
  Serial.println("Hello"); //Здрасьте

}

void loop() {
  if ((digitalRead(button) == LOW) && (condition_1 == 0)) // если кнопка нажата и прием данных закрыт
    {
      TIME = pulseIn(button, LOW, timeout); // время, которое кнопка была нажата

      if (TIME >= n_time) // если время нажатия больше или равно двум секундам
        {
          condition_1 = 1; // тогда условию 1 присваиваем единичку
          TIME = 0; //обнуляем времячко
          Serial.println("Data reception is open"); //пишем, что открыт прием данных
        }
    }

  if (condition_1 == 1) //если условие 1 единичка, то принимаем данные
    {
      vaule_XP = vaule_X; // данные в предыдущей итерации
      vaule_YP = vaule_Y;
      vaule_X = map(analogRead(axis_X), 0, 1023, -10, 10); //данные в текущей итерации
      vaule_Y = map(analogRead(axis_Y), 0, 1023, -10, 10);
      Serial.print("X: "); //пишем данные в КОМ
      Serial.print(vaule_X);
      Serial.print(" | Y: ");
      Serial.println(vaule_Y);

      delay(500); // ждем просто так

      if ((vaule_X == vaule_XP) && (vaule_Y == vaule_YP)) //если данные в предыдущей итерации и в текущей совпадают, значит изменения не произошло, значит бездействуем
        {
          if (condition_2 == 0) // если условие 2 нолик, то это значит, что бездействие началось только что
            {
              nT = millis(); // запоминаем время начала бездействия
              condition_2 = 1; // условию 2 присваиваем единичку, чтобы время nT не перезаписвалось с каждой новой итерацией
            }

          if (condition_2 == 1) //если условие 2 единичка, значит бездействие уже идет
            {
              kT = millis(); // текущее время

              if (kT - nT >= k_time) // если бездействие длилось 5 секунд
                {
                  condition_2 = 0; //заканчиваем бездействие
                  condition_1 = 0; //закрываем прием данных
                  Serial.println("Data reception is close"); //пишем, что прием данных закрыт
                }
            }
        }

      else { condition_2 = 0;} //если значения поменялись, присваиваем условию 2 нолик и в следующий раз ожидание бездействия начнется сначала
    }

}

 

Ссылка на комментарий
Поделиться на другие сайты

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Я понял так, что топикстартеру надо определить долгое нажатие, и отреагировать на него не так, как на обычное. Но тогда делается все совсем не так, и гораздо, гораздо проще!

1. Делаем функцию button_is_pressed(), которая вернет 1, если кнопка нажата, и 0 в противном случае. Эта функция занимается тем, что подавляет дребезг (выше вы уже это делали).
2. А теперь заводим переменную-счетчик и делаем цикл "пока кнопка нажата - инкремент счетчика и задержка в 10 мс".
3. После выхода из цикла смотрим на счетчик: его значение будет равно длительности удержания кнопки в нажатом состоянии в десятимиллисекундных интервалах. Ну и соответственно, принимаем решение, что надо сделать если счетчик большой или маленький.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

while(1)

{

delay_ms(10);

oldButton= Button;

Button= PINX.Y;

if(!oldButton && !Button && (counter < 255)) ++counter;

if(!oldButton && Button)

{

if(counter > N) {}; // кнопка была нажатой долго

else {}; // кнопка удерживалась недолго

counter= 0;

}

}

 

Я не раздаю удочки. Я продаю рыбу.

Ссылка на комментарий
Поделиться на другие сайты

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, ARV сказал:

Я понял так, что топикстартеру надо определить долгое нажатие, и отреагировать на него не так, как на обычное. Но тогда делается все совсем не так, и гораздо, гораздо проще!

1. Делаем функцию button_is_pressed(), которая вернет 1, если кнопка нажата, и 0 в противном случае. Эта функция занимается тем, что подавляет дребезг (выше вы уже это делали).
2. А теперь заводим переменную-счетчик и делаем цикл "пока кнопка нажата - инкремент счетчика и задержка в 10 мс".
3. После выхода из цикла смотрим на счетчик: его значение будет равно длительности удержания кнопки в нажатом состоянии в десятимиллисекундных интервалах. Ну и соответственно, принимаем решение, что надо сделать если счетчик большой или маленький.

А зачем так изголяться если можно использовать pulseIn(). Просто делаем условие: если кнопка нажата, считаем время, которое держится сигнал.

Ссылка на комментарий
Поделиться на другие сайты

Только что, Vladislav G. сказал:

А зачем так изголяться

Я описал абстрактный алгоритм - я не знаток ардуино и их "стандартных" функций. Общий алгоритм все равно будет правильным независимо от частностей...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

9 часов назад, ARV сказал:

я бы сделал

Само собой. Я привел только алгоритм в общем виде, не готовый код.

Я не раздаю удочки. Я продаю рыбу.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...