реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Дребезг контактов, Как избежать?
Labinskiy Nikola...
сообщение Jul 9 2006, 18:55
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 27
Регистрация: 5-07-06
Из: Украина, Донецк
Пользователь №: 18 606



Кнопка замыкает ножку на землю.
Mega16
Код
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL  // 8 MHz
#include <util/delay.h>

ISR(INT2_vect)
{
  int i;
  for (i=0;i<3;i++)
    _delay_ms(10);
  if ((PINB & 0x04)==0) // ножка внешнего прерывания
      PORTA ^= 1;
}

int main()
{
  PORTA = 0;
  DDRA = 0xFF;

  PORTB = 0xFF;
  DDRB = 0x00;
  
  MCUCSR &= ~_BV(ISC2);  // по заднему фронту (H->L)
  GICR = _BV (INT2);
  sei ();

  for(;;)
  return(0);
}


Идея вроде бы правильная, но на практике срабатывает плоховато...
В чем ошибка?

Сообщение отредактировал Labinskiy Nikolay - Jul 9 2006, 18:59


--------------------
If you can't make it good - don't make it look good ;)
Go to the top of the page
 
+Quote Post
Yura_K
сообщение Jul 9 2006, 19:13
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821



Код
  int i;
  for (i=0;i<3;i++)
    _delay_ms(10);

Во-первых, НЕОБХОДИМО ИЗБАВИТЬСЯ от задержек в прерывании. Всякие delay вынести в основной цикл.
Во-вторых, я бы сделал следующим образом: считывал 3 раза уровень на нужном выводе, а после принимал решение m из n (в данном случае 2 из 3) о нажатии кнопки (естественно, в основном цикле).


--------------------
Чудес не бывает - бывает мало знаний и опыта!
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 9 2006, 19:25
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Есть два стандартных способа опроса клавиатуры с устранением дребезга контактов.
1. Интервальный. Состояние кнопок опрашивается с интервалом заведомо превышающим время дребезга. Процедуру опроса удобно запускать в каком-нибудь таймерном прерывании с периодом 10-15 мс. Если состояние клавиатуры между двумя соседними вызовами процедуры одинаково, то оно считается устойчивым.
2. Счетчик состояния. При вызове процедуры подсчитывается (программно) количество совпадений одинакового состояния клавиши. Если до окончания счета состояние меняется, то счетчик сбрасывается и перезапускается. Состояние считается устойчивым, если счетчик совпадений досчитал до заранее определенного (алгоритмически, экспериментально или интуитивно smile.gif ) числа (например, 15).
Поскольку в вашем случае процедура определения состояния кнопки запускается по прерыванию от этой конопки, то думаю вам подойдет второй алгоритм.

Попробуйте такой алгоритм.

Код
#define COUNT_END  10
#define COUNT_PERIOD   15

ISR(INT2_vect)
{
  int i=0, j=0;
  while (i<COUNT_END)
  {  if ((PINB & 0x04)==0)
      { i++;
         j=0;
       }
       else
       { i=0;
      j++;
       }
       if (j>COUNT_PERIOD) break;
   }
   PORTA ^= 1;
}
Go to the top of the page
 
+Quote Post
Stas633
сообщение Jul 9 2006, 22:32
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



Цитата(rezident @ Jul 9 2006, 23:25) *
Есть два стандартных способа опроса клавиатуры с устранением дребезга контактов.
1. Интервальный.... .....Если состояние клавиатуры между двумя соседними вызовами процедуры одинаково, то оно считается устойчивым.....


Будет ли верным, на Ваш взгляд, определять состояние нажатой кнопки так: в начале определять "КАКАЯ-ТО ИЗ КНОПОК НАЖАТА", а через время на устранение дребезга - "КАКАЯ КНОПКА НАЖАТА"?

Особенно если клавиатура - не матрица кнопок, а резистивный делитель, как во многих автомагнитолах (пример схемы в файле).

Каким алгоритмом пользуются производители автомагнитол?

Спасибо.

