Протоколы SIRC и MilesTag2

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

делаю тагер для лазертага на ардуине. Необходимо использовать протокол MilesTag2. Судя по описанию, он очень похож на SIRC от SONY. Стартовые импульсы, единицы, нули и  паузы совпадают. В таком случаем лазертаг оружие - это просто большй пульт от телика SONY)
Т.е. не нужно дописывать новый протокол в файл IRRemote.cpp? Можно просто взять/скопировать протокол Sony изменив частоту на нужную?

 

MilesTag2  описание протокола
SIRC(SONY)

Поправьте если где не прав.

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Ну видимо они совпадают, раз никто ничего не поправляет.
Может кто-нибудь рассказать как отправлять пакеты данных?
 

irsend.sendSony(0x04, 32);

вот так отправка одно байта. А как послать несколько в одном пакете?

Вот такую конструкцию имеет пакет выстрела:

[Header]-[0ppppppp]-[ttdddd]
как будет выглядеть передаваемый сигнал:
[HEADER]00000001111111  - id - 1, команда 4, урон 100. Все верно?

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

DezmontDeXa пишет:

 

irsend.sendSony(0x04, 32);

вот так отправка одно байта. А как послать несколько в одном пакете?

Это отправка 32 бит, а не одного байта.

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Видимо уже совсем поплыл... Так как отправить пакет ?

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016
irsend.sendSony(0x04, 32);

Можно ли отправить пакет вида [Header]-[0ppppppp]-[ttdddd] с помощь стандартной команды?
Или нужно править библиотеку?

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Если пакет влезет в unsigned long, то править в библиотеке ничего не нужно. Сначала собрать пакет в unsigned long переменную, потом её отправить, указав количество бит в пакете.

С протоколом MilesTag2 я не знаком, потому бОльшего сказать не могу.

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

[Header]-[0ppppppp]-[ttdddd]
ppppppp - ID игрока
tt - номер команды
dddd - урон
это 14 бит данных.

unsigned long это 32 бита.

Наибольшая длина пакета 24 бита.

т.е. по идее можно вместить.
Можешь скинуть код команды как ото будет для например такого пакета?
[Header]-[0x83]-[0x17]-[0xE8]

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Это нереально. Сначала ты рисуешь формат один, потом даешь пример для совсем другой команды. Сделай проще, сам подставь вместо 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, на выходе команда, либо эта функция сразу вызывает отправку пакета.

Короче варианты есть.

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

О! Спасибо огромное!) Алгоритм понял)

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Вообщем, тагер у меня стреляет. Сейчас учу его принимать данные с датчиков.
Протокол стандартный 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

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Появился новый вопрос. Я делаю протокол Miles Tag 2. но оружия от компании Laserwar 4го поколения использует несколько измененые пакеты. А именно добавляют в конец контрольную сумму.

http://laserwar.ru/?do=static&page=protocol_laserwar

В оборудовании LASERWAR используется дополненный формат, в котором задействовано 24 бита:
[Header]-[0ppppppp]-[ttdddd00]-[cccccccc]

где p - биты идентификатора игрока;
  t - биты идентификатора команды;
  d - биты, отвечающие за силу выстрела;
  c - контрольная сумма CRC.

[Header]-[0ppppppp]-[ttdddd] - Майлс
[Header]-[0ppppppp]-[ttdddd00]-[cccccccc] - LASERWAR

При сравнении форматов видно, что первые 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?

Звините, если вопросы нубские. Пока не совсем вкуриваю в битовых операциях.
 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

DezmontDeXa пишет:

Важно: Контрольная сумма рассчитывается именно как сумма первых двух байт посылки, точнее ее младшие 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 не даст результат больше, чем байт (если работаем с байтами).

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Это и есть доки)
Попробую задать вопрос тех поддержке)

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Так, у меня тут какая-то непонятка.
 


    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

Уже и через калькулятор проверил действия, все правильно. Что не так-то?
 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Для полной проверки предложенного кода достаточно вывести ВСЕ переменные (в т.ч. маски) в 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 бита.

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

CRC пока не трогал. Последний байт = [0xE8], это типо закрывающий байт, судя по протоколу.

 

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Указание UL помогло. А по поводу:

unsigned long msg = (kod >> 16) & 0xFF;
unsigned long value = (kod >> 8) & 0xFF;

Это конечно короче. Но я эту запись не понимаю) Здесь, подгоняется код к маске. Для меня это как умножение, хотя я только научился складывать) Осталю пример на будущее) Спасибо)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Здесь всё просто. Сдвиг, он и в Африке сдвиг, потому, наложение маски на результат можно делать как ДО, так и ПОСЛЕ сдвига. Однако чисто логически, если сначала сдвинуть всё число, а потом от него отрезать только нужное, это понятней, нежели сначала отрезать, а потом сдвигать, мало ли что произойдет при сдвиге (шучу). В общем то это всё субъективно.

Дело двигается помаленьку, это главное. :)

 

vilioren56
Offline
Зарегистрирован: 03.06.2016

привет, тоже начал сборку тагера на ардуине, не расскаже как успехи? 

reypashi
Offline
Зарегистрирован: 23.10.2016

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

дисплей 1100   библиотеки вроде все перепробовал...одни ошибки

 

Arduino: 1.6.1 (Windows 8.1), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
Изменена опция сборки, пересобираем все
E:\проги\Arduino\hardware\arduino\avr\cores\arduino\main.cpp: In function 'int setup()':
E:\проги\Arduino\hardware\arduino\avr\cores\arduino\main.cpp:30:16: error: new declaration 'int setup()'
 int setup (void)
                ^
In file included from E:\проги\Arduino\hardware\arduino\avr\cores\arduino\main.cpp:20:0:
E:\проги\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:127:6: error: ambiguates old declaration 'void setup()'
 void setup(void);
      ^
Ошибка компиляции.
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки

 

DeGiz
Offline
Зарегистрирован: 16.01.2017

Приветсвую, есть готовые скетчи для тагера?? Готов купить))) 

satelit 2
Offline
Зарегистрирован: 04.12.2016

стерлитамаку привет. +1. продолжаем тему. какие у кого успехи. какие функции используете?

насмотрелся видео, тоже захотелось повторить. в голове пока несколько функций. 

1убили, возврат на базу и коннект(скорее всего как в оригиналах выстрелом в базовую точку)

2на базовой точке дисплей, кого кто когда убил, передсча нрф24

3звуковое сопровождение(выстрел. попадание-нрф)

4 ргб диод на автомате, уровень жизни-синий, зеленый, красный умер(автоматически пистолет не работает)

5.фантазия в думе. пишем делаем делимся фантазируем

пс. в самоделках обычно используют обычный светодиод ,линзу , а в качестве приемника солнечную панель.тк ик луч в фокусе прожигает, не дай бог в глаза. но думаю сигнал короткий и ни чего не будет . ваше мнение?

интересная игрушка на шашлыки, позитивчик

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

Дык я же выложил) Вообще делал для себя и в целях эксперимента. У меня все стреляло как надо. Для основы я думаю многим подойдет. Главное что я сделал - это определил протокол и описал класс дял тагера. Функции лишь выстрел и прием попадания. Но все остальные функции по факту от них происходят. Ток команды в ик-пакете другие.

satelit 2
Offline
Зарегистрирован: 04.12.2016

тыкните пожалуйста в каком направлении копать. оружие собрал, дошел до каски, в котором ик датчики по нрф отправляют сигнал на оружие(функция счетов жизни и оружие не стреляет, списал у дмитрия осипова-ик удлиннитель). теперь не могу совершить обратную связь- если убит каска красным горит. какойнибуди пример скиньте пожалуйста

DeGiz
Offline
Зарегистрирован: 16.01.2017

Если не трудно, скинь сам скетч и какие порты были задействованы на плате. Только начинаю знакомится с Ардуино, опыт никакой. С уважением. 

bod.petr
Offline
Зарегистрирован: 12.01.2017

Здравствуйте, понимаю,много времени прошло, но я сейчас с этим же борюсь. Вопрос такой, а на солнце у вас работало?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

bod.petr пишет:
а на солнце у вас работало?

на Солнце - только у великого вождя северокорейского народа Ким Чен Ына работает.

bod.petr
Offline
Зарегистрирован: 12.01.2017

