буду благодарен за примеры
Примеры к абстрактным данным не пишутся.
мне казалось данные вполне неабстрактные
пример:
- Читаете первый принятый байт. Если он 0x5F или 0x6F - переходите к п 2, если нет - остаетесь на п.1
- Читаете следующий байт. Если он один из 33х команд - отмечаете кнопку как нажатую или отжатую в массиве. Если нет - ничего не делаете. В любом случае переход на п1
Вот и все. В коде это должно занять строчек 10, не более.
Читаешь сериал, пока не попадется 0x5F или 0x6F. Попалось - сохранил в переменную action, читаешь сериал дальше. Следующим байтом пойдёт сканкод. Т.е. если считал байт не равный 0x5F или 0x6F, но action уже 0x5F или 0x6F, то этот байт сохраняешь в keycode и начинаешь искать в массиве связные данные. Массив не 2x33, а 33x2.
Т.е. элемент 0 - это сканкод, элемент 1 - данные.
Итого имеешь action, keycode и данные. Сделал с ними что нужно, action занулил. Начинаешь все сначала.
вот что получилось дальше немного запутался как проверять содержимое массива правильно сравнивая какая кнопка нажата
unsigned char rx_bayt = 0;
unsigned char rx_count = 0;
unsigned char action = 0;
unsigned char keycode = 0;
byte buttons[33][2] = {{0x07,0x00},
{0x06,0x00},
{0x05,0x00},
{0x0F,0x00},
{0x0E,0x00},
{0x0D,0x00},
{0x17,0x00},
{0x16,0x00},
{0x15,0x00},
{0x1E,0x00},
{0x1F,0x00},
{0x1D,0x00},
{0x27,0x00},
{0x26,0x00},
{0x25,0x00},
{0x04,0x00},
{0x03,0x00},
{0x1C,0x00},
{0x24,0x00},
{0x23,0x00},
{0x0C,0x00},
{0x0B,0x00},
{0x14,0x00},
{0x13,0x00},
{0x1B,0x00},
{0x2F,0x00},
{0x2D,0x00},
{0x2E,0x00},
{0x36,0x00},
{0x2C,0x00},
{0x37,0x00},
{0x35,0x00},
{0x34,0x00}};
//---------------------------------------------------------------------------
void Rx_Decode()
{
rx_bayt = Serial1.read();
if(((rx_bayt == 0x5F) || (rx_bayt == 0x6F)) && rx_count == 0)//принимаем 1й байт
{
action = rx_bayt;
rx_count++;
}
else if(((rx_bayt != 0x5F) || (rx_bayt != 0x6F)) && rx_count == 1)//принимаем 2й байт
{
keycode = rx_bayt;
pars();
rx_count = 0;
}
}
//---------------------------------------------------------------------------
void pars()
{
switch(keycode)
{
//buttons[0][0] проверка нажатия 1й кнопки
case :
//действие 1
Serial.println("1 button ON");
break;
//buttons[1][0] проверка нажатия 2й кнопки
case :
//действие 2
Serial.println("2 button ON");
break;
//buttons[2][0] проверка нажатия 3й кнопки
case :
//действие 3
Serial.println("3 button ON");
break;
//buttons[3][0] проверка нажатия 4й кнопки
case :
//действие 4
Serial.println("4 button ON");
break;
}
}
//---------------------------------------------------------------------------
void setup()
{
Serial1.begin(9600);
Serial.begin(9600);
}
//---------------------------------------------------------------------------
void loop()
{
if (Serial1.available() > 0) Rx_Decode();
}
//---------------------------------------------------------------------------
прямо в условие проверки второго байта вставьте свой цикл по всем кодам из старого скетча в начале ветки
что то не до конца понял вашу мысль в том виде в каком он был он явно неподходит массив изменился. Вот но не пойму как правильно.
void Rx_Decode()
{
rx_bayt = Serial1.read();
if(((rx_bayt == 0x5F) || (rx_bayt == 0x6F)) && rx_count == 0)//принимаем 1й байт
{
action = rx_bayt;
rx_count++;
}
else if(((rx_bayt != 0x5F) || (rx_bayt != 0x6F)) && rx_count == 1)//принимаем 2й байт
{
keycode = rx_bayt;
for(byte i=0; i<33; i++)
{
if(buttons[i][0] == keycode)
{
if (action == 0x5F)//нажатие
{
buttons[i][1] = 1;
Serial.println("button ON ");
i = 33;
}
if (action == 0x6F)//отпускание
{
buttons[i][1] = 0;
Serial.println("button OFF ");
i = 33;
}
}//конец if(buttons[0][i] == data[1])
}//конец for(byte i=0; i<33; i++)
//pars();
rx_count = 0;
}
}
Зачем вы все скопировали?
Нужно просто проверить, есть ли в массиве такое значение
void Rx_Decode()
{
rx_bayt = Serial1.read();
if(((rx_bayt == 0x5F) || (rx_bayt == 0x6F)) && rx_count == 0)//принимаем 1й байт
{
action = rx_bayt;
rx_count++;
}
else if ( rx_count == 1) //принимаем 2й байт
{ bool test = false;
keycode = rx_bayt;
for(byte i=0; i<33; i++)
{ if(buttons[i][0] == keycode) test = true; }
if (test) {
// байт есть в массиве, обрабатываем команду
}
else { // байта в массиве нет, команда неверна, возвращаемся в начало
rx_count =0;
}
добавил это работает спасибо. А как выглядеть должен обработчик команды?
unsigned char rx_bayt = 0;
unsigned char rx_count = 0;
unsigned char action = 0;
unsigned char keycode = 0;
byte buttons[33][2] = {{0x07,0x00},
{0x06,0x00},
{0x05,0x00},
{0x0F,0x00},
{0x0E,0x00},
{0x0D,0x00},
{0x17,0x00},
{0x16,0x00},
{0x15,0x00},
{0x1E,0x00},
{0x1F,0x00},
{0x1D,0x00},
{0x27,0x00},
{0x26,0x00},
{0x25,0x00},
{0x04,0x00},
{0x03,0x00},
{0x1C,0x00},
{0x24,0x00},
{0x23,0x00},
{0x0C,0x00},
{0x0B,0x00},
{0x14,0x00},
{0x13,0x00},
{0x1B,0x00},
{0x2F,0x00},
{0x2D,0x00},
{0x2E,0x00},
{0x36,0x00},
{0x2C,0x00},
{0x37,0x00},
{0x35,0x00},
{0x34,0x00}};
//---------------------------------------------------------------------------
void Rx_Decode()
{
rx_bayt = Serial1.read();
if(((rx_bayt == 0x5F) || (rx_bayt == 0x6F)) && rx_count == 0)//принимаем 1й байт
{
action = rx_bayt;
rx_count++;
}
else if(((rx_bayt != 0x5F) || (rx_bayt != 0x6F)) && rx_count == 1)//принимаем 2й байт
{
bool test = false;
keycode = rx_bayt;
for(byte i=0; i<33; i++)
{
if(buttons[i][0] == keycode) test = true;
}
if (test)
{
// байт есть в массиве, обрабатываем команду
Serial.println("button OK");
}
else // байта в массиве нет, команда неверна, возвращаемся в начало
{
rx_count = 0;
}
}
}
//---------------------------------------------------------------------------
void setup()
{
Serial1.begin(9600);
Serial.begin(9600);
}
//---------------------------------------------------------------------------
void loop()
{
if (Serial1.available() > 0) Rx_Decode();
}
//---------------------------------------------------------------------------
Почитайте про оператор switch() - это как раз то что надо.
Вот что вышло
вывод в терминал
1 button ON
2 button ON
Мне кажется что то в кейсе я сделал неправильно. Или мне так кажется.
unsigned char rx_bayt = 0;
unsigned char rx_count = 0;
unsigned char action = 0;
unsigned char keycode = 0;
byte buttons[33][2] = {{0x07,0x00},
{0x06,0x00},
{0x05,0x00},
{0x0F,0x00},
{0x0E,0x00},
{0x0D,0x00},
{0x17,0x00},
{0x16,0x00},
{0x15,0x00},
{0x1E,0x00},
{0x1F,0x00},
{0x1D,0x00},
{0x27,0x00},
{0x26,0x00},
{0x25,0x00},
{0x04,0x00},
{0x03,0x00},
{0x1C,0x00},
{0x24,0x00},
{0x23,0x00},
{0x0C,0x00},
{0x0B,0x00},
{0x14,0x00},
{0x13,0x00},
{0x1B,0x00},
{0x2F,0x00},
{0x2D,0x00},
{0x2E,0x00},
{0x36,0x00},
{0x2C,0x00},
{0x37,0x00},
{0x35,0x00},
{0x34,0x00}};
//---------------------------------------------------------------------------
void Rx_Decode()
{
rx_bayt = Serial1.read();
if(((rx_bayt == 0x5F) || (rx_bayt == 0x6F)) && rx_count == 0)//принимаем 1й байт
{
action = rx_bayt;
rx_count++;
}
else if(((rx_bayt != 0x5F) || (rx_bayt != 0x6F)) && rx_count == 1)//принимаем 2й байт
{
bool test = false;
keycode = rx_bayt;
for(byte i=0; i<33; i++)
{
if(buttons[i][0] == keycode) test = true;
}
if (test)
{
// байт есть в массиве, обрабатываем команду
//Serial.println("button OK");
pars();
rx_count = 0;
}
else // байта в массиве нет, команда неверна, возвращаемся в начало
{
rx_count = 0;
}
}
}
//---------------------------------------------------------------------------
void pars()
{
unsigned char temp = 0;
for(byte i=0; i<33; i++)
{
if(buttons[i][0] == keycode)
{
if (action == 0x5F)//нажатие
{
buttons[i][1] = 1;
//Serial.print(i);
//Serial.println(" button ON ");
i = 33;
}
if (action == 0x6F)//отпускание
{
buttons[i][1] = 0;
//Serial.print(i);
//Serial.println(" button OFF ");
i = 33;
}
}//конец if(buttons[0][i] == data[1])
}//конец for(byte i=0; i<33; i++)
for(byte i=0; i<33; i++)
{
temp = buttons[i][1];
switch(i)
{
//проверка нажатия 1й кнопки
case 0:
//действие 1
//if(temp == 1){Serial.println("1 button ON");}else{Serial.println("1 button OFF");}
if(temp == 1){Serial.println("1 button ON");}
break;
//проверка нажатия 2й кнопки
case 1:
//действие 2
//if(temp == 1){Serial.println("2 button ON");}else{Serial.println("2 button OFF");}
if(temp == 1){Serial.println("2 button ON");}
break;
//проверка нажатия 3й кнопки
case 2:
//действие 3
//Serial.println("3 button ON");
break;
//проверка нажатия 4й кнопки
case 3:
//действие 4
//Serial.println("4 button ON");
break;
}
}//конец for(byte i=0; i<33; i++)
}
//---------------------------------------------------------------------------
void setup()
{
Serial1.begin(9600);
Serial.begin(9600);
}
//---------------------------------------------------------------------------
void loop()
{
if (Serial1.available() > 0) Rx_Decode();
}
//---------------------------------------------------------------------------
Массив с нулевыми значениями точно нужен?
Мне кажется вот в этой строке:
else if(((rx_bayt != 0x5F) || (rx_bayt != 0x6F)) && rx_count == 1)//принимаем 2й байт
Должно быть не логическое или, а логическое и:
else if(((rx_bayt != 0x5F) && (rx_bayt != 0x6F)) && rx_count == 1)//принимаем 2й байт
Потому что во втором байте не может быть ни 0x5F ни 0x6F. А может быть и вообще упростить до:
else if (rx_count == 1)//принимаем 2й байт
Но может случится такое, что вторым придёт 5F или 6F вследствие взрыва газа на Венере. Первое условие должно быть безусловно синхронизирующим.
Поскольку этих значений нет в массиве, то второе условие все равно не выполнится.
Так что явная проверка на
не нужна
Это так. Но работать будет чуть медленней.
Кстати, для “наглядности”, диапазон значений rx_count логичнее сдвинуть от 1 до 2 (а не 0…1 как сейчас)
const uint8_t kaNone = 0x00;
const uint8_t kaOn = '1';
const uint8_t kaOff = '0';
typedef struct {
uint8_t action;
uint8_t code;
} panelKey_t;
panelKey_t getPanelKey() {
static uint8_t action = kaNone;
panelKey_t result = {.action = kaNone, .code = 0x00};
int16_t reading = Serial.read();
// read() returns -1 on empty Serial buffer
if (0x00 <= reading) {
uint8_t currentByte = (byte) reading;
if (kaOn == currentByte || kaOff == currentByte) {
Serial.println("Action code catched");
action = currentByte;
} else {
if (kaNone != action) {
Serial.println("Key code catched");
result.action = action;
result.code = currentByte;
action = kaNone;
}
}
}
return result;
}
void setup() {
Serial.begin(9600);
}
void loop()
{
panelKey_t panelKey = getPanelKey();
if (kaNone != panelKey.action) {
Serial.print("Key data incoming: code="); Serial.print((char)panelKey.code);
Serial.print(", action="); Serial.println(kaOn == panelKey.action ? "ON": "OFF");
}
}