Цитата:
Сообщение от OsDima
Конечно надо.
|
Вот кусок прошивки отвечающий за кнопки. Сделано на основе прошивки Андрея. Писал левой ногой, сильно не пинайте...
Код:
#include <EEPROM.h>
#define RES_KEY_FLAG_ 0x16 // Флаг первого запуска скетча
byte bytes[4];
//-----------------------------------------
//- входы(пины) ардуино -
//-----------------------------------------
const int RES_PIN = 5 ; // аналоговый вход(пин) для резестивных(рулевых) кнопок
//-----------------------------------------
//- переменные включения функций скетча -
//-----------------------------------------
boolean is_res_keys = false;
//-----------------------------------------
//- Новые переменные для кнопок
#define RES_BT_CNT 50 // макс кол-во кнопок
#define VOL_BT_CNT 2 // кол-во кнопок с автоповтором
#define RES_DT_MIN 5 // мин значение АЦП
#define RES_DT_MAX 1020 // макс значение АЦП
unsigned long res_key_wait_long = 600; // задержка длинного нажатия кнопки (ms)
unsigned int key_to_send = 0;
boolean res_key_hold = false;
//-----------------------------------------
//- Переменные для резистивных кнопок -
//-----------------------------------------
unsigned long res_dt = 0;
unsigned long res_dt_sum = 0;
#define RES_DT_COUNT 400 // Количество считываемых данных
#define RES_DT_SKIP_COUNT 100 // Количество данных, которые надо пропустить при нажатии
#define RES_DT_POINT 6 // Точность
int res_dt_n = 0;
unsigned long res_key = 0;
unsigned long res_key_old = 0;
unsigned long res_key_wait_next = 200; // задержка автоповтора (ms)
unsigned long res_key_wait_millis = 0;
unsigned long res_key_millis;
unsigned long res_key_array[RES_BT_CNT + 1][2];
unsigned int res_key_count = 0;
unsigned int res_key_delta = 3;
//-----------------------------------------
void setup() {
Serial.begin(115200);
res_key_millis = millis();
unsigned int first_run_key = EEPROM.read(0);
if ( first_run_key == RES_KEY_FLAG_ )
{
res_key_count = EEPROM.read(1);
//EEPROM.write(addr, val);
for(int i=0; i<res_key_count;i++)
{
res_key_array[i][0] = (EEPROM.read(i+2) * 256) + EEPROM.read(i+2+RES_BT_CNT) - res_key_delta; res_key_array[i][1] = res_key_array[i][0] + res_key_delta + res_key_delta;
}
}
for(int i=res_key_count; i<(RES_BT_CNT+1);i++)
{
res_key_array[i][0] = 0xFFFFFFFF; res_key_array[i][1] = 0xFFFFFFFF;
}
}
//-----------------------------------------
void loop() {
if (Serial.available() >= 1) // Проверяем наличие команд от компьютера
{
switch (Serial.read())
{
case 0x06: // включить передачу данных от резестивных кнопок
is_res_keys = true;
break;
case 0x86: // выключить передачу данных от резестивных кнопок
is_res_keys = false;
break;
}
}
if( is_res_keys ) res_keys(); // резистивные кнопки
// res_keys();
}
//----------------------------------------------------------------------------------
// Функция работы с резистивными кнопками
//----------------------------------------------------------------------------------
void res_keys()
{
{
res_dt = analogRead(RES_PIN); // прочитать данные АЦП
if( res_dt >= RES_DT_MIN && res_dt <= RES_DT_MAX )
{
res_dt_n++;
if( res_dt_n > RES_DT_SKIP_COUNT )
{
res_dt_sum += (res_dt << RES_DT_POINT);
if( res_dt_n == RES_DT_COUNT)
{
// res_key = (res_dt_sum / (RES_DT_COUNT - RES_DT_SKIP_COUNT));
res_key = (((((( res_dt_sum / (( RES_DT_COUNT - RES_DT_SKIP_COUNT ) + (2^(RES_DT_POINT-1)-1) ) >> (RES_DT_POINT-1)) + 1) >> 1) + 1)>> 1)); // + 1) >> 1;
res_dt_sum = 0; res_dt_n = 0;
}
}
}
else
{
res_dt_sum = 0; res_dt_n = 0; res_key = 0;
res_key_wait_millis = 0;
}
}
// обработка нажатия
int key_code = 0;
if (res_key != 0) // что-то нажато
{
key_code = keyCode(res_key);
if (key_code <= VOL_BT_CNT) // первые кнопки с автоповтором
{
if (res_key_old == res_key) // удержание кнопки
{
if (millis() - res_key_wait_millis > res_key_wait_next) // задержка автоповтора
{
sendKey(key_code);
res_key_wait_millis = millis();
}
}
else
{
sendKey(key_code);
res_key_wait_millis = millis();
res_key_old = res_key;
}
}
else // кнопки с долгим нажатием
{
if (res_key_old == res_key) // удержание кнопки
{
if (millis() - res_key_wait_millis > res_key_wait_long) // длинное нажатие
{
if (!res_key_hold)
{
sendKey(key_code+RES_BT_CNT);
res_key_wait_millis = millis();
res_key_hold = true;
}
}
}
else
{
key_to_send = key_code;
res_key_wait_millis = millis();
res_key_old = res_key;
}
}
}
else // ничего не нажато
{
res_key_old = 0;
if (key_to_send != 0 && !res_key_hold) sendKey(key_to_send);
res_key_hold = false;
key_to_send = 0;
}
}
void sendKey(int key_code)
{
bytes[0] = 0xAA; // преобразовать в 4-байта
bytes[1] = 0;
bytes[2] = RES_PIN;
bytes[3] = key_code;
Serial.write( bytes,4); // отправить прочитаное значение компьютеру
/*
Serial.write(bytes[3]+0x30); // отправить прочитаное значение компьютеру
Serial.print(" ");
Serial.print(res_key,DEC);
Serial.println("");
*/
}
unsigned int keyCode(unsigned long key_res)
{
int i = 0; boolean exit = false;
while( res_key_array[i][0] != 0xFFFFFFFF && (!exit) )
{ // проверяем новая ли кнопка
if( (res_key_array[i][0] <= key_res) && (key_res <= res_key_array[i][1]) ) exit = true; else i++;
}
if ( exit ) // кнопкка уже известная
{
return (i+1);
}
else { // кнопка новая
if ( res_key_count < RES_BT_CNT )
{
res_key_array[res_key_count][0] = key_res - res_key_delta;
res_key_array[res_key_count][1] = key_res + res_key_delta;
res_key_count++;
EEPROM.write(1, res_key_count); // Запоминаем количество кнопок
byte one_byte = key_res / 256;
EEPROM.write(res_key_count+1, one_byte ); // Запоминаем старший байт значения кнопки
one_byte = key_res - one_byte * 256;
EEPROM.write(res_key_count+1+RES_BT_CNT, one_byte ); // Запоминаем младший байт значения кнопки
EEPROM.write(0, RES_KEY_FLAG_);
return res_key_count;
}
else
{ // переполнение - больше кнопок не запоминаем
bytes[0] = 0xAA; // преобразовать в 4-байта
bytes[1] = 0xAA;
bytes[2] = (key_res & 0xFF00) >> 8;
bytes[3] = key_res & 0xFF;
Serial.write( bytes,4); // отправить прочитаное значение компьютеру
}
}
}
После заливки этого кода при первом включении, первые две нажатые кнопки будут с автоповтором (для регулировки громкости), остальные - обычные. Короткое нажатие работает на отпускание, длинное - по задержке в 600 мс.
Если надо переопределить кнопки для автоповтора - поменяйте значение RES_KEY_FLAG_ на любое другое число, и перезалейте прошивку. Если нужно больше двух кнопок с автоповтором - поменяйте значение VOL_BT_CNT.