Обработчик нажатий клавиатуры по Serial (UART)

Доброго времени суток. Возникла нужда написать программу которая парсит нажатия клавиатуры устройства которое отдает данные о нажатых кнопках по UART. не найдя чего то похожего написал сам в меру своего понимания. Случился небольшой затык в обработчике состояния клавиатуры который будут брать состояние кнопок из массива. Прошу совета.

//=================================================================
String strData = "";
boolean recievedFlag;
//===============================================================================
byte buttons[2][33] = {{0x07,0x06,0x05,0x0F,0x0E,0x0D,0x17,0x16,0x15,0x1E,0x1F,0x1D,0x27,0x26,0x25,0x04,0x03,0x1C,0x24,0x23,0x0C,0x0B,0x14,0x13,0x1B,0x2F,0x2D,0x2E,0x36,0x2C,0x37,0x35,0x34},
                       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};

char data[2];
//=================================================================
void setup() 
{
   Serial1.begin(9600);
   Serial.begin(9600);
}
//=================================================================
void loop() 
{
  if(Serial1.available() > 0)// если есть что то на вход 
  {
    strData = "";  // очистить строку
    while (Serial1.available()>0)   // пока идут данные
    {
       strData += (char)Serial1.read();  // забиваем строку принятыми данными
       delay(2);                         // обязательно задержка, иначе вылетим из цикла раньше времени
    }
    recievedFlag = true;  // поднять флаг что получили данные
  }//конец if(Serial1.available() > 0)// если есть что то на вход 

  if(recievedFlag)   // если есть принятые данные
  {
    strData.toCharArray(data, 3);//записывает строку в массив – буфер buf (типа char []) с начала и до длины len.
    Serial.print("prefix "); Serial.print(data[0], HEX); Serial.print(" data "); Serial.println(data[1], HEX);
    
    Serial.println("recievedFlag ");
    for(byte i=0; i<32; i++)
    {
      if(buttons[0][i] == data[1])
      {
        if (data[0] == 0x5F)//нажатие
        {
          buttons[1][i] = 1;
          Serial.println("button ON ");
          i = 32;
        }
    
        if (data[0] == 0x6F)//отпускание
        {
          buttons[1][i] = 0;
          Serial.println("button OFF ");
          i = 32;
        }
      }//конец if(buttons[0][i] == data[1])
    }//конец for(byte i=0; i<32; i++)

    for(byte i=0; i<32; i++)
    {
       Serial.print("0x"); Serial.print(buttons[0][i], HEX); Serial.print(" ");
    }
  
    Serial.println();
  
    for(byte i=0; i<32; i++)
    {
       Serial.print(buttons[1][i]); Serial.print(","); 
    }
    Serial.println();
  }//конец if(recievedFlag)
  recievedFlag = false;  // данные обработаны и сохранены, выходим !
  //ОТСЮДА И НИЖЕ МОЖНО ПИСАТЬ или писать))
}
//=================================================================.//введите или вставьте сюда код

это скан коды клавиатуры для справки

Спойлер
Кнопка "1" - нажата 0x5F, 0x07 отпускание 0x6F, 0x07.
Кнопка "2" - нажата 0x5F, 0x06 отпускание 0x6F, 0x06.
Кнопка "3" - нажата 0x5F, 0x05 отпускание 0x6F, 0x05.
Кнопка "4" - нажата 0x5F, 0x0F отпускание 0x6F, 0x0F.
Кнопка "5" - нажата 0x5F, 0x0E отпускание 0x6F, 0x0E.
Кнопка "6" - нажата 0x5F, 0x0D тпускание  0x6F, 0x0D.
Кнопка "7" - нажата 0x5F, 0x17 отпускание 0x6F, 0x17.
Кнопка "8" - нажата 0x5F, 0x16 отпускание 0x6F, 0x16.
Кнопка "9" - нажата 0x5F, 0x15 отпускание 0x6F, 0x15.
Кнопка "0" - нажата 0x5F, 0x1E отпускание 0x6F, 0x1E.
Кнопка "*" - нажата 0x5F, 0x1F отпускание 0x6F, 0x1F.
Кнопка "#" - нажата 0x5F, 0x1D отпускание 0x6F, 0x1D.
Кнопка "СИО" - нажата 0x5F, 0x27 отпускание 0x6F, 0x27.
Кнопка "Запрос" - нажата 0x5F, 0x26 отпускание 0x6F, 0x26.
Кнопка "Повтор" - нажата 0x5F, 0x25 отпускание 0x6F, 0x25.
Кнопка "Сообщение" - нажата 0x5F, 0x04 отпускание 0x6F, 0x04.
Кнопка "Авто" - нажата 0x5F, 0x03 отпускание 0x6F, 0x03.
Кнопка "Режим" - нажата 0x5F, 0x1C отпускание 0x6F, 0x1C.
Кнопка "Видио" - нажата 0x5F, 0x24 отпускание 0x6F, 0x24.
Кнопка "Помощ" - нажата 0x5F, 0x23 отпускание 0x6F, 0x23.
Кнопка "резерв 1" - нажата 0x5F, 0x0C отпускание 0x6F, 0x0C.
Кнопка "резерв 2" - нажата 0x5F, 0x0B отпускание 0x6F, 0x0B.
Кнопка "резерв 3" - нажата 0x5F, 0x14 отпускание 0x6F, 0x14.
Кнопка "резерв 4" - нажата 0x5F, 0x13 отпускание 0x6F, 0x13.
Кнопка "резерв 5" - нажата 0x5F, 0x1B отпускание 0x6F, 0x1B.
Кнопка "Стрелка Влево" - нажата 0x5F, 0x2F отпускание 0x6F, 0x2F.
Кнопка "Стрелка Вправо" - нажата 0x5F, 0x2D отпускание 0x6F, 0x2D.
Кнопка "Стрелка Вверх" - нажата 0x5F, 0x2E отпускание 0x6F, 0x2E.
Кнопка "Стрелка Вниз" - нажата 0x5F, 0x36 отпускание 0x6F, 0x36.
Кнопка "Меню" - нажата 0x5F, 0x2C отпускание 0x6F, 0x2C.
Кнопка "Омена" - нажата 0x5F, 0x37 отпускание 0x6F, 0x37.
Кнопка "ОК" - нажата 0x5F, 0x35 отпускание 0x6F, 0x35.
Кнопка "F" - нажата 0x5F, 0x34 отпускание 0x6F, 0x34.

