Как по нажатию кнопки отправить ОДИН символ в COM-порт

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

Проблема следующая. Есть 3 кнопки, по нажатию которых отправляются символы в com-порт. Все это организовано в цикле loop. Но при нажатии на кнопку в зависимости от продолжительности нажатия в com порт отсылается большое кол-во повторений данного символа. Так вот как сделать так чтобы при нажатии отправлялся только 1 символ до следующего нажатия?

11
Offline
Зарегистрирован: 10.03.2012

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

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

 не понял... а когда отправлять тогда?) 

Я делал так:

 val1 = digitalRead(BUTTON1); 
if (val1 == LOW) { //когда кнопка нажата, тогда LOW 
digitalWrite(LED1, HIGH); //зажигаю светодиод для проверки 
Serial.print('1'); //отправка 1 в порт
} else { digitalWrite(LED1, LOW); 

 

step962
Offline
Зарегистрирован: 23.05.2011

ArcaN0id пишет:

 не понял... а когда отправлять тогда?) 

Я делал так:

 val1 = digitalRead(BUTTON1); 
if (val1 == LOW) { //когда кнопка нажата, тогда LOW 
digitalWrite(LED1, HIGH); //зажигаю светодиод для проверки 
Serial.print('1'); //отправка 1 в порт
} else { digitalWrite(LED1, LOW); 

А я бы изменил это дело так:

int oldstate1=HIGH;  // где-нибудь в разделе объявления глобальных переменных

val1 = digitalRead(BUTTON1); 
if (val1 == LOW  && oldstate1 != val1) { //когда кнопка только что нажата
  digitalWrite(LED1, HIGH); //зажигаю светодиод для проверки 
  Serial.print('1'); //отправка 1 в порт
}
else digitalWrite(LED1, LOW);
oldstate1 = val1;

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

При этом светодиод будет лишь кратковременно вспыхивать в момент нажатия кнопки. Но дописывать логику для правильной отработки светодиода как-то лениво. В конце-концов оставьте свой вариант для мигания диодом (выкинув отправку в Serial), а в моем варианте оставьте только отправку символа (выкинув управление диодом). Два сравнения подряд должны дать нужную логику работы.

11
Offline
Зарегистрирован: 10.03.2012

при инициализации

 int oldstate1=4; тут несуществующая кнопка, 

 

 

step962
Offline
Зарегистрирован: 23.05.2011

 А откуда вы "4" взяли? В переменной запоминается состояние кнопки (LOW/HIGH) для проверки в следующем цикле, а не какой-то номер.

А LOW/HIGH - это либо 0, либо 1:

// из файла hardware\arduino\cores\arduino\wiring.h:
#define HIGH 0x1
#define LOW  0x0

Но даже если... При первом же проходе цикла переменной будет присвоено значение, соответствующее состоянию кнопки. Так что максимум, чего можно ожидать - лишняя буква, отправленная по UART в момент запуска микроконтроллера.

Не хочется даже один лишний символ получать - поставьте в setup присвоение состояния кнопки этой переменной:

oldstate1=digitalRead(BUTTON1);

11
Offline
Зарегистрирован: 10.03.2012

У ТС условие проверять 3 кнопки. неужели надо ТРИ int (65т) для хранения единственно нужного нам номера нажатия последней кнопки?

В переменную byte пишем при выводе в порт , а перед выводом проверяем значение на соотстветствие. Поэтому 4.

 

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

11 пишет:

У ТС условие проверять 3 кнопки. неужели надо ТРИ int (65т) для хранения единственно нужного нам номера нажатия последней кнопки?

В переменную byte пишем при выводе в порт , а перед выводом проверяем значение на соотстветствие. Поэтому 4.

 

Че-то я все равно не въеду в Вашу логику))) можете кусок кода привести, может понятнее будет))

step962
Offline
Зарегистрирован: 23.05.2011

11 пишет:

У ТС условие проверять 3 кнопки. неужели надо ТРИ int (65т) для хранения единственно нужного нам номера нажатия последней кнопки?

В переменную byte пишем при выводе в порт , а перед выводом проверяем значение на соотстветствие. Поэтому 4.

 

Если я правильно понимаю, ТС хочет отправлять символ каждый раз (но без автоповторения) при нажатии кнопки. Поэтому мы не номер нажатой кнопки храним, а три разных состояния трех разных кнопок. Чтобы иметь возможность отследить момент нажатия любой из этих кнопок, отправить соответствующий символ и заблокировать отправку нового символа до момента отпускания нажатой кнопки.

Эти состояния можно хранить и в битах единственной переменной типа char (для 8 кнопок) или int (для 16). Но судя по вопросу, топикстартеру следует сначала разобраться с принципом, получить первый работоспособный вариант, а уж потом заниматься его оптимизацией (если он на радостях не забъет на это). 

Да, и вопрос "почему 4" мне тоже интересен.

