From 5bd75b9d5d207e6b2b40a9f323281b96f6faf4dc Mon Sep 17 00:00:00 2001 From: Vladislav Ostapov Date: Sat, 10 Jan 2026 16:41:59 +0300 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=BE=D1=81=D0=B0=20=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=BD=D0=B0=20=D0=B0=D1=80=D0=B4=D1=83=D0=BF?= =?UTF-8?q?=D0=B8=D0=BB=D0=BE=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- air/main.cpp | 94 +++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/air/main.cpp b/air/main.cpp index 70b1ad4..a923bf9 100644 --- a/air/main.cpp +++ b/air/main.cpp @@ -95,8 +95,8 @@ struct SbusData { bool failsafe = false; bool ch17 = false, ch18 = false; static constexpr size_t NUM_CH = 18; - static constexpr int16_t SBUS_CH_MIN = 173 + 10; - static constexpr int16_t SBUS_CH_MAX = 1812 - 10; + static constexpr int16_t SBUS_CH_MIN = 173 + 20; + static constexpr int16_t SBUS_CH_MAX = 1812 - 20; int16_t ch[NUM_CH]; /* Message len */ @@ -112,42 +112,42 @@ struct SbusData { static constexpr uint8_t FAILSAFE_MASK_ = 0x08; uint8_t binaryBuffer[25]; - void fillDataBuf() { - typedef struct sbusChannels_s { - // 176 bits of data (11 bits per channel * 16 channels) = 22 bytes. - unsigned int chan0 : 11; - unsigned int chan1 : 11; - unsigned int chan2 : 11; - unsigned int chan3 : 11; - unsigned int chan4 : 11; - unsigned int chan5 : 11; - unsigned int chan6 : 11; - unsigned int chan7 : 11; - unsigned int chan8 : 11; - unsigned int chan9 : 11; - unsigned int chan10 : 11; - unsigned int chan11 : 11; - unsigned int chan12 : 11; - unsigned int chan13 : 11; - unsigned int chan14 : 11; - unsigned int chan15 : 11; - } __attribute__((__packed__)) sbusChannels_t; - static_assert(sizeof(sbusChannels_s) == 22); - struct sbusFrame_s { - uint8_t syncByte = HEADER_; - sbusChannels_t channels{}; - uint8_t flags{}; - /** - * The endByte is 0x00 on FrSky and some futaba RX's, on Some SBUS2 RX's the value indicates the telemetry byte that is sent after every 4th sbus frame. - * - * See https://github.com/cleanflight/cleanflight/issues/590#issuecomment-101027349 - * and - * https://github.com/cleanflight/cleanflight/issues/590#issuecomment-101706023 - */ - uint8_t endByte = FOOTER_; - } __attribute__ ((__packed__)); - static_assert(sizeof(sbusFrame_s) == sizeof(binaryBuffer)); + typedef struct sbusChannels_s { + // 176 bits of data (11 bits per channel * 16 channels) = 22 bytes. + unsigned int chan0 : 11; + unsigned int chan1 : 11; + unsigned int chan2 : 11; + unsigned int chan3 : 11; + unsigned int chan4 : 11; + unsigned int chan5 : 11; + unsigned int chan6 : 11; + unsigned int chan7 : 11; + unsigned int chan8 : 11; + unsigned int chan9 : 11; + unsigned int chan10 : 11; + unsigned int chan11 : 11; + unsigned int chan12 : 11; + unsigned int chan13 : 11; + unsigned int chan14 : 11; + unsigned int chan15 : 11; + } __attribute__((__packed__)) sbusChannels_t; + static_assert(sizeof(sbusChannels_s) == 22); + struct sbusFrame_s { + uint8_t syncByte = HEADER_; + sbusChannels_t channels{}; + uint8_t flags{}; + /** + * The endByte is 0x00 on FrSky and some futaba RX's, on Some SBUS2 RX's the value indicates the telemetry byte that is sent after every 4th sbus frame. + * + * See https://github.com/cleanflight/cleanflight/issues/590#issuecomment-101027349 + * and + * https://github.com/cleanflight/cleanflight/issues/590#issuecomment-101706023 + */ + uint8_t endByte = FOOTER_; + } __attribute__ ((__packed__)); + static_assert(sizeof(sbusFrame_s) == sizeof(binaryBuffer)); + void fillDataBuf() { auto* dest = reinterpret_cast(binaryBuffer); dest->syncByte = HEADER_; dest->channels.chan0 = std::min(std::max(ch[0], SBUS_CH_MIN), SBUS_CH_MAX); @@ -169,7 +169,7 @@ struct SbusData { dest->flags = 0; if (ch[16] >= (SBUS_CH_MAX + SBUS_CH_MAX) / 2) { dest->flags |= CH17_MASK_; } - if (ch[16] >= (SBUS_CH_MAX + SBUS_CH_MAX) / 2) { dest->flags |= CH18_MASK_; } + if (ch[17] >= (SBUS_CH_MAX + SBUS_CH_MAX) / 2) { dest->flags |= CH18_MASK_; } dest->endByte = FOOTER_; } @@ -234,6 +234,15 @@ public: return fd; } + int drain() { + int ret; + do { + ret = ioctl(fd, TCSBRK, 1); + } while (ret < 0 && errno == EINTR); + + return ret; + } + // Метод для записи данных в порт bool write(std::span data) { if (fd < 0) return false; @@ -245,7 +254,10 @@ public: } // Принудительная отправка данных - // tcdrain(fd); + if (drain() < 0) { + std::cerr << "Failed to flush data to serial port" << std::endl; + return false; + } return true; } }; @@ -289,8 +301,8 @@ int main(int argc, char* argv[]) { if (!data.empty()) { packetCount++; - for (int i = 0; i < data.size() && i < SbusData::NUM_CH; ++i) { - auto item = static_cast(data[i]); + for (int i = 0; i < SbusData::NUM_CH; ++i) { + auto item = i < data.size() ? static_cast(data[i]) : 1500.0; item -= 1000.0; item = std::min(item, 1000.0); item = std::max(item, 0.0);