Блин, ну покупные то работают! Дело в том, что я скетч написал, но несколько другой чем тут в теме описывается, так вот, в сумерках, тучи, помещение все хорошо, а на солнце не фурычит. Код другой на приемник приходит. Уже по-моему все испробовал. Ни у кого идей нету?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

bod.petr пишет:
Ни у кого идей нету?

ночь!

bod.petr
Offline
Зарегистрирован: 12.01.2017

Ну мб завтра)

DezmontDeXa
Offline
Зарегистрирован: 09.02.2016

По поводу солнца:
Причина понятна: Помехи.
Я бы сделал так:
При выстреле шлем не один единственный пакет. А сразу штук 100. Главное, что бы выстрел имел некий ID. И все эти 100 пакетов будут иметь один и тот же ID. Так мы увеличиваем шансы прохода пакета без помех в 100 раз. А при получении цельного пакета - запоминаем ID и более эти пакеты не обрабатываем.
Для проверки целостности добавим контрольную сумму в конец пакета.

Ну или искать источники и приемники в каком-нибудь более специфичном спектре.

GreyZ
Offline
Зарегистрирован: 09.02.2018

Всем привет. 

С солнцем проблема на уровне физики, решить можно увеличивая мощность выстрела, например диодом tsal6105, оптикой или подобными решениями.

Отправление 100 пакетов несовместимо с протоколом MT и оборудованием того же LaserWar.

С другой стороны, есть время шока, которое 99 дополнительных пакетов нейтрализует, но все равно криво.

Из моих поделок: аптечка на ардуино уно (отправляет админкилл, выстрел, аммо, здоровье и т.д.), нож на микро (как у lw, отправляет админкилл, на макете тренировочного ножа), точка - аналог battlefield (тоже на ардуино, но без инфракрасного интерактива, просто две кнопки и захват c световой и звуковой индикацией).

В связи с тем, что ребятам нужно еще, планирую библиотеку для удобства, наверное возьму DezmontDeXa за основу.

В целом, спасибо за то, что разобрался в sendSony, очень пригодилось))

bod.petr
Offline
Зарегистрирован: 12.01.2017

Что за стал 6105? Ничего про такой не нашел,  а как реализован нож??  Поражение от него 

GreyZ
Offline
Зарегистрирован: 09.02.2018

TSAL6100 - модель инфракрасного диода, можно заказать на али, к примеру. Достаточно мощный, но угол всего 10градусов. Он использовался раньше (до появления "гибридной оптики") в излучателях Laserwar'а.

нож купил на алиэкспрессе, тренировочная модель, или для косплея, пластиковый, с ножнами. Встроил arguino pro mini в ручку, две батарейки 2032, диод, бьет на метра полтора, убивает сразу, отправляет пакет admin kill

https://laserwar.ru/index.php?do=static&page=lasertag-knife&menuitem=spec&menusubitem=spec11

Один в один как по ссылке.

Вообще, если лазервар корпус такой же использует, как на али, то нож так себе, очень хлипкий, в бою очень редко используется, мне ни разу не пригодился.

TarasR
Offline
Зарегистрирован: 23.06.2018

Доброго времени суток! А можете поделится скетчем аптечки?

GreyZ
Offline
Зарегистрирован: 09.02.2018

Добрый день!

Примерно так (сам скетч):

#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);
	

}

 

TarasR
Offline
Зарегистрирован: 23.06.2018

Спасибо! Буду собирать и тестить на выходных.

Palbl4
Offline
Зарегистрирован: 09.03.2019

GreyZ, огромное спасибо!

 

 

Aleksandr Makarov
Offline
Зарегистрирован: 01.02.2019

Добрый день, пытаюсь разобраться в посте #35/

Судя по скетчу при нажатии на кнопку, подключенную к 5 входу происходит  trans.Heal(); из библиотеки.

Подскажите, к какому выводу  ардуины подключать ИК-диод. Нигде явно это не прописано.

strarbit
Offline
Зарегистрирован: 12.06.2016

ledir to arduino pin ๓

Aleksandr Makarov
Offline
Зарегистрирован: 01.02.2019

