Опрос кнопок микроконтроллером
Re: Помогите опросить кнопку
а какого номинала резисторы внутренней подтяжки у AVR ?
Tell Me The Truth
Re: Помогите опросить кнопку
вроде бы 50-100к
на плате без разговоров этого обычно достаточно, но если помеховая обстановка тяжелая или провода идут дальше или вообще шлейфом уходят с платы, то без раздумий нужно вешать внешнюю подтяжку, да посильнее, например 4,7 - 10к
У меня был случай прикольный:
Я тоже в своем устройстве использовал внутреннюю подтяжку, кнопка всего в 5-ти см от контроллера, кнопка использовалась для программирования устройства, все всегда нормально было, но как то раз...
На этом объекте другая фирма смонтировала рекламный щит, при этом поленились крепить свою коробку для коммутации питания щита, и взяли и засунули всю коммутацию в нашу коробку...
Далее в течение какого то времени нас периодически вызывали по поводу отказа нашего блока... всякий раз оказывалось что блок запрограммирован на несоответствующие функции, его тут же настраивали правильно и на какое то время все было ОК... но потом все повторялось...
Так было до тех пор пока я лично не приехал на объект... я конечно удивился куче проводов в нашей коробке, но не придал этому особого значения... и тут....... прям на моих глазах, блок самолично вошел в режим настроек..... и начал скакать туда сюда... я сначала потерял на время дар речи... но потом сообразил, что это - 10А импульсный блок питания, который стоит рядом, а его силовая проводка проходящая прям под контроллерной платой - так колбасят линию кнопки, что и даже программный антидребезг не помогает отсеть такие наводки...
После освобождения нашей коробки от лишних проводов, мы про этот объект постепенно забыли.....
на плате без разговоров этого обычно достаточно, но если помеховая обстановка тяжелая или провода идут дальше или вообще шлейфом уходят с платы, то без раздумий нужно вешать внешнюю подтяжку, да посильнее, например 4,7 - 10к
У меня был случай прикольный:
Я тоже в своем устройстве использовал внутреннюю подтяжку, кнопка всего в 5-ти см от контроллера, кнопка использовалась для программирования устройства, все всегда нормально было, но как то раз...
На этом объекте другая фирма смонтировала рекламный щит, при этом поленились крепить свою коробку для коммутации питания щита, и взяли и засунули всю коммутацию в нашу коробку...
Далее в течение какого то времени нас периодически вызывали по поводу отказа нашего блока... всякий раз оказывалось что блок запрограммирован на несоответствующие функции, его тут же настраивали правильно и на какое то время все было ОК... но потом все повторялось...
Так было до тех пор пока я лично не приехал на объект... я конечно удивился куче проводов в нашей коробке, но не придал этому особого значения... и тут....... прям на моих глазах, блок самолично вошел в режим настроек..... и начал скакать туда сюда... я сначала потерял на время дар речи... но потом сообразил, что это - 10А импульсный блок питания, который стоит рядом, а его силовая проводка проходящая прям под контроллерной платой - так колбасят линию кнопки, что и даже программный антидребезг не помогает отсеть такие наводки...
После освобождения нашей коробки от лишних проводов, мы про этот объект постепенно забыли.....
Re: Помогите опросить кнопку
shads писал(а):вроде бы 50-100к
нашол все-таки
ATmega8
выходит чем больше сопротивление резистора подтяжки тем сильнее он ловит всякие помехи ?
Tell Me The Truth
Re: Помогите опросить кнопку
Естественно...FreshMan писал(а):выходит чем больше сопротивление резистора подтяжки тем сильнее он ловит всякие помехи ?
Только не резистор ловит помехи, а вход контроллера...
При бесконечном сопротивлении подтяжки - вход вообще будет работать как антенна )))
Re: Помогите опросить кнопку
тогда я вот что не возьму в толк: почему специ из AVR поставили подтягивающий резистор номиналом в 20-50кОм ?
почему бы не поставить 4,7кОм ?
они что о подобного рода проблемах не ведали ?
навряд......
почему бы не поставить 4,7кОм ?
они что о подобного рода проблемах не ведали ?
навряд......
Tell Me The Truth
- Oxford
- Опытный кот
- Сообщения: 819
- Зарегистрирован: Вт окт 23, 2012 13:17:25
- Откуда: Прокопьевск
- Контактная информация:
Re: Помогите опросить кнопку
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Re: Помогите опросить кнопку
Ну просто всему есть разумные пределы... А то можно и продолжить тему, почему они например не сделали внутренний отключаемый последовательный резистор? чтобы можно было сразу светодиод вешать???FreshMan писал(а):тогда я вот что не возьму в толк: почему специ из AVR поставили подтягивающий резистор номиналом в 20-50кОм ?
почему бы не поставить 4,7кОм ?
Их разработчики вроде не кулибины самоучки, а высококлассные инженеры, наверное уж просчитали что востребовано, что не востребовано, что допустимо, что позводлительно, чтобы вписаться в рамки потребления, цены, размеров и т.д. и т.п.
Ну а у нас, простых кулибинов, как всегда - сколько людей столько и мнений)))
Радуйтесь, что хоть такой резистор есть, хуже было бы если бы они его вообще не реализовали... для многих задач его хватает, ну а если вам нужно выжимать максимумы, тут уж будьте добры навешивайте то что вам необходимо - резисторы, силовые ключи или что там еще может пригодится...
Кстати а вы знаете о такого рода проблеме как энергосбережение??? есть же много батарейных устройств... представьте что конкуренты ставят 50к резисторы, а вы поставили 4к7... так вот теперь когда вы будете нажимать на кнопочку своего устройства, ваша батареечка будет садится в 10 раз быстрее чем у конкурентов!!!!! как вам такие перспективы?FreshMan писал(а):они что о подобного рода проблемах не ведали ?
Посмотрел у STM8 - примерно та же песня...
- Вложения
-
- Безымянный.png
- (53.61 КБ) 2725 скачиваний
Интервал нажатия кнопки.
Всем доброго времени суток.
Подскажите пожалуйста начинающему, как реализовать программную обработку условия нажатой кнопки. К примеру, нажата кнопка ST1 - 1 сек, выполняем функцию 1, если время вышло, функцию 2. . Заранее благодарен.
{
if(BUT2==1)// если отжата кнопка BUT2
delay_ms(50);
OUT6=0; // тушим левый
delay_ms(50);
OUT5=1; // зажигаем правый
}
else
{
if(ST1==0)//если нажали ST1
{
delay_ms(50);
OUT5=0; //тушим правый
delay_ms (300);
OUT5=1;
}
}
if(BUT2==0) // если нажата кнопка BUT1
{
if(BUT1==1) //если отжата but1
delay_ms(50);
OUT5=0; // тушим правый
if(BUT1==1)// если отжата кнопка BUT2
delay_ms(50);
OUT6=1; // зажигаем левый
}
else
{
if(ST2==0)//если нажали ST1
{
delay_ms(50);
OUT6=0; //тушим левый
delay_ms (300);
OUT6=1;
}
}
}
Подскажите пожалуйста начинающему, как реализовать программную обработку условия нажатой кнопки. К примеру, нажата кнопка ST1 - 1 сек, выполняем функцию 1, если время вышло, функцию 2. . Заранее благодарен.
Спойлер
if(BUT1==0) // если нажата кнопка BUT1{
if(BUT2==1)// если отжата кнопка BUT2
delay_ms(50);
OUT6=0; // тушим левый
delay_ms(50);
OUT5=1; // зажигаем правый
}
else
{
if(ST1==0)//если нажали ST1
{
delay_ms(50);
OUT5=0; //тушим правый
delay_ms (300);
OUT5=1;
}
}
if(BUT2==0) // если нажата кнопка BUT1
{
if(BUT1==1) //если отжата but1
delay_ms(50);
OUT5=0; // тушим правый
if(BUT1==1)// если отжата кнопка BUT2
delay_ms(50);
OUT6=1; // зажигаем левый
}
else
{
if(ST2==0)//если нажали ST1
{
delay_ms(50);
OUT6=0; //тушим левый
delay_ms (300);
OUT6=1;
}
}
}
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Интервал нажатия кнопки.
тут посмотри
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Re: Интервал нажатия кнопки.
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3332308#p3332308"]тут посмотри[/uquote]
Спасибо. Так как я начинающий, очень с трудом дался вариант со сбросом счетчика после выполнения условия. Для одной кнопки.Но не смог я сделать это для двух кнопок. Мне бы кусок кода глянуть. Пробовал таким методом.
{
if(counter!=255)counter++; //начинаем счет
OUT4=1;
delay_ms(150); //Мигаем индикатором нога №3
OUT4=0;
if(counter==LONGKEY) //Если длительное по длительности нажатие
{
if(OUT1)OUT1=0; else OUT1=1;eep_1=OUT1; //Включаем, запоминаем PORTB.1 нога №6
}
}
else // иначе
{
if(counter>=1) //если был начат счет
{
if(counter<midkey) // и это короткое по длительности нажатие
{
if(OUT2)OUT2=0;else OUT2=1;eep_2=OUT2; //Включаем, запоминаем PORTB.2 нога №7
}
else
{
if(counter<longkey) //среднее по длительности нажатие
{
if(OUT3)OUT3=0;else OUT3=1;eep_3=OUT3; //Включаем, запоминаем PORTB.3 нога №2
}
}
}
counter=0; //Сброс подсчитанного
}
}
Спасибо. Так как я начинающий, очень с трудом дался вариант со сбросом счетчика после выполнения условия. Для одной кнопки.Но не смог я сделать это для двух кнопок. Мне бы кусок кода глянуть. Пробовал таким методом.
Спойлер
if(KEY==0) // если нажата кнопка{
if(counter!=255)counter++; //начинаем счет
OUT4=1;
delay_ms(150); //Мигаем индикатором нога №3
OUT4=0;
if(counter==LONGKEY) //Если длительное по длительности нажатие
{
if(OUT1)OUT1=0; else OUT1=1;eep_1=OUT1; //Включаем, запоминаем PORTB.1 нога №6
}
}
else // иначе
{
if(counter>=1) //если был начат счет
{
if(counter<midkey) // и это короткое по длительности нажатие
{
if(OUT2)OUT2=0;else OUT2=1;eep_2=OUT2; //Включаем, запоминаем PORTB.2 нога №7
}
else
{
if(counter<longkey) //среднее по длительности нажатие
{
if(OUT3)OUT3=0;else OUT3=1;eep_3=OUT3; //Включаем, запоминаем PORTB.3 нога №2
}
}
}
counter=0; //Сброс подсчитанного
}
}
Re: Помогите опросить кнопку
Голову готов расшибить себе... Подскажите пожалуйста где ошибка? Код с этого топика. Работает только на короткое нажатие.
- Вложения
-
- butt1.rar
- (62.64 КБ) 517 скачиваний
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Помогите опросить кнопку
А где в коде обработка события длинного нажатия ?
Re: Помогите опросить кнопку
[uquote="Аlex",url="/forum/viewtopic.php?p=3333146#p3333146"]А где в коде обработка события длинного нажатия ?[/uquote]
Спасибо за столь быстрый ответ. Я поудалял все, за сутки этих пробных версий ведро написал
( Вот теперь думаю в самой инициализации ошибки допустил.
Спасибо за столь быстрый ответ. Я поудалял все, за сутки этих пробных версий ведро написал
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: Помогите опросить кнопку
Спойлер
//Chip type : ATtiny13//Clock frequency : 9,600000 MHz
#include <tiny13.h>
#include <delay.h>
bit oldButton, Button;
unsigned char timeout;
void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Port B initialization
PORTB=0x01;
DDRB=0x18;
// Clock value: Timer 0 Stopped
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
Button= PINB.0; // считываем состояние кнопки
while (1)
{
delay_ms(10); // задержка 10 мсек
oldButton= Button; // предыдущее состояние кнопки
Button= PINB.0; // текущее состояние кнопки
if(oldButton && !Button) timeout= 100; // взводим таймаут на 1 сек при нажатии кнопки
if(!oldButton && !Button && timeout) --timeout; // уменьшаем таймаут при удержании кнопки
if(!oldButton && Button) // если кнопка отжата
{
if(timeout) PORTB^= 0x08; // если прошло менее 1 сек, то инвертируем выход РВ3
else PORTB^= 0x10; // если прошло более 1 сек, то инвертируем выход РВ4
}
};
}
Docendo discimus
Re: Помогите опросить кнопку
pyzhman Спасибо огромное! 