Для справки: Весовые резисторы подобраны всегда так, что диапазон напряжения делителя делится поровну, по числу кнопок.

С уважением.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
TamTam
сообщение Jul 9 2006, 22:50
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254



[quote name='Stas633' date='Jul 10 2006, 02:32' post='132459']
[quote name='rezident' post='132434' date='Jul 9 2006, 23:25']

Каким алгоритмом пользуются производители автомагнитол?

Спасибо.

Для справки: Весовые резисторы подобраны всегда так, что диапазон напряжения делителя делится поровну, по числу кнопок.

С уважением.
[/quote]

Судя по схеме подключения они используют 1 канал АЦП, а резюки подобраны так для того чтоб можно было определить нажатие 2-х кнопок сразу, а не спутать его с нажатием другой кнопки
Go to the top of the page
 
+Quote Post
Velund
сообщение Jul 9 2006, 23:59
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 693
Регистрация: 19-11-04
Пользователь №: 1 177



С весовыми резисторами имеет смысл связываться только тогда, когда есть уверенность в долговременной надежности самих кнопок и не будет конденсации влаги никогда. Иначе получится как у доблестной фирмы Моторола в радиостанциях CP-50 - при активном использовании максимум год и надо менять "резинку" клавиш с проводящими пятачками, предварительно отмыв до блеска пленочную плату что под ней на держатель наклеена. Иначе "нажимается" все что угодно, кроме того что надо, часто само по себе.
Go to the top of the page
 
+Quote Post
upc2
сообщение Jul 10 2006, 04:32
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Можно с использованием флагов.В прерывании устанавливается флаг, а в основной программе, после обработки функции нажатия клавиши , он должен сбрасываться.
По стандарту время на нажатие клавиши от 0,5 до 1 сек. Иногда достаточно установить задержку
около 200 мсек.
Go to the top of the page
 
+Quote Post
Kovrov
сообщение Jul 10 2006, 06:17
Сообщение #8


Мастер-фломастер
****

Группа: Свой
Сообщений: 611
Регистрация: 29-12-05
Пользователь №: 12 700



Такой вариант обхода дребезга - пользуюсь когда мне нужно быть на 200% уверенным что дребезг кончился..
завожу переменную (счетчик нужного состояния порта) , и делаю переодический опрос этого алгоритма (полингом ,таймером, или как угодно)
при каждой опросе смотрю за состоянием порта если вкл - прибавляю переменную до нужного значения, если вдруг дрыгнулось в другую сторону, сбрасываю счетчик и все котовасию повторяю до тех пор, пока переменная не достигнет значения на реакцию ON
ну и соответственно тоже самое с OFF тока переменную убаваляю до нужного значения...


--------------------
Вон ПОПОВ, клоун клоуном, а радио изобрел!!
Go to the top of the page
 
+Quote Post
Stas633
сообщение Jul 10 2006, 07:45
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



Цитата(Velund @ Jul 10 2006, 03:59) *
С весовыми резисторами имеет смысл связываться только тогда, когда есть уверенность в долговременной надежности самих кнопок и не будет конденсации влаги никогда......


Не во всем согласен с Вами. Вы ведете речь о "резиновой" клавиатуре. А сопротивление замкнутого контакта у нее от десятков (новая) до сотен (старая) ом. У "кнопочной" (контактной) клавиатуры значение сопротивления в процессе эксплуатации меняется от десятых долей до единиц ома.
Для весовых резисторов сопротивлением в единицы кОм, согласитесь, это большая разница.

Да и эксплуатациую в салоне автомобиля "тепличными" условиями, назвать трудно. Наоборот, изделие будет подвержено частой смене температурно-влажностного режима. И тем не менее, во всех (кроме тех, где процессор объединен с PLL) автомагнитолах используется схема с весовымы резисторами. Правда "резиновой" клавиатуры на магнитолах я не встречал никогда.

