#pragma once #include /*////////////////////////////////////////////////////////////////////////////////////// Для работы в паре положить декодер в энкодер */// Адресация с 1 до 65 499 #define IR_Broadcast 65000 // 65 500 ~ 65 535 - широковещательные пакеты (всем), возможно разделить на 35 типов /* Адрес 0 запрещен и зарезервирован под NULL, либо тесты IR_MSG_ACCEPT с адреса 0 воспринимается всеми устройствами Адресное пространство: Излучатели контрольных точек: 1000 ~ 1999 Излучатели без обратной связиЖ 2000 ~ 2999 Излучатели светофоров: 3000 ~ 3999 /```````````````````````````````````````````````` data pack `````````````````````````````````````````````\                                                                                                                                             {``````````} [````````````````````````] [````````````````````] [````````````````````````] [``````````````] { msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [ data bytes ] [ CRC Bytes ] {..........} [........................] [....................] [........................] [..............]                                                                                                            { aka size } [addr_self_H][addr_self_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ] |     0           1            2              3         4          5                         |       |     \____________________________________________________________________________________________/       |     |                                                                                                    |     \____________________________________________________________________________________________________/     msg type:                                         //  __________                                         // | 01234567 |                                         //  ----------                                         // | xxx..... | = тип сообщения                                         // | ...xxxxx | = длина (максимум 32 бита)                                         //  ---------- */ #define IR_MSG_ 0U // | 000..... | = = ?? #define IR_MSG_ACCEPT 1U // | 001..... | = */ /* = подтверждение #define IR_MSG_REQUEST 2U // | 010..... | = */ /* = запрос #define IR_MSG_ 3U // | 011..... | = */ /* = ?? #define IR_MSG_ 4U // | 100..... | = */ /* = ?? #define IR_MSG_ 5U // | 101..... | = */ /* = ?? #define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = */ /* = данные, не требующие подтверждения //                                      // | \\\xxxxx | = = L длина данных #define IR_MSG_DATA_ACCEPT 7U // | 111..... | = */ /* = данные требующие подтверждения //                                      // | \\\xxxxx | = = L длина данных /*   // ---------- /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\                                                                                                                        {``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] { msg type } [ addr_self uint16_t ] [ CRC Bytes ]      { msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] {..........} [........................] [..............]      {..........} [........................] [........................] [..............]                                                                                                                                                   { 001..... } [addr_self_H][addr_self_L] [ crc1 ][ crc2 ]      { 010..... } [addr_self_H][addr_self_L] [addr_self_H][addr_self_L] [ crc1 ][ crc2 ] |     0            1           2           3       4          |     0            1           2              3           4           5       6     \__________________________________________/       |          \_____________________________________________________________________/       |     |                                                  |          |                                                                             |     \__________________________________________________/          \_____________________________________________________________________________/     */ #define IR_MASK_MSG_TYPE 0b00000111 #define IR_MASK_MSG_INFO 0b00011111 /* /////////////////////////////////////////////////////////////////////////////////////*/ typedef uint16_t crc_t; #define bytePerPack 3 // колличество байтов в пакете #ifndef freeFrec #define freeFrec true #endif #define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают (передатчик) #define preambPulse 3 #define disablePairDec false // Отключать парный приёмник, возможны баги, используйте setBlindDecoders() ///////////////////////////////////////////////////////////////////////////////////// #define bitPerByte 8U // Колличество бит в байте #define addrBytes 2 #define msgBytes 1 #define crcBytes 2 #define poly1 0x31 #define poly2 0x8C #define syncBits 3U // количество битов синхронизации #define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes) #define preambFronts (preambPulse*2) // количество фронтов преамбулы (Приём) #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) // колличество переключений преамбулы (Передача) #define carrierFrec 38000U // частота несущей (Приём/Передача) #define carrierPeriod (1000000U/carrierFrec) // период несущей в us (Приём) // В процессе работы значения будут отклонятся в соответствии с предыдущим битом #define bitActiveTakts 25U // длительность высокого уровня в тактах #define bitPauseTakts 6U // длительность низкого уровня в тактах #define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define tolerance 300U class IR_FOX { private: bool isSending = false; protected: uint8_t crc8(uint8_t* data, uint8_t start, uint8_t end, uint8_t poly) { //TODO: сделать возможность межбайтовой проверки uint8_t crc = 0xff; size_t i, j; for (i = start; i < end; i++) { crc ^= data[i]; for (j = 0; j < 8; j++) { if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ poly); else crc <<= 1; } } return crc; } // public: /// @brief Вывод массива байт в строковом формате /// @param d Указатель на массив /// @param s Размер массива /// @param mode Формат вывода DEC, BIN /// @return Готовая для вывода строка String printBytes(uint8_t* d, uint8_t s, uint8_t mode = 10) { String str = ""; uint8_t control = bitPerByte; uint8_t* _data = d; switch (mode) { case 2: for (size_t i = 0; i < s * 8; i++) { if (i == control) { str += " "; control += bitPerByte; } str += _data[(i / 8)] >> (7 - (i % 8)) & 1; } break; case 10: for (size_t i = 0; i < s; i++) { str += _data[i]; str += " "; } break; default: break; } str += " "; return str; } };