ЗЫ: кажется въехал... При вашем способе проверки/блокировки одновременное нажатие двух кнопок 1+2 (или 1+3, 2+3, а также 1+2+3) будет давать все ту же пулеметную очередь из отправляемых символов. 

11
Offline
Зарегистрирован: 10.03.2012
int oldstate=4;  // где-нибудь в разделе 	 

	
if (digitalRead(BUTTON1)==LOW)
 { 
 if(oldstate!=1)
{
Serial.print('1'); 
oldstate=1;
}
}

if (digitalRead(BUTTON2)==LOW)
 { 
 if(oldstate!=2)
{
Serial.print('2'); 
oldstate=2;
}
}

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

естественно если ввести функцию возвражающую численное значение нажатой кнопки, то всё будет красиво и кратко.

 

 

11
Offline
Зарегистрирован: 10.03.2012

о множественном нажатии я не думал, 4 потомучто потом ТС напишет функцию с результатом нажатой кнопки и неизвестно какие значения функция будет выдавать :)

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

11 пишет:

int oldstate=4;  // где-нибудь в разделе 	 

	
if (digitalRead(BUTTON1)==LOW)
 { 
 if(oldstate!=1)
{
Serial.print('1'); 
oldstate=1;
}
}

if (digitalRead(BUTTON2)==LOW)
 { 
 if(oldstate!=2)
{
Serial.print('2'); 
oldstate=2;
}
}

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

естественно если ввести функцию возвражающую численное значение нажатой кнопки, то всё будет красиво и кратко.

 

работает, только если нажимать кнопки по очереди. Т.е. повторное нажатие на кнопку не срабатывает. Работает только по 1 разу. Ну это логично, при нажатии присваиваем 1, и второй раз условие не проходит... а как же на повторное нажатие сделать?

А глобальная задача, сделать тестирование на компе через Arduino. Т.е варианты ответов выбирать кнопками с ардуины. Отсюда появляется вероятность, что 2 подряд идущих вопроса, могут иметь правильный вариант ответа под кнопкой 1.

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

step962 пишет:

А я бы изменил это дело так:

int oldstate1=HIGH;  // где-нибудь в разделе объявления глобальных переменных

val1 = digitalRead(BUTTON1); 
if (val1 == LOW  && oldstate1 != val1) { //когда кнопка только что нажата
  digitalWrite(LED1, HIGH); //зажигаю светодиод для проверки 
  Serial.print('1'); //отправка 1 в порт
}
else digitalWrite(LED1, LOW);
oldstate1 = val1;

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

так тоже засылает кучу 1 в порт)

11
Offline
Зарегистрирован: 10.03.2012

ах, я не прочитал это у ТС.

Ну очень просто !!!

if (digitalRead(BUTTON1)==HIGH  &&  вторая && третья )

{

oldstate=4;

delay (100); //защита от дребезга 0,1 секунда может и мало, опытным путём , может и 10с нормально будет

}

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

зы наверное не нужно писать "==HIGH"

зыы и кнопки антивандальные сразу :)

step962
Offline
Зарегистрирован: 23.05.2011

ArcaN0id пишет:

так тоже засылает кучу 1 в порт)

Ну а это уже дребезг контактов проявляет себя.

Либо вводите в схему интегрирующие цепочки, либо эмулируйте антидребезг программно. Простейший вариант - поставить в loop задержку около 1/10 сек. Быстрее кнопки все равно никто давить не будет.

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

 Все заработало отлично!))) 11. step962 Огромное вам спасибо за помощь)))) выручили в работе с дипломом)))

Mastino
Offline
Зарегистрирован: 03.12.2011

ArcaN0id пишет:

 Все заработало отлично!))) 11. step962 Огромное вам спасибо за помощь)))) выручили в работе с дипломом)))

Сильный диплом, а специалист который его получить еще сильнее..

ArcaN0id
Offline
Зарегистрирован: 11.03.2012

Mastino пишет:

ArcaN0id пишет:

 Все заработало отлично!))) 11. step962 Огромное вам спасибо за помощь)))) выручили в работе с дипломом)))

Сильный диплом, а специалист который его получить еще сильнее..

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

Mastino
Offline
Зарегистрирован: 03.12.2011

ArcaN0id пишет:

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

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

Dreddlampard
Offline
Зарегистрирован: 13.03.2012

Привет. А кто-нибудь знает,как по нажатию кнопки с SD-карты передать один байт(символ) во флеш-память микронтроллера на Ардуино?))

step962
Offline
Зарегистрирован: 23.05.2011

 Никак - чтение/запись производится блоками 512 байт. И если при чтении еще можно поизгаляться, сохраняя считываемые байты в одну и ту же ячейку памяти, то уже записать один байт на карточку, не уничтожив остальные 511 байт блока, не удастся.

mixail844
Offline
Зарегистрирован: 30.04.2012

попробую ответить сразу на поставенный вопрос

есть функция Serial.flush(); 
 

loop()
{
while(!Serial.available());
int a=Serial.read();
Serial.flush();
}

поидее должен считаться только 1 байт.