Имея же в "распоряжении" ADC "на борту" AVR'a считаю целесообразным "связываться" с весовыми резисторами, чтобы выводы портов оставить "свободными" для иных нужд. Вопрос - как правильно и оптимально защититься от "ложных" срабатываний на всем периоде эксплуатации?

To Kovrov.

Описанный Вами метод, есть ни что иное, как "Счетчик состояния", используя терминологию rezident. Если быть точным, то это "мажоритарный" метод принятия решения.

Мне кажеться он не удобен, в силу непредсказуемости времени окончания работы алгоритма. Хотя для правильного определения нажатия кнопки - метод самый верный. ("200%" - согласен).


Интересно, каким же алгоритмом пользуются производители автомагнитол?

С уважением.
Go to the top of the page
 
+Quote Post
Kovrov
сообщение Jul 10 2006, 08:46
Сообщение #10


Мастер-фломастер
****

Группа: Свой
Сообщений: 611
Регистрация: 29-12-05
Пользователь №: 12 700



Цитата(Stas633 @ Jul 10 2006, 11:45) *
Мне кажеться он не удобен, в силу непредсказуемости времени окончания работы алгоритма. Хотя для правильного определения нажатия кнопки - метод самый верный. ("200%" - согласен).

почемуже не предсказуем?
у меня этот алгоритм в моей программе "крутиться" всегда
другое дело время реакции зависит от самого дребезга...
ну вот тут действительно дребезг - вещь непредсказуемая
если кнопка грязью забилась да ещё при этом еле нажмать.... smile.gif


--------------------
Вон ПОПОВ, клоун клоуном, а радио изобрел!!
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 10 2006, 09:27
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



При использовании ADC и "аналоговой" клавитуры считаю более логичным избавляться от дребезга путем введения интегрирующего звена на входе АЦП. То бишь RC нужно. Тут в соседний теме уже давали ссылку на пример матричной "аналоговой" клавиатуры. http://www.ustr.net/electronics/akeys.shtml
Go to the top of the page
 
+Quote Post
Stas633
сообщение Jul 10 2006, 10:40
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



Цитата(rezident @ Jul 10 2006, 13:27) *
При использовании ADC и "аналоговой" клавитуры считаю более логичным избавляться от дребезга путем введения интегрирующего звена на входе АЦП. То бишь RC нужно. Тут в соседний теме уже давали ссылку на пример матричной "аналоговой" клавиатуры. http://www.ustr.net/electronics/akeys.shtml

Не согласен принципиально.
Дребезг контактов в "аналоговой" (поддерживаю такое определение) клавиатуре - это увеличение напряжения на входе ADC, из-за высокого сопротивления нажимаемой кнопки в начале "нажатия". А интегрирующее звено, по природе своей - "накопитель". То есть призвано устранять "провалы", накапливать напряжение. Что только усугубит последствия дребезга, увеличив время установления конечного напряжения.
Как (хорошо или плохо) работает схема по ссылке я не знаю. Но думаю, что со "старыми" кнопками устойчивых значений до ТЫСЯЧНЫХ долей вольта НЕ ПОЛУЧИТЬ! Интерсно было бы узнать мнение конструктора после некоторого периода эксплуатации.

Спасибо.

С уважением.
Go to the top of the page
 
+Quote Post
Kovrov
сообщение Jul 10 2006, 11:36
Сообщение #13


Мастер-фломастер
****

Группа: Свой
Сообщений: 611
Регистрация: 29-12-05
Пользователь №: 12 700



по профилю работы часто приходится общаться с профессиональной аудио аппаратурой
с микропроцессорным управлением
конечно не все но очень много приборов где
реализован опрос при помощи ацп
использован ряд кнопок (обычно не более 6 на канал ацп) и все это идет через делитель
так и опрашивается...
хотя когда начинаются кнопочки "наедаться" очень весело бывает....


--------------------
Вон ПОПОВ, клоун клоуном, а радио изобрел!!
Go to the top of the page
 
+Quote Post
Stas633
сообщение Jul 10 2006, 11:52
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



Цитата(Kovrov @ Jul 10 2006, 15:36) *
.... и все это идет через делитель......