- Мокренькая кисонька
- Открыл глаза
- Сообщения: 59
- Зарегистрирован: Вт сен 27, 2011 07:28:44
- Откуда: Москва
- Контактная информация:
Re: Обработка нажатия кнопки в AVR...
Господа, помогите разобраться, третий день мучаюсь.
Имеется три кнопки и три светодиода контрольных. Дребезг победил, но проблема в том, когда держишь одну кнопку нажатой (допустим первую), то любой другой кнопкой можно выполнить действие для первой кнопки, при этом действие прописанное для самой этой кнопки, которую нажимаешь к уже нажатой не выполняется. Сумбурно, но вроде понятно.
Имеется три кнопки и три светодиода контрольных. Дребезг победил, но проблема в том, когда держишь одну кнопку нажатой (допустим первую), то любой другой кнопкой можно выполнить действие для первой кнопки, при этом действие прописанное для самой этой кнопки, которую нажимаешь к уже нажатой не выполняется. Сумбурно, но вроде понятно.
Спойлер
Код: Выделить всё
#include <avr/io.h> /* Device specific include file */
#include "hd44780.h" /* EZ-LCD include file (библиотека по японской технологии) */
#include <util/delay.h> //Delay library
#include <avr/interrupt.h> //Interrupt library
//#include "xprintf.h"
//#include <avr/pgmspace.h>
//#include <stdio.h>
//#include <string.h>
//#include <avr/eeprom.h>
#define RED PD7
#define YELLOW PD6
#define GREEN PD5
#define BTN1 PD0
#define BTN2 PD1
#define BTN3 PD2
static volatile uint8_t divider, state=0, keys=0, btns=0, flags=0;
void toggle (uint8_t color)
{
if (~PIND&(1<<color))
{
PORTD|=(1<<color);
}
else
{
PORTD&=~(1<<color);
}
}
void buttons (void)
{
btns=~PIND; //читаем PIND в переменную и инвертируем прочитанное
btns=btns&((1<<BTN1)|(1<<BTN2)|(1<<BTN3)); //отсекаем лишние разряды, оставляем только кнопки
switch(btns)
{
case (1<<BTN1): //если нажата кнопка 1
if(~flags&(1<<BTN1)) //если флаг первой кнопки не установлен, то
{
flags|=(1<<BTN1); //устанавливаем флаг
toggle(RED); //что-то делаем
}
break; //и на выход
case (1<<BTN2): //если нажата кнопка 2
if(~flags&(1<<BTN2)) //если флаг второй кнопки не установлен, то
{
flags|=(1<<BTN2); //устанавливаем флаг
toggle(YELLOW); //что-то делаем
}
break; //и на выход
case (1<<BTN3): //если нажата кнопка 3
if (~flags&(1<<BTN3)) //если флаг третьей кнопки не установлен, то
{
flags|=(1<<BTN3); //устанавливаем флаг
toggle(GREEN); //что-то делаем
}
break; //и на выход
default: //если не нажата ни одна кнопка
flags=0; //сбрасываем все флаги
break; //и на выход
}
keys=0; //сбрасываем флаг разрешения опроса кнопок
}
/*void button (void)
{
if (~PIND&(1<<BTN1) && state==0) // если кнопка нажата и флаг не установлен, то
{
toggle(RED); // вызываем переключалку красного светодиода
//toggle(GREEN);
}
if (~PIND&(1<<BTN1)) // если кнопка нажата, то
{ state=1; } // устанавливаем флаг
else
{ state=0; } // если отпущена, то опускаем флаг
keys=0;
}
*/
ISR(TIMER0_OVF_vect) //прерывание по переполнению
{
divider++; //увеличиваем щоччик
if (divider==3) // 61Гц/3=20Гц (или 50 мс)
{
divider=0; //сбрасываем щоччик
keys=1; //устаналиваем флаг разрешения опроса кнопок
}
}
int main (void)
{
//Инициализация портов I/O
//PORTB это LCD порт, инициализируется в файле hd44780.c
//Ноги PB0 и PB1 свободны
ACSR|=(1<<ACD); //отключение компаратора
DDRD|=(1<<PD7)|(1<<PD6)|(1<<PD5); //ноги PD7, PD6, PD5 на выход
PORTD|=(1<<PD0)|(1<<PD1)|(1<<PD2); //подключение подтягивающих резисторов
//Инициализируем таймер для кнопок
TCCR0|=(1<<CS02)|(0<<CS01)|(1<<CS00); //таймер0 с предделителем 1024, т.е. 8000000/1042=7812,5Гц (или 128мс)
TCNT0=128; //значение щ0ччика 7812,5/128=61Гц (или 16мс)
TIMSK|=(1<<TOIE0); //разрешаем прерывание таймера0 по переполнению
//Баловство-приветствие
lcd_init(); /* Initialize LCD */
_delay_ms(200);
lcd_putc(0x56); //V
_delay_ms(200);
lcd_putc(0x41); //A
_delay_ms(200);
lcd_putc(0x44); //D
_delay_ms(200);
lcd_putc(0x45); //E
_delay_ms(200);
lcd_putc(0x47); //G
_delay_ms(200);
lcd_locate(1,3); //ставим курсор на вторую строку, 4-е знакоместо
lcd_putc(0x44); //D
_delay_ms(200);
lcd_putc(0x41); //A
_delay_ms(200);
lcd_putc(0x44); //D
_delay_ms(200);
lcd_putc(0x45); //E
_delay_ms(200);
lcd_putc(0x47); //G
_delay_ms(500);
lcd_locate(0,0); //почему-то нужен возврат на нулевую позицию, я х.з?
lcd_putc('\f'); //очистка экрана и возврат курсора "домой"
sei(); //сеем
while(1) //бесконечный цикл
{
if(keys==1) //если флаг разрешения опроса кнопок поднят, то
{
buttons(); //опрашиваем кнопки
}
}
}
ИзвЕните от слова - веник, ИзвИните от слова - вина.
Re: Обработка нажатия кнопки в AVR...
Необходим алгоритм для определения последней устойчивой КОМБИНАЦИИ нажатых/активных кнопок, а не "поштучное" оценивание каждой кнопы в отдельности.

Без схемотехники кноп затруднительно подсказать...

Без схемотехники кноп затруднительно подсказать...

- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Обработка нажатия кнопки в AVR...
по-моему, надо просто убрать все флаги и тупо выполнять в switch-е нужное действие по коду нажатой кнопки. в этом случае надо учитывать и комбинации нажатых кнопок. при необходимости после switch-а дожидаться отпускания кнопок.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Обработка нажатия кнопки в AVR...
Под ассемблером...
буфер статуса ЛВК получает значение при первом обнаружении какого-либо нажатия
при контроле антидребезга снова чтение
если комбинация совпала с предыдущей - исполняем
если иная - замена содержимого в буфере и повтор антидребезга
если ВСЕ сброшены - возврат в исходное состояние.
Ну а по завершении обработки цикл ожидания "полного отпускания".
Как под Си... ешшо не пробовал...

буфер статуса ЛВК получает значение при первом обнаружении какого-либо нажатия
при контроле антидребезга снова чтение
если комбинация совпала с предыдущей - исполняем
если иная - замена содержимого в буфере и повтор антидребезга
если ВСЕ сброшены - возврат в исходное состояние.
Ну а по завершении обработки цикл ожидания "полного отпускания".
Как под Си... ешшо не пробовал...
