Протоколы SIRC и MilesTag2
- Войдите на сайт для отправки комментариев
Ср, 10/02/2016 - 07:58
делаю тагер для лазертага на ардуине. Необходимо использовать протокол MilesTag2. Судя по описанию, он очень похож на SIRC от SONY. Стартовые импульсы, единицы, нули и паузы совпадают. В таком случаем лазертаг оружие - это просто большй пульт от телика SONY)
Т.е. не нужно дописывать новый протокол в файл IRRemote.cpp? Можно просто взять/скопировать протокол Sony изменив частоту на нужную?
MilesTag2 описание протокола
SIRC(SONY)
Поправьте если где не прав.
Ну видимо они совпадают, раз никто ничего не поправляет.
Может кто-нибудь рассказать как отправлять пакеты данных?
вот так отправка одно байта. А как послать несколько в одном пакете?
Вот такую конструкцию имеет пакет выстрела:
[Header]-[0ppppppp]-[ttdddd]
как будет выглядеть передаваемый сигнал:
[HEADER]00000001111111 - id - 1, команда 4, урон 100. Все верно?
вот так отправка одно байта. А как послать несколько в одном пакете?
Это отправка 32 бит, а не одного байта.
Видимо уже совсем поплыл... Так как отправить пакет ?
Можно ли отправить пакет вида [Header]-[0ppppppp]-[ttdddd] с помощь стандартной команды?
Или нужно править библиотеку?
Если пакет влезет в unsigned long, то править в библиотеке ничего не нужно. Сначала собрать пакет в unsigned long переменную, потом её отправить, указав количество бит в пакете.
С протоколом MilesTag2 я не знаком, потому бОльшего сказать не могу.
[Header]-[0ppppppp]-[ttdddd]
ppppppp - ID игрока
tt - номер команды
dddd - урон
это 14 бит данных.
unsigned long это 32 бита.
Наибольшая длина пакета 24 бита.
т.е. по идее можно вместить.
Можешь скинуть код команды как ото будет для например такого пакета?
[Header]-[0x83]-[0x17]-[0xE8]
Это нереально. Сначала ты рисуешь формат один, потом даешь пример для совсем другой команды. Сделай проще, сам подставь вместо ppppp, tt, dddd нужные значения, например (в двоичном виде) для формата [Header]-[0ppppppp]-[ttdddd]:
ppppppp = 0010111
tt = 10
dddd = 1111
В таком случае общая посылка будет такой:
[Header] - [00010111]-[101111]
теперь отбрасываем Header и группируем цифры, начиная справа, по 4 бита, получаем:
00 0101 1110 1111
это же самое в HEX виде будет выглядеть как: 0x05EF
отправка выполняется так:
sendSony(0x05EF, 14);
Можешь себе набросать программку (на большом компе), которая на входе получает pppppp, tt, dddd, а на выходе выводит в HEX виде нужную команду. Либо в Excel забей данные и подставь формулы. Это поможет не ошибаться с битами.
Можно написать функцию, которая будет собирать правильно эту команду, в эту функцию нужно будет передавать ppppppp, tt, dddd, на выходе команда, либо эта функция сразу вызывает отправку пакета.
Короче варианты есть.
О! Спасибо огромное!) Алгоритм понял)
Вообщем, тагер у меня стреляет. Сейчас учу его принимать данные с датчиков.
Протокол стандартный Miles Tag 2, полная копия протокола от Sony(Sirk), только команды другие. По этому использовалась библиотека IRremote.h в которой уже включен протокол от Sony.
Сам скетч:
/*Пакет выстрела состоит из 14 битов 1 бит = 0 - метка пакета выстрела далее 7 бит id оружия далее 2 бита нормера команды далее 4 бита урона*/ #include "IRremote.h" #include "MT.h" MT MTsend; //Класс для отправки команд по протоколу МТ //Параметры: unsigned long playerId = 89; //Уникальный номер оружия в игре (0-127) unsigned long teamId = TEAMID[1]; //00 - Red, 01 - Blue, 10 - Yellow, 11 - Green unsigned long WeaponDamage = DMG[15]; //см. таблицу урона в протоколе MilesTag2 void setup() { Serial.begin(9600); } void loop() { if (Serial.read() != -1) { MTsend.Shot(playerId, teamId, WeaponDamage); } }Заголовочный(Выглядит страшновато=). Первый блин комом) :
#ifndef MT_h #define MT_h #include "IRremote.h" #define ID_WEAPON_BITS_COUNT (7) #define TEAM_ID_BITS_COUNT (2) #define DAMAGE_VALUE_BITS_COUNT (4) unsigned int DMG[] = { B0000, //1 0 B0001, //2 1 B0010, //4 2 B0011, //5 3 B0100, //7 4 B0101, //10 5 B0110, //15 6 B0111, //17 7 B1000, //20 8 B1001, //25 9 B1010, //30 10 B1011, //35 11 B1100, //40 12 B1101, //50 13 B1110, //75 14 B1111, //100 15 }; unsigned int TEAMID[] { B00, // REDTEAM 0 B01, // BLUETEAM 1 B10, // YELLOWTEAM 2 B11 // GREENTEAM 3 }; //Valid messages: // BYTE 1: BYTE2: #define ADD_HEALTH 0x80 /*1 to 100HP*/ #define ADD_ROUNDS 0x81 /*1 to 100HP*/ #define COMMAND 0x83 #define ADMIN_KILL 0x00 #define PAUSE_UNPAUSE 0x01 #define START_GAME 0x02 #define RESTORE_DEFAULTS 0x03 #define RESPAWN 0x04 #define NEW_GAME_IMMEDIATE 0x05 #define FULL_AMMO 0x06 #define END_GAME 0x07 #define RESET_CLOCK 0x08 #define INITIALIZE_PLAYER 0x0A #define EXPLODE_PLAYER 0x0B #define NEW_GAME_READY 0x0C #define FULL_HEALTH 0x0D #define FULL_ARMOR 0x0F #define CLEAR_SCORES 0x14 #define TEST_SENSORS 0x15 #define STUN_PLAYER 0x16 #define DISARM_PLAYER 0x17 #define SYS_DATA 0x87 #define CLONING_DATA 0x01 #define SCORE_DATA_PART1 0x03 #define SCORE_DATA_PART2 0x04 #define SCORE_DATA_PART3 0x05 #define CLIPS_PICKUP 0x8A #define AMMO_BOX_ID /*0x00-OxF*/ #define HEALTH_PICKUP 0x8B #define MEDIC_BOX_ID /*0x00-OxF*/ #define FLAG_PICKUP 0x8C #define FLAG_BOX_ID /*0x00-OxF*/ IRsend irsend; //объект для отправки по ИК class MT { public: void Shot(unsigned long playerId, unsigned long teamId, unsigned long damageValue); void DecodeMT(unsigned long kod, int nbits); }; /* MT.Shot функция для отправки выстрела по ИК шлет 13бит информации в 14 битном пакете 1 бит = 0 - индентификатор пакеты выстрела */ void MT::Shot(unsigned long playerId, unsigned long teamId, unsigned long damageValue) { unsigned long result = playerId; result <<= TEAM_ID_BITS_COUNT; // teamId bits result |= teamId; result <<= DAMAGE_VALUE_BITS_COUNT; // damageValue bits result |= damageValue; irsend.sendSony(result, 14); } void MT::DecodeMT(unsigned long kod, int nbits) { unsigned long maskType = 1UL << (nbits - 1); if (kod & maskType) { //Пакет информации или команды Serial.println("CMD/SYS/INFO PAKET"); }else { //Пакет выстрела Serial.println("SHOT PAKET"); unsigned long maskWID = 127 << 6; unsigned long maskTID = 3 << 4; unsigned long maskDID = 15; unsigned long teamID = (kod & maskTID)>>4; unsigned long dmgID = kod & maskDID; Serial.print("Player ID: "); Serial.println((kod & maskWID)>>6, DEC); Serial.print("TEAM ID: "); Serial.println(teamID, DEC); Serial.print("Damage ID: "); Serial.println(dmgID, DEC); } } #endifПоявился новый вопрос. Я делаю протокол Miles Tag 2. но оружия от компании Laserwar 4го поколения использует несколько измененые пакеты. А именно добавляют в конец контрольную сумму.
http://laserwar.ru/?do=static&page=protocol_laserwar
В оборудовании LASERWAR используется дополненный формат, в котором задействовано 24 бита:
[Header]-[0ppppppp]-[ttdddd00]-[cccccccc]
При сравнении форматов видно, что первые 14 бит у них идентичны, таким образом, ружья на базе "родного" Майлс без проблем принимают и обрабатывают "выстрел" 4-го поколения LASERWAR. В свою очередь, оборудование 4-го поколения LASERWAR проверяет количество принятых бит в посылке - если их 14, то дальше принятый сигнал обрабатывается как сигнал Майлса. Если же принятых битов 24, то сначала проверяется правильность принятого пакета по контрольной сумме и, если все нормально, то обрабатывается попадание. Такое усложнение позволяет свести практически к нулю количество ложных попаданий.
Важно: Контрольная сумма рассчитывается именно как сумма первых двух байт посылки, точнее ее младшие 8 значащих бит: CRC = Lo(Byte1 + byte2). Это сделано для исключения ложных попаданий при настройке оборудования через ИК-канал (при настройке формат посылки тоже имеет 3 байта, но CRC = Byte1 XOR Byte 2) - выстрел никогда не будет воспринят как команда, и наоборот - команда не будет засчитана как выстрел.
Я не совсем понял что это за сумма такая.
Объясните пожалуйста на пальцах)
Допустим код такой:
byte1 byte2 CRC
[Header] - [01000101] - [10111100] - [????????]
Как получить сумму значащих младших бит? Это которые вообще?
CRC = byte1 | byte2?
Звините, если вопросы нубские. Пока не совсем вкуриваю в битовых операциях.
Важно: Контрольная сумма рассчитывается именно как сумма первых двух байт посылки, точнее ее младшие 8 значащих бит: CRC = Lo(Byte1 + byte2). Это сделано для исключения ложных попаданий при настройке оборудования через ИК-канал (при настройке формат посылки тоже имеет 3 байта, но CRC = Byte1 XOR Byte 2) - выстрел никогда не будет воспринят как команда, и наоборот - команда не будет засчитана как выстрел.
...
Допустим код такой:
byte1 byte2 CRC
[Header] - [01000101] - [10111100] - [????????]
Как получить сумму значащих младших бит? Это которые вообще?
...
Ничего не понял, то сложение, то XOR, смотрите доки, как правильно.
Если сложение:
CRC = 01000101 + 10111100 = 100000001. Отбрасываем старший бит и получаем 8 бит контрольной суммы 00000001. Чтобы не париться с отбрасыванием битов, нужно сложить байт с байтом и поместить в байт, всё, что будет размером больше байта будет игнорироваться.
Если XOR:
CRC = 01000101 ^ 10111100 = 11111001. Здесь ничего отбрасывать не нужно, потому что XOR не даст результат больше, чем байт (если работаем с байтами).
Это и есть доки)
Попробую задать вопрос тех поддержке)
Так, у меня тут какая-то непонятка.
Serial.println("CMD/SYS/INFO PAKET"); unsigned long maskMSG = 255 << 16; unsigned long maskVALUE = 255 << 8; unsigned long msg = ((kod & maskMSG) >> 16); unsigned long value = ((kod & maskVALUE) >> 8); Serial.println(msg, HEX); Serial.println(value, HEX);kod = 100000110000000111101000(Проверил, посылаю именно такой код)
maskMSG = 111111110000000000000000
maskVALUE = 1111111100000000
Значит умножение даст:
100000110000000000000000
0000000100000000
После сдвигов вправо:
msg = 10000011 = 0x83
value = 00000001 = 0x01
Порт же выдает следющее:
CMD/SYS/INFO PAKET
0
8301
Уже и через калькулятор проверил действия, все правильно. Что не так-то?
Для полной проверки предложенного кода достаточно вывести ВСЕ переменные (в т.ч. маски) в Serial, тогда сомнений не будет много меньше и калькулятор может не понадобиться.
Я бы не парился с масками, а сдвигал, потом маскировал, типа так:
unsigned long msg = (kod >> 16) & 0xFF;
unsigned long value = (kod >> 8) & 0xFF;
так оно понятней и проще, не будет ошибок с маской.
Еще, зачем в kod оставлять место под CRC? Не проще передавать как есть, т.е. условно как kod = (msg << 8) | value; А уже потом, перед отправкой, если нужно, формировать CRC, просто сдвинуть kod на 8 влево и вставить CRC в младший байт. Это удобней с любой стороны, например, можно использовать отправку как с CRC, так и без неё. Плюс не нужно совершать "космической" величины сдвиги.
Калькулятор - хорошо, однако, программист часто совершает логические ошибки, т.е. он думает, что компилятор сделает такой код, а он, собака, делает по-своему, а не так как надо. Компилятор - он тупой и делает так, как его создатели задумали, а программист думает не всегда так же, потому и "загадки".
Особенно осторожно нужно обходиться с выражениями, потому что 255 << 16 и 255UL << 16 могут выдать разный результат на разных компиляторах. Впрочем на 8-битниках это всё несколько проще. Кстати, если угодно, маски лучше задавать в HEX виде, например, не 255, а 0xFF. Сдвиг на 16 бит удобно и читабельно, однако, я бы объявил маску как 0x00FF0000UL, т.е. со строгим объявлением типа константы (UL = unsigned long) и в HEX виде (я просто привык в HEXе, так проще и удобней для меня). В HEX число короче, потому что каждая цифра (напоминаю, что это HEX) занимает 4 бита.
CRC пока не трогал. Последний байт = [0xE8], это типо закрывающий байт, судя по протоколу.
Указание UL помогло. А по поводу:
Это конечно короче. Но я эту запись не понимаю) Здесь, подгоняется код к маске. Для меня это как умножение, хотя я только научился складывать) Осталю пример на будущее) Спасибо)
Здесь всё просто. Сдвиг, он и в Африке сдвиг, потому, наложение маски на результат можно делать как ДО, так и ПОСЛЕ сдвига. Однако чисто логически, если сначала сдвинуть всё число, а потом от него отрезать только нужное, это понятней, нежели сначала отрезать, а потом сдвигать, мало ли что произойдет при сдвиге (шучу). В общем то это всё субъективно.
Дело двигается помаленьку, это главное. :)
привет, тоже начал сборку тагера на ардуине, не расскаже как успехи?
првет, подскажите пожалуста што делать не компилируетса скетч
дисплей 1100 библиотеки вроде все перепробовал...одни ошибки
"Отображать вывод во время компиляции"
включено в Файл > Настройки
Приветсвую, есть готовые скетчи для тагера?? Готов купить)))
стерлитамаку привет. +1. продолжаем тему. какие у кого успехи. какие функции используете?
насмотрелся видео, тоже захотелось повторить. в голове пока несколько функций.
1убили, возврат на базу и коннект(скорее всего как в оригиналах выстрелом в базовую точку)
2на базовой точке дисплей, кого кто когда убил, передсча нрф24
3звуковое сопровождение(выстрел. попадание-нрф)
4 ргб диод на автомате, уровень жизни-синий, зеленый, красный умер(автоматически пистолет не работает)
5.фантазия в думе. пишем делаем делимся фантазируем
пс. в самоделках обычно используют обычный светодиод ,линзу , а в качестве приемника солнечную панель.тк ик луч в фокусе прожигает, не дай бог в глаза. но думаю сигнал короткий и ни чего не будет . ваше мнение?
интересная игрушка на шашлыки, позитивчик
Дык я же выложил) Вообще делал для себя и в целях эксперимента. У меня все стреляло как надо. Для основы я думаю многим подойдет. Главное что я сделал - это определил протокол и описал класс дял тагера. Функции лишь выстрел и прием попадания. Но все остальные функции по факту от них происходят. Ток команды в ик-пакете другие.
тыкните пожалуйста в каком направлении копать. оружие собрал, дошел до каски, в котором ик датчики по нрф отправляют сигнал на оружие(функция счетов жизни и оружие не стреляет, списал у дмитрия осипова-ик удлиннитель). теперь не могу совершить обратную связь- если убит каска красным горит. какойнибуди пример скиньте пожалуйста
Если не трудно, скинь сам скетч и какие порты были задействованы на плате. Только начинаю знакомится с Ардуино, опыт никакой. С уважением.
Здравствуйте, понимаю,много времени прошло, но я сейчас с этим же борюсь. Вопрос такой, а на солнце у вас работало?
на Солнце - только у великого вождя северокорейского народа Ким Чен Ына работает.
Блин, ну покупные то работают! Дело в том, что я скетч написал, но несколько другой чем тут в теме описывается, так вот, в сумерках, тучи, помещение все хорошо, а на солнце не фурычит. Код другой на приемник приходит. Уже по-моему все испробовал. Ни у кого идей нету?
ночь!
Ну мб завтра)
По поводу солнца:
Причина понятна: Помехи.
Я бы сделал так:
При выстреле шлем не один единственный пакет. А сразу штук 100. Главное, что бы выстрел имел некий ID. И все эти 100 пакетов будут иметь один и тот же ID. Так мы увеличиваем шансы прохода пакета без помех в 100 раз. А при получении цельного пакета - запоминаем ID и более эти пакеты не обрабатываем.
Для проверки целостности добавим контрольную сумму в конец пакета.
Ну или искать источники и приемники в каком-нибудь более специфичном спектре.
Всем привет.
С солнцем проблема на уровне физики, решить можно увеличивая мощность выстрела, например диодом tsal6105, оптикой или подобными решениями.
Отправление 100 пакетов несовместимо с протоколом MT и оборудованием того же LaserWar.
С другой стороны, есть время шока, которое 99 дополнительных пакетов нейтрализует, но все равно криво.
Из моих поделок: аптечка на ардуино уно (отправляет админкилл, выстрел, аммо, здоровье и т.д.), нож на микро (как у lw, отправляет админкилл, на макете тренировочного ножа), точка - аналог battlefield (тоже на ардуино, но без инфракрасного интерактива, просто две кнопки и захват c световой и звуковой индикацией).
В связи с тем, что ребятам нужно еще, планирую библиотеку для удобства, наверное возьму DezmontDeXa за основу.
В целом, спасибо за то, что разобрался в sendSony, очень пригодилось))
Что за стал 6105? Ничего про такой не нашел, а как реализован нож?? Поражение от него
TSAL6100 - модель инфракрасного диода, можно заказать на али, к примеру. Достаточно мощный, но угол всего 10градусов. Он использовался раньше (до появления "гибридной оптики") в излучателях Laserwar'а.
нож купил на алиэкспрессе, тренировочная модель, или для косплея, пластиковый, с ножнами. Встроил arguino pro mini в ручку, две батарейки 2032, диод, бьет на метра полтора, убивает сразу, отправляет пакет admin kill
https://laserwar.ru/index.php?do=static&page=lasertag-knife&menuitem=spec&menusubitem=spec11
Один в один как по ссылке.
Вообще, если лазервар корпус такой же использует, как на али, то нож так себе, очень хлипкий, в бою очень редко используется, мне ни разу не пригодился.
Доброго времени суток! А можете поделится скетчем аптечки?
Добрый день!
Примерно так (сам скетч):
#include <LT.h> //Определение IR передатчика LT_transmitter trans; void setup() { // put your setup code here, to run once: pinMode(5, INPUT_PULLUP); // 5 контакт - кнопка } void loop() { // put your main code here, to run repeatedly: if (!digitalRead(5)) { trans.Heal(); delay(100); } }Код библиотеки LT:
файл заголовков:
/* Библиотека управления устройствами, поддерживающими протокол Miles Tag 2 (и производные от LaserWar) */ #ifndef LT_h #define LT_h #include "Arduino.h" #include "IRremote.h" #define TEAM_ID_BITS_COUNT (2) #define DAMAGE_VALUE_BITS_COUNT (4) const byte DAMAGE1 = B0000; const byte DAMAGE2 = B0001; const byte DAMAGE4 = B0010; const byte DAMAGE5 = B0011; const byte DAMAGE7 = B0100; const byte DAMAGE10 = B0101; const byte DAMAGE15 = B0110; const byte DAMAGE17 = B0111; const byte DAMAGE20 = B1000; const byte DAMAGE25 = B1001; const byte DAMAGE30 = B1010; const byte DAMAGE35 = B1011; const byte DAMAGE40 = B1100; const byte DAMAGE50 = B1101; const byte DAMAGE75 = B1110; const byte DAMAGE100 = B1111; const byte REDTEAM = B00; const byte BLUETEAM = B01; const byte YELLOWTEAM = B10; const byte GREENTEAM = B11; // BYTE 1: BYTE2: #define ADD_HEALTH 0x80 /*1 to 100HP*/ #define ADD_ROUNDS 0x81 /*1 to 100HP*/ const byte COMMAND = 0x83; const byte ADMIN_KILL = 0x00; const byte PAUSE_UNPAUSE = 0x01; const byte START_GAME = 0x02; const byte RESTORE_DEFAULTS = 0x03; const byte RESPAWN = 0x04; const byte NEW_GAME_IMMEDIATE = 0x05; const byte FULL_AMMO = 0x06; const byte END_GAME = 0x07; const byte RESET_CLOCK = 0x08; const byte INITIALIZE_PLAYER = 0x0A; const byte EXPLODE_PLAYER = 0x0B; const byte NEW_GAME_READY = 0x0C; const byte FULL_HEALTH = 0x0D; const byte FULL_ARMOR = 0x0F; const byte CLEAR_SCORES = 0x14; const byte TEST_SENSORS = 0x15; const byte STUN_PLAYER = 0x16; const byte DISARM_PLAYER = 0x17; #define SYS_DATA 0x87 #define CLONING_DATA 0x01 #define SCORE_DATA_PART1 0x03 #define SCORE_DATA_PART2 0x04 #define SCORE_DATA_PART3 0x05 #define CLIPS_PICKUP 0x8A #define AMMO_BOX_ID /*0x00-OxF*/ #define HEALTH_PICKUP 0x8B #define MEDIC_BOX_ID /*0x00-OxF*/ #define FLAG_PICKUP 0x8C #define FLAG_BOX_ID /*0x00-OxF*/ /* LT_transmitter class для отправления пакетов протокола Miles Tag 2. */ class LT_transmitter { public: LT_transmitter(); void Heal(); void Ammo(); void AdminKill(); void Shot(unsigned long playerId, unsigned long teamId, unsigned long damageValue); private: IRsend _irsend; void sendCommand(byte command, byte byte2); };Файл CPP:
/* */ #include "Arduino.h" #include "LT.h" LT_transmitter::LT_transmitter() { } void LT_transmitter::Heal() { sendCommand(COMMAND, START_GAME); } void LT_transmitter::Ammo() { sendCommand(COMMAND, FULL_AMMO); } void LT_transmitter::AdminKill() { sendCommand(COMMAND, ADMIN_KILL); } void LT_transmitter::Shot(unsigned long playerId, unsigned long teamId, unsigned long damageValue) { unsigned long result = playerId; result <<= TEAM_ID_BITS_COUNT; // teamId bits result |= teamId; result <<= DAMAGE_VALUE_BITS_COUNT; // damageValue bits result |= damageValue; _irsend.sendSony(result, 14); } void LT_transmitter::sendCommand(byte command, byte byte2) { unsigned long result = command; result <<= 8; // command bits result |= byte2; result <<= 8; // command value bits result |= 0xE8; _irsend.sendSony(result, 24); }Спасибо! Буду собирать и тестить на выходных.
GreyZ, огромное спасибо!
Добрый день, пытаюсь разобраться в посте #35/
Судя по скетчу при нажатии на кнопку, подключенную к 5 входу происходит
trans.Heal(); из библиотеки.Подскажите, к какому выводу ардуины подключать ИК-диод. Нигде явно это не прописано.
ledir to arduino pin ๓
Спасибо, опытным путем установил, что на d3. А вот где это задается - не вижу.
Please, sir.
i told you the truth. the output pin number ๓ == 3. Arduino\libraries\IRLibmaster\IRLibTimer.h
Это задаётся в библиотеке, но поменять нельзя. Используйте д3 а то, что было на д3 перенесите на другой пин.)
starbit Thanks!
GreyZ огромное спасибо за библиотеку, помогла разобраться с формированием комманд. И с дешифровкой комманд. Таггер уже запилил, осталось датчиков дождаться в нужном количестве. Ребенок радуется пострелять пока по мишени.
GreyZ, большое спасибо за скетч и библиотеку! Если не сложно могли бы поделиться скетчем для повязок (прием сигнала)? Буду очень благодарен. Моя почта - alexfulga@mail.ru
DezmontDeXa GreyZ kisoft
Поделитесь пожалуйста скетчем для тагера аптечки
kg2@tut.by
Очень сильно понравился скетч GreyZ для атечки выложенный в этой ветке.
Так хочется еще скетч для тагера?
Пре много благодарен.
Доброго времени суток!
Так кто-нибудь тагер доделал?
Можете поделиться скетчем?
e-mail: pavel.250776@yandex.ru
Привет.
Лично я тагер не делал. Использую данную библиотеку только для девайсов ,типа гранат и аптечек.
Тагер не делал, привет. Делал нож, он по сути Тагер, разницы нет. Код, приложенный выше подойдёт. Вообще, каждый девайс, если он уникальный, обладает уникальным кодом.. Все остальное из библиотеки. Поэтому нужно разбираться хоть немного в коде, просто скопипастить не вариант.
Попробовал реализовать протокол MilesTag 2 с расширением от Laserwar, т.е. с подсчетом контрольной суммы - все работает, однако есть большое НО: процент искаженных пакетов весьма велик. Из десяти может быть неверных 3-5 пакетов. Алгоритм вычисления контрольной суммы их успешно отбрасывает, только есть две проблемы:
1. Получается, что, выстрелив 10 раз точно в цель, попаданий будет засчитано гораздо меньше.
2. Иногда пакет искажается настолько сильно, что получается слишком коротким - не более 2 байт. Разумеется, алгоритм декодера решает, что это просто пакет выстрела без контрольной суммы, и начинает из него выделять данные об игроке, команде и уроне. Данные получаются, конечно, неверными. Интересно, как с этим борется Laserwar?
Как правило, данные искажаются в случае, если стрелок движется, либо на датчик приемника попадает край ИК-пятна излучателя. Тесты проводил дома, на улице пока не гонял.
Кто-нибудь сталкивался с такими проблемами? Есть идеи, как с этим бороться?
Честно говоря, я уже не рад, что связался с MilesTag :). Гораздо проще было оставить свой собственный протокол, как я планировал изначально. Там все было просто: никаких номеров игроков, никакого урона, по ИК передавался только номер команды. Если приемник получал номер чужой команды, он фиксировал попадание. Причем помехоустойчивость у этой системы была отличной, т.к. номера команд были выбраны с большим разносом - 32, 64, 128 и 256. Т.о., вероятность того, что искаженный пакет совпадет с номером твоей команды (ну да, предполагалось играть без FF, т.е. огня по своим) была очень мала.
Привет.
А что является приёмником: повязка LW или самодельное устройство?