Интегратор??
Go to the top of the page
 
+Quote Post
BVU
сообщение Jul 10 2006, 13:01
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 301
Регистрация: 30-11-04
Из: Россия, Н.Новгород
Пользователь №: 1 264



Программных алгоритмов антидребезга может быть достаточно много, но на мой взгляд самыми классическим критериями (на все случаи жизни для обработки состояний клавиатуры) по которым можно написать такие алгоритмы должны основываться на построении следующего замкнутого графа:
1. Определение состояния надежно-разомкнутого контакта (группы контактов).
2. Определение состояния первого замыкания контакта. Это и есть начало дребезга, который должен игнорироваться до определения следующего состояния (3).
3. Определение состояния надежно-замкнутого контакта (группы контактов).
4. Определение состояния первого размыкания контакта. Есть начало дребезга, который должен игнорироваться до определения следующего состояния (1).

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


--------------------
Не корысти ради, не в целях наживы, а во исполнение велений души!
Go to the top of the page
 
+Quote Post
fantasy
сообщение Jul 10 2006, 15:19
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 69
Регистрация: 17-09-05
Из: Kirov
Пользователь №: 8 659



Внесу свою реплику в дискуссию...

Код
#define _fDreb 5 //защита от дребезга (0.05 сек.)
#define _fRepite 39 //время первого автоповтора (0.4 сек.)
#define _nRepite 10 //время второго и последующего автоповтора (0.1 сек.)

//уровни напряжений для кнопок (_minKey1 > _minKey2 > _minKey3 > _minKey4)
#define _minKey1 ... //минимальный уровень напряжения для кнопки 1
#define _minKey2 ... //минимальный уровень напряжения для кнопки 2
#define _minKey3 ... //минимальный уровень напряжения для кнопки 3
#define _minKey4 ... //минимальный уровень напряжения для кнопки 4
    
unsigned int ADCresult;
unsigned char newHKey, oldHKey, drebCount;
unsigned char _key;

    ADCresult = ...;   //данные с АЦП
    
    //... вызывается с частотой ~100 Гц
    newHKey = 0;
    if(ADCresult>=_minKey1)
    {
newHKey = 0x01; //key1
    }
    else if(ADCresult>=_minKey2)
    {
newHKey = 0x02; //key2
    }
    else if(ADCresult>=_minKey3)
    {
newHKey = 0x04; //key3
    }
    else
    {
newHKey = 0x08; //key4
    };
    if((oldHKey!=newHKey)||(newHKey==0x0))
    {
_key = false;
drebCount = _fDreb;
    }
    else
    {
if((--drebCount)==0)
{
     //расшифровываем нажатие на кнопки
     if(newHKey&0x01)key1=true;
     if(newHKey&0x02)key2=true;
     if(newHKey&0x04)key3=true;
     if(newHKey&0x08)key4=true;
     drebCount = _fRepite;  //предполагаем повторное нажатие
     if(_key==false)drebCount = _nRepite; //устанавливаем ожидание 1-го нажатия
     _key = true;
};
    };
    oldHKey = newHKey;


--------------------
В голове слышался грохот: рушились грандиозные планы...
Go to the top of the page
 
+Quote Post
Labinskiy Nikola...
сообщение Jul 10 2006, 16:36
Сообщение #17


Участник
*

Группа: Новичок
Сообщений: 27
Регистрация: 5-07-06
Из: Украина, Донецк
Пользователь №: 18 606



Всем спасибо за ответы - пойду экспериментировтаь wink.gif


--------------------
If you can't make it good - don't make it look good ;)
Go to the top of the page
 
+Quote Post
dio
сообщение Jul 19 2006, 17:58
Сообщение #18


Участник
*

Группа: Новичок
Сообщений: 40
Регистрация: 4-06-06
Пользователь №: 17 766



Понимаю что вопрос тупой, но всё таки ...
Упростил пример до невозможного, а он опять не работает blink.gif


