прошу помощи по заполнению и обработке массива
- Войдите на сайт для отправки комментариев
Пнд, 30/03/2020 - 20:55
#include <SoftwareSerial.h> #define LOOP_DELAY 50 #define SW_SERIAL_BAUD_RATE 9600 #define HW_SERIAL_BAUD_RATE 9600 #define SW_SERIAL_RX_PIN 11 #define SW_SERIAL_TX_PIN 10 SoftwareSerial mySerial(SW_SERIAL_RX_PIN, SW_SERIAL_TX_PIN); // RX, TX int IBUSreceiveByte = 0; // byte reading from I-BUS byte IBUSbyte[7] = {0,0,0,0,0,0,0}; // key byte sequence int Delay = 0; //delay in millisec int ButtonPressed = 0; //boolean value set 1 if key press detected int KeyID = 0; // key press number (for easy select case routine) //hold keys flags //int N_HOLD_F = 0; //next track hold flag //int P_HOLD_F = 0; //prev track hold flag //int V_HOLD_F = 0; // r/t key hold flag byte PLUS_DOWN[7] = {0, 0x50, 0x04, 0x68, 0x32, 0x11, 0x1F}; // + press button byte MINUS_DOWN[7] = {0, 0x50, 0x04, 0x68, 0x32, 0x10, 0x1E}; // - press button byte NEXT_DOWN[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x01, 0x06}; // > press button byte NEXT_HOLD[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x11, 0x16}; // > hold button byte NEXT_REL[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x21, 0x26}; // > release button byte PREV_DOWN[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x08, 0x0F}; // < press button byte PREV_HOLD[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x08, 0x0F}; // < hold button byte PREV_REL[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x08, 0x0F}; // < release button byte VOICE_DOWN[7] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x80, 0x27}; // voice press button byte VOICE_HOLD[7] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x90, 0x37}; // voice hold button byte VOICE_REL[7] = {0, 0x50, 0x04, 0xC8, 0x3B, 0xA0, 0x07}; // voice release button byte RT_DOWN[7] = {0, 0x50, 0xFF, 0x03, 0xC8, 0x01, 0x9A}; // voice release button void setup() { mySerial.begin(9600); Serial.begin(9600); } void loop() { if (Serial.available() && ButtonPressed==0){ TryReadIBUSmsg(); } if (ButtonPressed==1){ mySerial.print(millis()); mySerial.println(" ----------------------------------------------- "); switch (KeyID){ case 100: //Если клавиша не опознана или какие-то ошибки в шине при чтении mySerial.print("UNKNOWN KEY: "); SerialPrintKey(); break; case 40: mySerial.print("R/T KEY: "); SerialPrintKey(); break; case 1: mySerial.print("VOL + key: "); SerialPrintKey(); break; case 2: mySerial.print("VOL - key: "); SerialPrintKey(); break; case 11: mySerial.print("NEXT FLAG HOLD=0: "); SerialPrintKey(); // N_HOLD_F=0; break; case 12: mySerial.print("NEXT FLAG HOLD=1: "); SerialPrintKey(); // N_HOLD_F=1; break; /* case 13: if (N_HOLD_F==0){ mySerial.print("NEXT TRACK key: "); SerialPrintKey(); } else { mySerial.print("NEXT FOLDER key: "); SerialPrintKey(); } break; */ case 21: mySerial.print("PREV FLAG HOLD=0: "); SerialPrintKey(); // P_HOLD_F=0; break; case 22: mySerial.print("PREV FLAG HOLD=1: "); SerialPrintKey(); // P_HOLD_F=1; break; /* case 23: if (P_HOLD_F==0){ mySerial.print("PREV TRACK key: "); SerialPrintKey(); } else { mySerial.print("PREV FOLDER key: "); SerialPrintKey(); } break; */ case 31: mySerial.print("VOICE FLAG HOLD=0: "); SerialPrintKey(); // V_HOLD_F=0; break; case 32: mySerial.print("VOICE FLAG HOLD=1: "); SerialPrintKey(); // V_HOLD_F=1; break; /* case 33: if (V_HOLD_F==0){ mySerial.print("VOICE key press: "); SerialPrintKey(); } else { mySerial.print("Voice key hold: "); SerialPrintKey(); } break; */ } ButtonPressed = 0; } } void TryReadIBUSmsg() { IBUSreceiveByte = Serial.read(); //read 1-st byte Если 50 то это начало посылки от рулевых кнопок if (IBUSreceiveByte==0x50) { IBUSbyte[1]=0x50; for (int i=2; i <= 7; i++){ IBUSbyte[i] = Serial.read(); //read 2,3,4,5,6,7 bytes of data - читаем следующие байты delay(Delay); SerialPrintKey(); } KeyID=100; //Устанавливаем по умолчанию что клавиша не опознана if(memcmp(IBUSbyte, PLUS_DOWN, 7) == 0 ){KeyID=1;} // и меняем если опознана на соответствующий код if(memcmp(IBUSbyte, MINUS_DOWN, 7) == 0 ){KeyID=2;} if(memcmp(IBUSbyte, NEXT_DOWN, 7) == 0 ){KeyID=11;} if(memcmp(IBUSbyte, NEXT_HOLD, 7) == 0 ){KeyID=12;} if(memcmp(IBUSbyte, NEXT_REL, 7) == 0 ){KeyID=13;} if(memcmp(IBUSbyte, PREV_DOWN, 7) == 0 ){KeyID=21;} if(memcmp(IBUSbyte, PREV_HOLD, 7) == 0 ){KeyID=22;} if(memcmp(IBUSbyte, PREV_REL, 7) == 0 ){KeyID=23;} if(memcmp(IBUSbyte, VOICE_DOWN, 7) == 0 ){KeyID=31;} if(memcmp(IBUSbyte, VOICE_HOLD, 7) == 0 ){KeyID=33;} if(memcmp(IBUSbyte, VOICE_REL, 7) == 0 ){KeyID=32;} if(memcmp(IBUSbyte, RT_DOWN, 7) == 0 ){KeyID=40;} ButtonPressed=1; } else { ButtonPressed=0; } } void SerialPrintKey() // печать в ком порт посылки { for (int x=1; x <= 7; x++){ mySerial.print(IBUSbyte[x], HEX); mySerial.print(" "); } mySerial.println(); }
Здравствуйте все
Нужна помощь новичку.
Прошу подсказки, в чем может быть проблема - пробую переделать найденный скетч для распознавания нажатий кнопок руля.
Не могу понять, почему на месте первого байта массива появляется FF
на картинке ситуация в мониторе порта, после нажатия кнопки руля - первый раз (кстати тоже не могу понять почему одно нажатие выводит две распечатки) - на месте второго байта FF, и соответственно, сравнение массива не успешное. Тут же появляется вторая распечатка - видно как (для меня странно) дублируются байты, смещаясь по мере заполнения. Но при этом посылка уже правильная, 04 вместо FF и таки в конце распознается скетчем.
Собственно, задача более чем тривиальная - принять в порт посылку, и на основании ее содержания (условия строятся на основании определенных байт посылки) - выполнять те или иные действия. Но пока какой-то тотальный бардак с заполнением массива из посылки.
Подскажите, кто знает - где ошибка?
Спасибо!
Знаю есть тут люди с машинами понимающие. Я пока со своей колокольни брякну, может и не поможет, но на мысли какие наведёт. Байты же справа на лево читаться должны, полагаю FF это заполнение не достающих данных, типа нету ничего поэтому по максимуму. Но это я так, со своей колокольни и вообще ничего не понимая брыкнул. Удачи вам!
Спасибо за участие.
У меня есть решение как обойти это - просто "подогнать" строку для сравнения с тем, что приходит на экран. Но это не выход. Я принципиально где-то недопонимаю и ошибаюсь. А очень хочется таки разобраться и сделать как надо.
напал на след этого безобразия.
Вот такой скетч
Дает в монитор следующее :
Получается, что если отправить посылку (я с эмулятора вручную пока пробую) длинной равной длине объявленного массива - то ( с горем пополам) посылка в монитора показывается верно. Периодически "пролетает" какой-то мусор (видно на левой части) но, это скорее всего к портам-таймингам вопрос.
А самый главный вопрос - почему вторая часть строки все равно попадает в массив, хотя он ограничен по размеру? Получается, что все, что пришло в порт "загоняется" в массив по кругу.
Как сделать так, чтобы принимались только необходимые мне байты, а остальное просто игнорировалось?
На правой части картинки видно, что все, что отправлено в порт попадает в массив, а мне это не нужно.
Я вижу вариант - через условие, в посылке ведь есть длинна сообщения. Но если кто-то подскажет решение проще - буду благодарен.
Грубо говоря, какой бы длинны не было принято сообщение - в массив записать только 8 байт. Остальное игнорировать.
Спасибо всем!
Почему вы читаете из буфера N байт, не убедившись, что они там есть?
Прошу понять и простить, я начинающий
if
(
Serial
.available() - это не проверка наличия чего-то в буфере?
Именно - чего-то. Но считываете вы не чего-то, а 7 байт.
if (Serial.available() > 7)
так?
Сделал так. Стало намного лучше. Отсекает "хвост" в 7 байт, если посылка до 14. Если длиннее - получается 7 первых приняло, потом 7 пропустило, и оставшиеся снова приняло.
Я может неправильно понимаю как это работает. Моя расшифровка if (Serial.available() > 7) - если в буфере есть что-то длинной больше 7 байт, то....
Стало быть, по условиям - приняло первые 7, ок. Проверили остаток, и если меньше 7 - то ничего, а если больше, то снова условие выполняется и "остатки" попадают в порт.
Так?
Можно как-то очистить буфер после успешного принятия первых N байт?
Я пробовал втыкнуть flush, но не сработало. Это для отправки, как я понял.
Спасибо
Нельзя очистить то, что ещё не принято. Переходите от парадигмы "данные ждут в массиве" к парадигме "данные придут хрен знает когда": ждете маркера начала пакета, считываете после этого N байт в свой массив (буферизуете), обрабатываете. Потом всё заново.
Благодарю, буду пробовать