#include // --- ПИНЫ RS485 (НЕЗЫБЛЕМЫЕ) --- #define INV_RX 4 #define INV_TX 5 #define INV_DE 6 #define BMS_RX 7 #define BMS_TX 15 #define BMS_DE 16 // Переменные для мониторинга через Serial float mVolt = 0; float mCurr = 0; int mSoc = 0; uint16_t getCRC(const uint8_t *buf, size_t len) { uint16_t crc = 0xFFFF; for (size_t pos = 0; pos < len; pos++) { crc ^= (uint16_t)buf[pos]; for (int i = 8; i != 0; i--) { if ((crc & 0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else crc >>= 1; } } return crc; } void setup() { // Serial для отладки (компьютер) Serial.begin(115200); // Serial1: Связь с Инвертором Serial1.begin(9600, SERIAL_8N1, INV_RX, INV_TX); // Serial2: Связь с BMS Serial2.begin(9600, SERIAL_8N1, BMS_RX, BMS_TX); pinMode(INV_DE, OUTPUT); pinMode(BMS_DE, OUTPUT); digitalWrite(INV_DE, LOW); digitalWrite(BMS_DE, LOW); Serial.println("--- GCE BRIDGE LIGHT VERSION START ---"); } void loop() { // 1. Проброс Инвертор -> BMS if (Serial1.available()) { digitalWrite(BMS_DE, HIGH); while (Serial1.available()) Serial2.write(Serial1.read()); Serial2.flush(); digitalWrite(BMS_DE, LOW); } // 2. Проброс BMS -> Инвертор + Подмена лимита if (Serial2.available()) { uint8_t buf[128]; int len = 0; uint32_t t = micros(); // Быстрый сбор пакета while (micros() - t < 15000 && len < 128) { if (Serial2.available()) { buf[len++] = Serial2.read(); t = micros(); } } if (len > 0) { // Если пришел основной пакет данных (43 байта) от Мастера (ID 01) if (len == 43 && buf[0] == 0x01 && buf[1] == 0x03) { // Извлекаем данные для контроля в Serial (по твоим логам) mVolt = (float)((buf[3] << 8) | buf[4]) * 0.01503f; mSoc = buf[14]; int16_t cRaw = (int16_t)((buf[32] << 8) | buf[33]); mCurr = (float)cRaw * 0.001f; // ПОДМЕНА ЛИМИТА ТОКА (75А) buf[21] = 0x1D; buf[22] = 0x4C; // Пересчет CRC uint16_t newCrc = getCRC(buf, len - 2); buf[len - 2] = newCrc & 0xFF; buf[len - 1] = (newCrc >> 8) & 0xFF; // Лог в консоль для проверки (можно закомментировать) Serial.printf("Master: %4.1fV | %d%% | %4.1fA (Sum: %4.1fA)\n", mVolt, mSoc, mCurr, mCurr * 3.0f); } // Мгновенная отправка инвертору digitalWrite(INV_DE, HIGH); Serial1.write(buf, len); Serial1.flush(); digitalWrite(INV_DE, LOW); } } }