Цитата
int main( void )
{
byte t1,t2;
DDRB=0x0F; // b0-b3 : outputs b4-b7 : inputs
DDRD=0xFF; // d0-d7 output

PORTB=0x01;;
for(;;)
{
__delay_cycles(160000); // Пихните куда надо
t1=PORTB;
t2=0x10;
t1=t1 & t2;

if (t1==t2) PORTD=0xFF;
else PORTD=0x00;
}
}


Хочу чтоб загорелся диод на PORTD после нажатия клав. "1" на 4x4 клавиатуре.
Помогите плииииис !!!
sad.gif

п.с. Не ругайте снльно.
rolleyes.gif
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 10 2010, 17:48
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



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


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Feb 11 2010, 09:23
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



Как-то уже приводил здесь этот код.

Код
unsigned long int debounced_state = 0,debounced_stateOld = 0;
unsigned long int A = 0x0;
unsigned long int B = 0x0;
unsigned long int C = 0x0;

void debounce(unsigned long int new_sample)
{
    unsigned long int delta;

    delta = new_sample ^ debounced_state;   //Find all of the changes

/*  clock_A ^= clock_B;                     //Increment the counters
  clock_B  = ~clock_B;*/

    A  = A^(B&C);
    B  = B^C;
//    C  = ~C;

    A &= delta;                       //Reset the counters if no changes
    B &= delta;                       //were detected.
//    C &= delta;

    //Preserve the state of those bits that are being filtered and simultaneously
    //clear the states of those bits that are already filtered.
    debounced_state &= (A|B|C);
    //Re-write the bits that are already filtered.
    debounced_state |= (~(A|B|C) & new_sample);
}
Go to the top of the page
 
+Quote Post
Lexdaw
сообщение Feb 11 2010, 13:24
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 87
Регистрация: 5-02-08
Пользователь №: 34 772



А я по опросу входа (кнопки) сдвигаю регистр влево/вправо, до заполнения указателя нулями/единицами.Этакий стрелочный прибор получается.
Go to the top of the page
 
+Quote Post
Corvus
сообщение Feb 11 2010, 13:47
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 24-04-08
Из: Зеленоград
Пользователь №: 37 056



А простой инкремент/декремент чем не угодил? rolleyes.gif
Go to the top of the page
 
+Quote Post
Marian
сообщение Feb 11 2010, 13:49
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 23-02-07
Пользователь №: 25 618



Цитата(smk @ Feb 10 2010, 19:48) *
Как выяснилось в моем случае, полезно обеспечивать не только устранение дребезга, но и время нечувствительности к повторному нажатию. Иначе сканировать и отрабатывать будет успевать быстрее чем поймет оператор что он нанажимал.

Или следить, когда кнопку отпустили.
Для схемы с одной кнопкой делал типа :

Код
#define Knopka PIND.3
// Knopka podl na PD 3 , vtoraja noga na zemlu
// v portu vklucit podtiagivajushchij rezistor, ili postavit vneshnij k +5 V
// jesli knopka nazata, to "Knopka " budet ravna 0

unsigned char ButtonDownTime(void)
// return TimeLong if long, and TimeShort if short time
{
   unsigned char i;
   while ( Knopka == 1);  
   for(i=0;i<7;i++)
   {
      delay_ms(50);      // zadierzka od drebiezga kontaktow
      if (Knopka == 1)   // odpuscili knopku
      {
         return TimeShort;//short
         goto MEnd; // vyhod s cikla
      }
   }    
   return TimeLong;//long
MEnd:  
}

void WaitButtonUp(void)
{                        
   while (Knopka == 0);
   delay_ms(50);
}