Спасибо, опытным путем установил, что на d3. А вот где это задается - не вижу.

strarbit
Offline
Зарегистрирован: 12.06.2016

Aleksandr Makarov пишет:
Спасибо, опытным путем установил, что на d3. А вот где это задается - не вижу.

Please, sir.

i told you the truth. the output pin number ๓ == 3. Arduino\libraries\IRLibmaster\IRLibTimer.h

GreyZ
Offline
Зарегистрирован: 09.02.2018

Это задаётся в библиотеке, но поменять нельзя. Используйте д3 а то, что было на д3 перенесите на другой пин.)

Aleksandr Makarov
Offline
Зарегистрирован: 01.02.2019

starbit Thanks!

 

GreyZ огромное спасибо за библиотеку, помогла разобраться с формированием комманд. И с дешифровкой комманд. Таггер уже запилил, осталось датчиков дождаться в нужном количестве. Ребенок радуется пострелять пока по мишени.

Master86
Offline
Зарегистрирован: 05.12.2019

GreyZ, большое спасибо за скетч и библиотеку! Если не сложно могли бы поделиться скетчем для повязок (прием сигнала)? Буду очень благодарен. Моя почта - alexfulga@mail.ru 

korggrodno
Offline
Зарегистрирован: 05.06.2019

DezmontDeXa GreyZ kisoft

Поделитесь пожалуйста скетчем для тагера аптечки 

kg2@tut.by

Очень сильно понравился скетч GreyZ  для атечки выложенный в этой ветке.

Так хочется еще скетч для тагера?

Пре много благодарен.

 

HUNTER_73RUS
Offline
Зарегистрирован: 23.01.2021

Доброго времени суток!

Так кто-нибудь тагер доделал?

Можете поделиться скетчем?

e-mail: pavel.250776@yandex.ru

 

 

Palbl4
Offline
Зарегистрирован: 09.03.2019

Привет.

Лично я тагер не делал. Использую данную библиотеку только для девайсов ,типа гранат и аптечек.

GreyZ
Offline
Зарегистрирован: 09.02.2018

Тагер не делал, привет. Делал нож, он по сути Тагер, разницы нет. Код, приложенный выше подойдёт. Вообще, каждый девайс, если он уникальный, обладает уникальным кодом.. Все остальное из библиотеки. Поэтому нужно разбираться хоть немного в коде, просто скопипастить не вариант.

kvark
Offline
Зарегистрирован: 03.06.2021

Попробовал реализовать протокол MilesTag 2 с расширением от Laserwar, т.е. с подсчетом контрольной суммы - все работает, однако есть большое НО: процент искаженных пакетов весьма велик. Из десяти может быть неверных 3-5 пакетов. Алгоритм вычисления контрольной суммы их успешно отбрасывает, только есть две проблемы:

1. Получается, что, выстрелив 10 раз точно в цель, попаданий будет засчитано гораздо меньше. 
2. Иногда пакет искажается настолько сильно, что получается слишком коротким - не более 2 байт. Разумеется, алгоритм декодера решает, что это просто пакет выстрела без контрольной суммы, и начинает из него выделять данные об игроке, команде и уроне. Данные получаются, конечно, неверными. Интересно, как с этим борется Laserwar?

Как правило, данные искажаются в случае, если стрелок движется, либо на датчик приемника попадает край ИК-пятна излучателя. Тесты проводил дома, на улице пока не гонял.

Кто-нибудь сталкивался с такими проблемами? Есть идеи, как с этим бороться? 

Честно говоря, я уже не рад, что связался с MilesTag :). Гораздо проще было оставить свой собственный протокол, как я планировал изначально. Там все было просто: никаких номеров игроков, никакого урона, по ИК передавался только номер команды. Если приемник получал номер чужой команды, он фиксировал попадание. Причем помехоустойчивость у этой системы была отличной, т.к. номера команд были выбраны с большим разносом - 32, 64, 128 и 256. Т.о., вероятность того, что искаженный пакет совпадет с номером твоей команды (ну да, предполагалось играть без FF, т.е. огня по своим) была очень мала.

Palbl4
Offline
Зарегистрирован: 09.03.2019

Привет.
А что является приёмником: повязка LW или самодельное устройство?