websocket 속도 , task 조정
This commit is contained in:
@@ -220,6 +220,23 @@ SerialSettings serial2Settings = {115200, 8, 0, 1}; // ⭐ Serial2 추가
|
|||||||
// 전역 객체 (내부 SRAM)
|
// 전역 객체 (내부 SRAM)
|
||||||
SPIClass hspi(HSPI);
|
SPIClass hspi(HSPI);
|
||||||
// SPIClass vspi(FSPI); // ⭐ SDIO 사용으로 제거
|
// SPIClass vspi(FSPI); // ⭐ SDIO 사용으로 제거
|
||||||
|
// ========================================
|
||||||
|
// MCP2515 크리스탈 설정
|
||||||
|
// ========================================
|
||||||
|
// 8MHz 크리스탈: 500 Kbps까지 안정적
|
||||||
|
// 16MHz 크리스탈: 1 Mbps 고속 통신 권장 (고부하 대응)
|
||||||
|
//
|
||||||
|
// 사용법:
|
||||||
|
// - 하드웨어에 16MHz 크리스탈 장착 시: MCP_16MHZ
|
||||||
|
// - 하드웨어에 8MHz 크리스탈 장착 시: MCP_8MHZ
|
||||||
|
//
|
||||||
|
#define MCP_CRYSTAL MCP_16MHZ // ⭐ 16MHz 크리스탈 (1 Mbps 권장)
|
||||||
|
// #define MCP_CRYSTAL MCP_8MHZ // 8MHz 크리스탈 (500 Kbps까지)
|
||||||
|
|
||||||
|
// SPI 속도: 20MHz (MCP2515 최대 속도와 균형)
|
||||||
|
// 10MHz: 안정적이지만 느림
|
||||||
|
// 20MHz: 권장 (고속 + 안정성)
|
||||||
|
// 25MHz: 불안정할 수 있음
|
||||||
MCP2515 mcp2515(HSPI_CS, 20000000, &hspi);
|
MCP2515 mcp2515(HSPI_CS, 20000000, &hspi);
|
||||||
HardwareSerial SerialComm(1); // UART1
|
HardwareSerial SerialComm(1); // UART1
|
||||||
HardwareSerial Serial2Comm(2); // ⭐ UART2 추가
|
HardwareSerial Serial2Comm(2); // ⭐ UART2 추가
|
||||||
@@ -370,7 +387,7 @@ void resetMCP2515() {
|
|||||||
Serial.printf(" 3. Speed=%d, Mode=%d\n", (int)currentCanSpeed, (int)currentMcpMode);
|
Serial.printf(" 3. Speed=%d, Mode=%d\n", (int)currentCanSpeed, (int)currentMcpMode);
|
||||||
|
|
||||||
// 5. Bitrate 설정 (Configuration 모드에서)
|
// 5. Bitrate 설정 (Configuration 모드에서)
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
// 6. 필터/마스크 설정 (모든 메시지 수신)
|
// 6. 필터/마스크 설정 (모든 메시지 수신)
|
||||||
@@ -427,7 +444,7 @@ void resetMCP2515() {
|
|||||||
// 에러가 있으면 완전 리셋
|
// 에러가 있으면 완전 리셋
|
||||||
mcp2515.reset();
|
mcp2515.reset();
|
||||||
delay(50);
|
delay(50);
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
delay(10);
|
delay(10);
|
||||||
if (currentMcpMode == MCP_MODE_NORMAL) {
|
if (currentMcpMode == MCP_MODE_NORMAL) {
|
||||||
mcp2515.setNormalMode();
|
mcp2515.setNormalMode();
|
||||||
@@ -1386,7 +1403,7 @@ void canRxTask(void *parameter) {
|
|||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
// 2. Bitrate 재설정
|
// 2. Bitrate 재설정
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
// 3. 모든 에러 플래그 클리어
|
// 3. 모든 에러 플래그 클리어
|
||||||
@@ -1807,10 +1824,11 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
if (type == WStype_CONNECTED) {
|
if (type == WStype_CONNECTED) {
|
||||||
Serial.printf("[%u] ✅ WebSocket 연결됨\n", num);
|
Serial.printf("[%u] ✅ WebSocket 연결됨\n", num);
|
||||||
|
|
||||||
// 기본 설정 전송
|
// ⭐ 모든 데이터를 하나의 JSON으로 통합 전송 (빠른 연결)
|
||||||
DynamicJsonDocument settings(512);
|
DynamicJsonDocument allData(3072); // 통합 JSON
|
||||||
settings["type"] = "currentSettings";
|
allData["type"] = "initialData";
|
||||||
|
|
||||||
|
// 기본 설정
|
||||||
int speedIndex = 3;
|
int speedIndex = 3;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (canSpeedValues[i] == currentCanSpeed) {
|
if (canSpeedValues[i] == currentCanSpeed) {
|
||||||
@@ -1818,29 +1836,20 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings["canSpeed"] = speedIndex;
|
allData["canSpeed"] = speedIndex;
|
||||||
settings["mcpMode"] = (int)currentMcpMode;
|
allData["mcpMode"] = (int)currentMcpMode;
|
||||||
settings["autoTriggerEnabled"] = autoTriggerEnabled;
|
allData["autoTriggerEnabled"] = autoTriggerEnabled;
|
||||||
settings["autoTriggerLogCSV"] = autoTriggerLogCSV;
|
allData["autoTriggerLogCSV"] = autoTriggerLogCSV;
|
||||||
|
|
||||||
String json;
|
// Auto Trigger 설정도 포함
|
||||||
serializeJson(settings, json);
|
|
||||||
webSocket.sendTXT(num, json);
|
|
||||||
|
|
||||||
// Auto Trigger 설정도 전송
|
|
||||||
if (autoTriggerEnabled) {
|
if (autoTriggerEnabled) {
|
||||||
delay(50); // 메시지 간격
|
allData["logFormat"] = autoTriggerLogCSV ? "csv" : "bin";
|
||||||
|
allData["startLogic"] = startLogicOp;
|
||||||
|
allData["stopLogic"] = stopLogicOp;
|
||||||
|
allData["startFormula"] = startFormula;
|
||||||
|
allData["stopFormula"] = stopFormula;
|
||||||
|
|
||||||
DynamicJsonDocument autoTrigger(2048);
|
JsonArray startArray = allData.createNestedArray("startTriggers");
|
||||||
autoTrigger["type"] = "autoTriggers";
|
|
||||||
autoTrigger["enabled"] = autoTriggerEnabled;
|
|
||||||
autoTrigger["logFormat"] = autoTriggerLogCSV ? "csv" : "bin";
|
|
||||||
autoTrigger["startLogic"] = startLogicOp;
|
|
||||||
autoTrigger["stopLogic"] = stopLogicOp;
|
|
||||||
autoTrigger["startFormula"] = startFormula;
|
|
||||||
autoTrigger["stopFormula"] = stopFormula;
|
|
||||||
|
|
||||||
JsonArray startArray = autoTrigger.createNestedArray("startTriggers");
|
|
||||||
for (int i = 0; i < startTriggerCount; i++) {
|
for (int i = 0; i < startTriggerCount; i++) {
|
||||||
JsonObject t = startArray.createNestedObject();
|
JsonObject t = startArray.createNestedObject();
|
||||||
char idStr[10];
|
char idStr[10];
|
||||||
@@ -1853,7 +1862,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
t["enabled"] = startTriggers[i].enabled;
|
t["enabled"] = startTriggers[i].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray stopArray = autoTrigger.createNestedArray("stopTriggers");
|
JsonArray stopArray = allData.createNestedArray("stopTriggers");
|
||||||
for (int i = 0; i < stopTriggerCount; i++) {
|
for (int i = 0; i < stopTriggerCount; i++) {
|
||||||
JsonObject t = stopArray.createNestedObject();
|
JsonObject t = stopArray.createNestedObject();
|
||||||
char idStr[10];
|
char idStr[10];
|
||||||
@@ -1865,11 +1874,12 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
t["value"] = (long)stopTriggers[i].value;
|
t["value"] = (long)stopTriggers[i].value;
|
||||||
t["enabled"] = stopTriggers[i].enabled;
|
t["enabled"] = stopTriggers[i].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
String autoJson;
|
|
||||||
serializeJson(autoTrigger, autoJson);
|
|
||||||
webSocket.sendTXT(num, autoJson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ⭐ 하나의 메시지로 전송 (delay 제거)
|
||||||
|
String json;
|
||||||
|
serializeJson(allData, json);
|
||||||
|
webSocket.sendTXT(num, json);
|
||||||
}
|
}
|
||||||
else if (type == WStype_TEXT) {
|
else if (type == WStype_TEXT) {
|
||||||
DynamicJsonDocument doc(44384);
|
DynamicJsonDocument doc(44384);
|
||||||
@@ -2138,7 +2148,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
// ⭐⭐⭐ MCP2515 리셋 제거! (CAN 수신 중단 방지)
|
// ⭐⭐⭐ MCP2515 리셋 제거! (CAN 수신 중단 방지)
|
||||||
// 속도 변경은 로깅 중지 후 수동으로만 가능하도록 변경
|
// 속도 변경은 로깅 중지 후 수동으로만 가능하도록 변경
|
||||||
// mcp2515.reset();
|
// mcp2515.reset();
|
||||||
// mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
// mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
// setMCP2515Mode(currentMcpMode);
|
// setMCP2515Mode(currentMcpMode);
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
@@ -2263,7 +2273,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
// ⭐⭐⭐ MCP2515 리셋 제거! (CAN 수신 중단 방지)
|
// ⭐⭐⭐ MCP2515 리셋 제거! (CAN 수신 중단 방지)
|
||||||
// 속도 변경은 로깅 중지 후 수동으로만 가능하도록 변경
|
// 속도 변경은 로깅 중지 후 수동으로만 가능하도록 변경
|
||||||
// mcp2515.reset();
|
// mcp2515.reset();
|
||||||
// mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
// mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
// setMCP2515Mode(currentMcpMode);
|
// setMCP2515Mode(currentMcpMode);
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
@@ -2875,10 +2885,10 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
// Web Update Task
|
// Web Update Task
|
||||||
// ========================================
|
// ========================================
|
||||||
void webUpdateTask(void *parameter) {
|
void webUpdateTask(void *parameter) {
|
||||||
const TickType_t xDelay = pdMS_TO_TICKS(200); // ⭐ 100ms → 200ms (WiFi 안정성 향상)
|
const TickType_t xDelay = pdMS_TO_TICKS(100); // ⭐ 200ms → 100ms (더 빠른 업데이트)
|
||||||
|
|
||||||
// 🆕 초기화 대기 (부팅 직후 안정화)
|
// 🆕 초기화 대기 단축 (부팅 직후 안정화)
|
||||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
vTaskDelay(pdMS_TO_TICKS(500)); // ⭐ 2000ms → 500ms (빠른 연결)
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
webSocket.loop();
|
webSocket.loop();
|
||||||
@@ -3136,7 +3146,33 @@ void webUpdateTask(void *parameter) {
|
|||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
|
// ⭐ 리셋 원인 확인 (전원 부족 감지)
|
||||||
|
esp_reset_reason_t reset_reason = esp_reset_reason();
|
||||||
|
if (reset_reason == ESP_RST_BROWNOUT) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("╔════════════════════════════════════════════╗");
|
||||||
|
Serial.println("║ 🚨 브라운아웃 리셋 감지! ║");
|
||||||
|
Serial.println("║ ║");
|
||||||
|
Serial.println("║ 원인: 전원 공급 부족 ║");
|
||||||
|
Serial.println("║ ║");
|
||||||
|
Serial.println("║ 필요 전류: ║");
|
||||||
|
Serial.println("║ - 평균: 300 mA ║");
|
||||||
|
Serial.println("║ - 피크: 550 mA (WiFi TX + SD Write) ║");
|
||||||
|
Serial.println("║ ║");
|
||||||
|
Serial.println("║ 해결 방법: ║");
|
||||||
|
Serial.println("║ 1. 5V 1A USB 어댑터 사용 (권장) ║");
|
||||||
|
Serial.println("║ 2. USB 케이블 교체 (짧고 굵은 케이블) ║");
|
||||||
|
Serial.println("║ 3. USB 3.0 포트 사용 (900mA 지원) ║");
|
||||||
|
Serial.println("╚════════════════════════════════════════════╝");
|
||||||
|
Serial.println("");
|
||||||
|
delay(5000); // 경고 메시지 읽을 시간
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐ WiFi 전력 최적화 (전류 소비 감소)
|
||||||
WiFi.setSleep(false);
|
WiFi.setSleep(false);
|
||||||
|
WiFi.setTxPower(WIFI_POWER_15dBm); // 19.5dBm → 15dBm (전류 절감)
|
||||||
|
|
||||||
Serial.println("\n========================================");
|
Serial.println("\n========================================");
|
||||||
Serial.println(" Byun CAN Logger + Serial Terminal");
|
Serial.println(" Byun CAN Logger + Serial Terminal");
|
||||||
Serial.println(" Version 2.3 - PSRAM Optimized");
|
Serial.println(" Version 2.3 - PSRAM Optimized");
|
||||||
@@ -3198,7 +3234,7 @@ void setup() {
|
|||||||
|
|
||||||
// 4. Configuration 모드에서 설정 (중요: 이 순서대로!)
|
// 4. Configuration 모드에서 설정 (중요: 이 순서대로!)
|
||||||
Serial.println(" 3. Bitrate 설정...");
|
Serial.println(" 3. Bitrate 설정...");
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
// 5. 필터/마스크 설정 (모든 메시지 수신)
|
// 5. 필터/마스크 설정 (모든 메시지 수신)
|
||||||
@@ -3275,7 +3311,7 @@ void setup() {
|
|||||||
// 에러가 있으면 완전 리셋 재시도
|
// 에러가 있으면 완전 리셋 재시도
|
||||||
mcp2515.reset();
|
mcp2515.reset();
|
||||||
delay(50);
|
delay(50);
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_CRYSTAL);
|
||||||
delay(10);
|
delay(10);
|
||||||
mcp2515.clearRXnOVRFlags();
|
mcp2515.clearRXnOVRFlags();
|
||||||
mcp2515.clearInterrupts();
|
mcp2515.clearInterrupts();
|
||||||
@@ -3658,8 +3694,8 @@ void setup() {
|
|||||||
// - TX: CAN 전송
|
// - TX: CAN 전송
|
||||||
// - SEQ: 시퀀스 재생
|
// - SEQ: 시퀀스 재생
|
||||||
// - MONITOR: 상태 모니터링
|
// - MONITOR: 상태 모니터링
|
||||||
xTaskCreatePinnedToCore(canRxTask, "CAN_RX", 12288, NULL, 24, &canRxTaskHandle, 1); // ⭐ 8KB → 12KB, Pri 24 (최고)
|
xTaskCreatePinnedToCore(canRxTask, "CAN_RX", 12288, NULL, 20, &canRxTaskHandle, 1); // ⭐ 8KB → 12KB, Pri 24 (최고)
|
||||||
xTaskCreatePinnedToCore(webUpdateTask, "WEB_UPDATE", 12288, NULL, 4, &webTaskHandle, 1); // ⭐ Core 0 → 1, Pri 4 (SD와 분리)
|
xTaskCreatePinnedToCore(webUpdateTask, "WEB_UPDATE", 12288, NULL, 16, &webTaskHandle, 1); // ⭐ Core 0 → 1, Pri 4 (SD와 분리)
|
||||||
xTaskCreatePinnedToCore(txTask, "TX", 4096, NULL, 3, NULL, 1); // Pri 3
|
xTaskCreatePinnedToCore(txTask, "TX", 4096, NULL, 3, NULL, 1); // Pri 3
|
||||||
xTaskCreatePinnedToCore(sequenceTask, "SEQ", 4096, NULL, 2, NULL, 1); // Pri 2
|
xTaskCreatePinnedToCore(sequenceTask, "SEQ", 4096, NULL, 2, NULL, 1); // Pri 2
|
||||||
xTaskCreatePinnedToCore(sdMonitorTask, "SD_MONITOR", 4096, NULL, 1, NULL, 1); // Pri 1
|
xTaskCreatePinnedToCore(sdMonitorTask, "SD_MONITOR", 4096, NULL, 1, NULL, 1); // Pri 1
|
||||||
|
|||||||
Reference in New Issue
Block a user