// vyzyvat primerno tak
if (Knopka == 0) //Pervoje nazatije, vhod v menu
{
    WaitButtonUp(); // zhdem otpuskanija knopki
    if (ButtonDownTime() == TimeShort)
   {
      //naprimer uvelichit peremennuju HD++;
      WaitButtonUp();
    }
   else //if (ButtonDownTime() == TimeShort)
  {          
     // perehod na sledushchij punkt menu
  }
}
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 11 2010, 15:53
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(smk @ Feb 10 2010, 22:48) *
Иначе сканировать и отрабатывать будет успевать быстрее чем поймет оператор что он нанажимал.
Что-то не то в таком утверждении. cranky.gif То ли вы дребезг не полностью устраняете, то ли оператора каким-то дураком представить пытаетесь.
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 11 2010, 17:08
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Нет, просто события внутри микроконтроллера опережают реакцию оператора. Ну например, сделайте счетчик с отображением на индикаторе. Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10. Компьютерная клава тому яркий пример - скорость выдачи при удержании кнопки ограничена.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Feb 11 2010, 17:17
Сообщение #26


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(smk @ Feb 11 2010, 21:08) *
Нет, просто события внутри микроконтроллера опережают реакцию оператора. Ну например, сделайте счетчик с отображением на индикаторе. Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10. Компьютерная клава тому яркий пример - скорость выдачи при удержании кнопки ограничена.

Естественно, необходимо кроме антидребезга вводить ещё паузу и период автоповтора.
Никто не сомневается, что контроллер может считать быстрее человека biggrin.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 11 2010, 17:25
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(smk @ Feb 11 2010, 22:08) *
Нет, просто события внутри микроконтроллера опережают реакцию оператора. Ну например, сделайте счетчик с отображением на индикаторе. Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10.
Извините, но это дурдом какой-то. wacko.gif Переменная открытая для редактирования не может изменяться до окончания процесса редактирования. У вас явно что-то не то в консерваториях. cranky.gif
Цитата(smk @ Feb 11 2010, 22:08) *
Компьютерная клава тому яркий пример - скорость выдачи при удержании кнопки ограничена.
Ну и какой вы делаете из этого вывод? Все верно в компьютерных клавах сделано, я лично на точно таких же принципах реализую клавиатуру в приборах. Задержка перед началом повтора и паузы между выдачей кодов повторного нажатия. Параметры задержки и паузы настраиваемые. Причем повтор обычно разрешен не для всех кнопок, а только для клавиш "навигации": вправо-влево-вверх-вниз.
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Feb 11 2010, 19:27
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



Товарищ смешивает две задачи, устранения дребезга и частота автоповтора. Для первой задачи я применяю код, приведённый выше, для второй таймер. При поступлении события от таймера, в основном цикле применяю значение, которое даёт антидребезговый код.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 11 2010, 21:31
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Oleg_IT @ Feb 12 2010, 00:27) *
Товарищ смешивает две задачи, устранения дребезга и частота автоповтора.
Может это я не совсем понимаю или неправильно понимаю суть написанного smk? smile.gif
Поясняю для самого общего случая.
Процедура устранения дребезга требуется для ликвидации недостатков аппаратуры. Единичное нажатие клавиши пользователем аппаратура должна четко определить именно как единичное, а не как 2 или 52 или 152 нажатия. Все! Никаких ограничений на частоту нажатий эта процедура оказывать не должна. Ограничения возникают чисто физиологические. Человек физически не способен нажимать клавиши чаще чем, скажем, 100 раз в секунду. И осмысленно с такой скоростью нажимать их, тем более не способен.
- Я способна набирать 1200 символов в минуту!
- Ну и как, получается?
- Вы знаете, если честно, такая фигня выходит.
(из анекдота) smile.gif
В реальности процедура устранения дребезга конечно тоже налагает ограничение на темп нажатий сверху. Типовое время дребезга механических контактов кнопок составляет порядка 10мс. Если устранение дебезга построено на периодическом опросе, то сверху ограничение в те же 100 нажатий в секунду выходит. Но если клавиатура способна 100 нажатий/с обеспечить, то она обязана их обеспечивать без каких-либо других ограничений.
Теперь про автоповтор. Автоповтор это "фича" клавиатуры, дополнительное удобство т.с. Автоповтор имитирует многократное нажатие пользователем одной и той же клавиши. Но раз он только имитирует действия пользователя (а пользователи-то все разные), то следовательно автоповтор должен иметь настраиваемые или даже (само)адаптируемые параметры. Пример самоадаптируемого изменения скорости автоповтора можно привести на базе паяльной станции с цифровой регулировкой температуры. Одиночные нажатия изменяют регулировку температуры на 1°C. Автоповтор вначале имитирует такую же ступень изменения (на 1°C). Но если удерживать клавишу дольше и изменение произойдет более чем на 10°C, то шаг приращения температуры автоматически увеличивается до 10°C. Впрочем это я немного отвлекся. Суть-то в том, что автоповтор это имитация действий пользователя. Для его (пользователя) удобства. А ведь пользователи все разные, кто-то реально по 20 раз/с способен нажимать кнопки, а кто-то "с ограниченными возможностями" нажимает кнопки локтем (калека) или физически не способен на быстрые движения (старик или с отклонениями в психическом развитии). Соответственно для каждого из них нужны разные задержки для включения функции автоповтора и разный темп имитации нажатий. Если у функции автоповтора есть возможности подстройки этих параметров, то я не представляю ситуации, когда
Цитата("smk")
Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10.
laughing.gif Вот где мое недоумение/непонимание возникло.
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 11 2010, 23:02
Сообщение #30


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Stas633 @ Jul 10 2006, 09:45) *
Интересно, каким же алгоритмом пользуются производители автомагнитол?