а можно уточнить что это? Нельзя ли кнопки парсить прямо на нем, а на ардуину передавать уже готовую инфу? Или вообще разместить программу на том устройстве и ничего не передавать?

по коду замечания нужны?

Во-первых, как то странно сначала читать символы из Сериал в String, а потом конвертировать методом

обратно в символьный массив. Почему не читать сразу в массив?

Во-вторых - прочитайте комменты к этой строчке - написано что она записывает в массив символы до длины len . А на самом деле только три. А куда девается остальное принятое? - в вечность

В третьих, если у вас в массиве клавишь 33 элемента, почему во всех циклах вы проверяете только 32 ?

Это панель оператора оно сканирует клавиатуру само и шлет ее состояние по UART. что нибудь свое добавить нельзя это готовая железка с закрытым софтом. С элементами массива возможно ошибка

возможно я что то делаю не так по незнанию просто так получилось запустить потому спрашиваю совета как правильно

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

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

Ок, почему стоит 3 - понятно.
Но принимаете то вы не по три символа, а “пока идут данные” (см коммент к строке 21). Это несоответствие рано или поздно выйдет вам боком. В таком случае надо либо принимать тоже только по одному сканкоду, либо из буфера брать не только три символа, а все.

Ну и на вопрос почему циклы только до 32х - я ответа не увидел.

Да, и главное - что собственно вы хотите узнать от форума - вы не написали. Написано “прошу совета”. какого совета?

а разве в массиве начинается не с нуля отсчет элементов если массив 33 элемента то циклы от 0 до 32 или я не прав?
Совет нужен как это правильно сделать если у меня неправильно.
Если моя реализация жизнеспособна то вопрос такой как реализовать обработчик массива который будет опрашивать состояние массива и если к примеру сработала кнопка которая сохраняется в 3й элемент массива то вызвать обработчик 4й кнопки и тп. Просто я туплю и не пойму как это реализовать

нет, все ваши циклы от 0 до 31-ого элемента. 32-й остается не охваченным.

Для i =32 условие i < 32 уже не выполняется.

спасибо массив исправлю

не массив, а циклы, массив правильный.

Так в чем проблема с этой программой? Что не так работает?

программа выводит в термина срабатывания кнопок с этим все хорошо. Дело в том чтобы добавить обработчик действий по сработке клавиш к сожалению я не пойму как это сделать более менее правильно не городя кучу if else

или через кучу if else или через свитч, что в сущности те же куча if else но в другой форме

Начните с исследования пакета данных - 2 там байта или 3. С чего начинается, чем заканчивается и как кодируется клавиша.
В противном случае будете тыкаться недели три.

там все исследовано в первом сообщении под спойлером ровна два байта при нажатии кнопки и еще два при отпускании лишние символы скорее всего из за использования строки и знака конца строки

почему тогда принимается три?

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

вот про это вам Садман и пишет.
Будете полагаться на “скорее всего” - программа “скорее всего” не будет работать :slight_smile:

1 лайк

С такими короткими пакетами никакого сбора в строку или ещё куда не нужно. Все анализируется за два хода.