Не знаю как производители магнитол, а я пользуюсь алгоритмом откладывания события:
Код
const PROGMEM U8 transTab[] =
{
    200, 167, 125, 99, 83, 71, 61, 55,
    49, 44, 40, 37, 35, 32, 30, 28
};

// это задачка, которая запускается с периодом 5ms
// сканирует АЦП канал, и преобразует показания АЦП в индекс от 0x0 до 0xF,
// индекс представляет собой код, где каждый бит соответствует одной нажатой кнопке.
void kbr_ScanTask(void)
{
    U8 val = kbr_AdcChanRead( kbrContext.AdcChan );
    U8 i;
    U8 NewStatus = 0;

    for(i = 0; i < sizeof(transTab); i++)
    {
        if (val > pgm_read_byte_near( transTab +  i ))
        {
            NewStatus = i;
            break;
        }
    }

    if (NewStatus != kbrContext.status)
    {
        kbrContext.status = NewStatus;
        if (NULL != kbrContext.StatusChange_CB)
        { // register keyboard status change handler to be executed after 50 ms (to filter out all false events)
            Kernel_SetTask( kbrContext.StatusChange_CB, 50, TASK_RUN_ONCE );
        }
    }
}


И при изменении статуса клавиатуры (в данном случае 4 кнопки на 1 канал АЦП), сканирующая задачка ставит в очередь на исполнение через __50ms__ "Keyboard Status Change event". За эти 50ms задача сканирует канал АЦП еще 10 раз (т.к. она выполяется раз в 5ms) и если статус будет изменяться (дребезг), то запуск event'a будет откладываться. Когда состояние АЦП установится - т.е. на протяжении 10 следующих подряд сканирований состояние не изменится, event таки отработает.


Это есть, одна из возможных, реализация "Интервального" алгоритма, упомянутого resident'ом
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 12 2010, 05:56
Сообщение #31


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Corvus @ Feb 11 2010, 15:47) *
А простой инкремент/декремент чем не угодил? rolleyes.gif

Если Вы о коде Oleg IT - то вдумайтесь просто в этот код :-)
Там на трёх 32-битных переменных реализовано тридцать два 3-битовых счётчика и они все инкрементируются одновремённо теми несколькими операторами.
vertical counters называется.

Да ещё и переносы счётчиков авоматически все сгруппированы в одно 32-битное слово "напротив соответствующих им кнопок".
Да ещё и сбрасываются счётчики кнопок, у которых значение не установилось, также "коротким движением руки" и без горсти if.

По другому, "простым инкрементом" это так компактно и быстро не выйдет.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 12 2010, 06:58
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
я лично на точно таких же принципах

о чем тогда речь?

на счет автоповторов. единичное нажатие регистрируется как единичное нажатие и приводит к некоторому действию. Действие происходит быстро. Если скорость повторения действий при нажатой кнопке не ограничивать, то в следствие частого опроса клавиатуры рискуем произ0вести несколько действий за одно нажатие (это мы думаем, что оно одно, а программа видит нажатую кнопку и действует как и положено). Вы вероятно имели ввиду, что одно нажатие должно приводить к одному действию? Это правильно, но на мой взгляд код компактнее если регулировать этот вопрос через "зону нечувствительности". Одним выстрелом два зайца - одно действие за одно нажатие и переход в автоповтор.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
muravei
сообщение Feb 12 2010, 08:18
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 2 538
Регистрация: 13-08-05
Пользователь №: 7 591



Цитата(smk @ Feb 12 2010, 09:58) *
в следствие частого опроса клавиатуры рискуем произ0вести несколько действий за одно нажатие

Чтобы так сильно не рисковать smile.gif стоит проверять не только нажатие , но и отпускание (с той же борьбой с дребезгом)
Go to the top of the page
 
+Quote Post
Corvus
сообщение Feb 12 2010, 09:09
Сообщение #34


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 24-04-08
Из: Зеленоград
Пользователь №: 37 056



Цитата(ReAl @ Feb 12 2010, 08:56) *
Если Вы о коде Oleg IT

Нет, я про сообщение Lexdaw.
А пример Oleg IT интересный.
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 12 2010, 09:30
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Код
Чтобы так сильно не рисковать  стоит проверять не только нажатие , но и отпускание (с той же борьбой с дребезгом)

Это верно, но в моем случае удобней так как я сделал.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
andr_doy
сообщение Feb 12 2010, 09:50
Сообщение #36


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 12-09-06
Пользователь №: 20 300



давно и с большим успехом пользую следущий код
//.............................................................................
static unsigned char debounce_sw_left(void)
{
static uint16_t state2 = 0; //holds present state
state2 = (state2 << 1) | (! bit_is_clear(PORT_LEFT, PIN_LEFT)) | 0xE000;
if (state2 == 0xF000) return 1;
if (state2 == 0xE000) return 2;
return 0;
}
//.............................................................................
сдесь и подавление дребезга как на нажатие так и на отпускание

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

если будем анализировать код возврата 1 то получим кнопку с действием нажал и пока не отпустил
а если код возврата 2 то кнопка с автоповтором

у меня вызывается с по таймеру в 1 мс при том в конкретном прерывании сканируем только одну кнопку

если их к примеру 8 то все кнопки будут опрошены за 8мс

работает настолько все четко я даже сам удивляюсь
попробуйте
Go to the top of the page
 
+Quote Post
sonycman
сообщение Feb 12 2010, 13:42
Сообщение #37


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(ReAl @ Feb 12 2010, 09:56) *
Да ещё и переносы счётчиков авоматически все сгруппированы в одно 32-битное слово "напротив соответствующих им кнопок".
Да ещё и сбрасываются счётчики кнопок, у которых значение не установилось, также "коротким движением руки" и без горсти if.

По другому, "простым инкрементом" это так компактно и быстро не выйдет.

А счёт там идёт до скольки? До 8?
Через сколько вызовов функции получим валидное значение в debounced_state?
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 12 2010, 14:26
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(smk @ Feb 12 2010, 11:58) *
Действие происходит быстро. Если скорость повторения действий при нажатой кнопке не ограничивать, то в следствие частого опроса клавиатуры рискуем произ0вести несколько действий за одно нажатие (это мы думаем, что оно одно, а программа видит нажатую кнопку и действует как и положено).
Это проблема вовсе не клавиатуры, а UI (User Interface - пользовательский интерфейс) и к клавиатуре она не имеет непосредственного отношения.
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 07:46
Рейтинг@Mail.ru


Страница сгенерированна за 0.01755 секунд с 7
ELECTRONIX ©2004-2016