리셋 시 세팅저장
This commit is contained in:
@@ -275,6 +275,10 @@ char startLogicOp[4] = "OR";
|
|||||||
char stopLogicOp[4] = "OR";
|
char stopLogicOp[4] = "OR";
|
||||||
bool autoTriggerActive = false;
|
bool autoTriggerActive = false;
|
||||||
bool autoTriggerLogCSV = false; // 🆕 Auto Trigger용 CSV 형식 설정
|
bool autoTriggerLogCSV = false; // 🆕 Auto Trigger용 CSV 형식 설정
|
||||||
|
|
||||||
|
// 🆕 File Format 저장 변수
|
||||||
|
bool savedCanLogFormatCSV = false; // 저장된 CAN 로그 형식 (BIN=false, CSV=true)
|
||||||
|
|
||||||
volatile bool serialLoggingEnabled = false;
|
volatile bool serialLoggingEnabled = false;
|
||||||
volatile bool serial2LoggingEnabled = false; // ⭐ Serial2 추가
|
volatile bool serial2LoggingEnabled = false; // ⭐ Serial2 추가
|
||||||
volatile bool sdCardReady = false;
|
volatile bool sdCardReady = false;
|
||||||
@@ -298,7 +302,7 @@ volatile uint64_t serialLogStartTime = 0;
|
|||||||
volatile uint64_t serial2LogStartTime = 0; // ⭐ Serial2 추가
|
volatile uint64_t serial2LogStartTime = 0; // ⭐ Serial2 추가
|
||||||
|
|
||||||
// 기타 전역 변수
|
// 기타 전역 변수
|
||||||
MCP2515Mode currentMcpMode = MCP_MODE_LISTEN_ONLY;
|
MCP2515Mode currentMcpMode;
|
||||||
SoftWire rtcWire(RTC_SDA, RTC_SCL);
|
SoftWire rtcWire(RTC_SDA, RTC_SCL);
|
||||||
char rtcSyncBuffer[20];
|
char rtcSyncBuffer[20];
|
||||||
CAN_SPEED currentCanSpeed = CAN_1000KBPS;
|
CAN_SPEED currentCanSpeed = CAN_1000KBPS;
|
||||||
@@ -348,12 +352,23 @@ void resetMCP2515() {
|
|||||||
// 4. MCP2515 재초기화
|
// 4. MCP2515 재초기화
|
||||||
mcp2515.reset();
|
mcp2515.reset();
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
|
// ✅ Preferences에서 설정 불러오기
|
||||||
|
preferences.begin("can-logger", true);
|
||||||
|
int speedIndex = preferences.getInt("can_speed", 3);
|
||||||
|
if (speedIndex >= 0 && speedIndex < 4) {
|
||||||
|
currentCanSpeed = canSpeedValues[speedIndex];
|
||||||
|
}
|
||||||
|
int savedMode = preferences.getInt("mcp_mode", 1);
|
||||||
|
if (savedMode >= 0 && savedMode <= 3) {
|
||||||
|
currentMcpMode = (MCP2515Mode)savedMode;
|
||||||
|
}
|
||||||
|
preferences.end();
|
||||||
|
|
||||||
|
Serial.printf("🔧 resetMCP2515: Speed=%d, Mode=%d\n", (int)currentCanSpeed, (int)currentMcpMode);
|
||||||
|
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
||||||
delay(10);
|
delay(10);
|
||||||
mcp2515.setListenOnlyMode();
|
|
||||||
//currentMcpMode = MCP_MODE_LISTEN_ONLY;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 5. 모드 설정 (Normal/Loopback/Listen Only)
|
// 5. 모드 설정 (Normal/Loopback/Listen Only)
|
||||||
if (currentMcpMode == MCP_MODE_NORMAL) {
|
if (currentMcpMode == MCP_MODE_NORMAL) {
|
||||||
@@ -639,10 +654,15 @@ void loadSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int savedMode = preferences.getInt("mcp_mode", 1);
|
int savedMode = preferences.getInt("mcp_mode", 1);
|
||||||
|
Serial.printf("📥 loadSettings: MCP Mode = %d\n", savedMode);
|
||||||
if (savedMode >= 0 && savedMode <= 3) {
|
if (savedMode >= 0 && savedMode <= 3) {
|
||||||
currentMcpMode = (MCP2515Mode)savedMode;
|
currentMcpMode = (MCP2515Mode)savedMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 File Format 불러오기
|
||||||
|
savedCanLogFormatCSV = preferences.getBool("can_format_csv", false);
|
||||||
|
Serial.printf("📥 loadSettings: CAN Format = %s\n", savedCanLogFormatCSV ? "CSV" : "BIN");
|
||||||
|
|
||||||
loadSerialSettings();
|
loadSerialSettings();
|
||||||
preferences.end();
|
preferences.end();
|
||||||
}
|
}
|
||||||
@@ -833,9 +853,19 @@ void saveAutoTriggerSettings() {
|
|||||||
|
|
||||||
preferences.putBool("enabled", autoTriggerEnabled);
|
preferences.putBool("enabled", autoTriggerEnabled);
|
||||||
preferences.putBool("logCSV", autoTriggerLogCSV); // 🆕 로그 형식 저장
|
preferences.putBool("logCSV", autoTriggerLogCSV); // 🆕 로그 형식 저장
|
||||||
|
Serial.printf("💾 Save: autoTriggerLogCSV = %d\n", autoTriggerLogCSV);
|
||||||
preferences.putString("start_logic", startLogicOp);
|
preferences.putString("start_logic", startLogicOp);
|
||||||
preferences.putString("stop_logic", stopLogicOp);
|
preferences.putString("stop_logic", stopLogicOp);
|
||||||
|
|
||||||
|
// 디버그: Start Triggers 저장
|
||||||
|
Serial.printf("💾 Save: startTriggerCount = %d\n", startTriggerCount);
|
||||||
|
for (int i = 0; i < startTriggerCount; i++) {
|
||||||
|
Serial.printf(" [%d] ID=0x%X, Bit=%d, Len=%d, Op=%s, Val=%ld, En=%d\n",
|
||||||
|
i, startTriggers[i].canId, startTriggers[i].startBit,
|
||||||
|
startTriggers[i].bitLength, startTriggers[i].op,
|
||||||
|
startTriggers[i].value, startTriggers[i].enabled);
|
||||||
|
}
|
||||||
|
|
||||||
preferences.putInt("start_count", startTriggerCount);
|
preferences.putInt("start_count", startTriggerCount);
|
||||||
for (int i = 0; i < startTriggerCount; i++) {
|
for (int i = 0; i < startTriggerCount; i++) {
|
||||||
char key[32];
|
char key[32];
|
||||||
@@ -884,6 +914,7 @@ void loadAutoTriggerSettings() {
|
|||||||
|
|
||||||
autoTriggerEnabled = preferences.getBool("enabled", false);
|
autoTriggerEnabled = preferences.getBool("enabled", false);
|
||||||
autoTriggerLogCSV = preferences.getBool("logCSV", false); // 🆕 로그 형식 로드
|
autoTriggerLogCSV = preferences.getBool("logCSV", false); // 🆕 로그 형식 로드
|
||||||
|
Serial.printf("📥 Load: autoTriggerLogCSV = %d\n", autoTriggerLogCSV);
|
||||||
preferences.getString("start_logic", startLogicOp, sizeof(startLogicOp));
|
preferences.getString("start_logic", startLogicOp, sizeof(startLogicOp));
|
||||||
preferences.getString("stop_logic", stopLogicOp, sizeof(stopLogicOp));
|
preferences.getString("stop_logic", stopLogicOp, sizeof(stopLogicOp));
|
||||||
|
|
||||||
@@ -914,6 +945,15 @@ void loadAutoTriggerSettings() {
|
|||||||
startTriggers[i].enabled = preferences.getBool(key, true);
|
startTriggers[i].enabled = preferences.getBool(key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 디버그: Start Triggers 출력
|
||||||
|
Serial.printf("📥 Load: startTriggerCount = %d\n", startTriggerCount);
|
||||||
|
for (int i = 0; i < startTriggerCount; i++) {
|
||||||
|
Serial.printf(" [%d] ID=0x%X, Bit=%d, Len=%d, Op=%s, Val=%ld, En=%d\n",
|
||||||
|
i, startTriggers[i].canId, startTriggers[i].startBit,
|
||||||
|
startTriggers[i].bitLength, startTriggers[i].op,
|
||||||
|
startTriggers[i].value, startTriggers[i].enabled);
|
||||||
|
}
|
||||||
|
|
||||||
stopTriggerCount = preferences.getInt("stop_count", 0);
|
stopTriggerCount = preferences.getInt("stop_count", 0);
|
||||||
if (stopTriggerCount > MAX_TRIGGERS) stopTriggerCount = MAX_TRIGGERS;
|
if (stopTriggerCount > MAX_TRIGGERS) stopTriggerCount = MAX_TRIGGERS;
|
||||||
|
|
||||||
@@ -960,6 +1000,12 @@ void saveSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
preferences.putInt("mcp_mode", (int)currentMcpMode);
|
preferences.putInt("mcp_mode", (int)currentMcpMode);
|
||||||
|
Serial.printf("💾 MCP Mode 저장: %d\n", (int)currentMcpMode);
|
||||||
|
|
||||||
|
// 🆕 File Format 저장
|
||||||
|
preferences.putBool("can_format_csv", savedCanLogFormatCSV);
|
||||||
|
Serial.printf("💾 CAN Format 저장: %s\n", savedCanLogFormatCSV ? "CSV" : "BIN");
|
||||||
|
|
||||||
saveSerialSettings();
|
saveSerialSettings();
|
||||||
preferences.end();
|
preferences.end();
|
||||||
}
|
}
|
||||||
@@ -1082,6 +1128,7 @@ void rtcSyncTask(void *parameter) {
|
|||||||
// MCP2515 모드
|
// MCP2515 모드
|
||||||
// ========================================
|
// ========================================
|
||||||
bool setMCP2515Mode(MCP2515Mode mode) {
|
bool setMCP2515Mode(MCP2515Mode mode) {
|
||||||
|
Serial.printf("🔧 MCP Mode 변경 요청: %d → ", (int)mode);
|
||||||
const char* modeName;
|
const char* modeName;
|
||||||
MCP2515::ERROR result;
|
MCP2515::ERROR result;
|
||||||
|
|
||||||
@@ -1652,7 +1699,75 @@ void sequenceTask(void *parameter) {
|
|||||||
// WebSocket 이벤트 처리 (중요!)
|
// WebSocket 이벤트 처리 (중요!)
|
||||||
// ========================================
|
// ========================================
|
||||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
|
void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
|
||||||
if (type == WStype_TEXT) {
|
// 🆕 WebSocket 연결 시 현재 설정 전송
|
||||||
|
if (type == WStype_CONNECTED) {
|
||||||
|
Serial.printf("[%u] ✅ WebSocket 연결됨\n", num);
|
||||||
|
|
||||||
|
// 기본 설정 전송
|
||||||
|
DynamicJsonDocument settings(512);
|
||||||
|
settings["type"] = "currentSettings";
|
||||||
|
|
||||||
|
int speedIndex = 3;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (canSpeedValues[i] == currentCanSpeed) {
|
||||||
|
speedIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings["canSpeed"] = speedIndex;
|
||||||
|
settings["mcpMode"] = (int)currentMcpMode;
|
||||||
|
settings["autoTriggerEnabled"] = autoTriggerEnabled;
|
||||||
|
settings["autoTriggerLogCSV"] = autoTriggerLogCSV;
|
||||||
|
|
||||||
|
String json;
|
||||||
|
serializeJson(settings, json);
|
||||||
|
webSocket.sendTXT(num, json);
|
||||||
|
|
||||||
|
// Auto Trigger 설정도 전송
|
||||||
|
if (autoTriggerEnabled) {
|
||||||
|
delay(50); // 메시지 간격
|
||||||
|
|
||||||
|
DynamicJsonDocument autoTrigger(2048);
|
||||||
|
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++) {
|
||||||
|
JsonObject t = startArray.createNestedObject();
|
||||||
|
char idStr[10];
|
||||||
|
sprintf(idStr, "0x%03X", startTriggers[i].canId);
|
||||||
|
t["canId"] = idStr;
|
||||||
|
t["startBit"] = startTriggers[i].startBit;
|
||||||
|
t["bitLength"] = startTriggers[i].bitLength;
|
||||||
|
t["op"] = startTriggers[i].op;
|
||||||
|
t["value"] = (long)startTriggers[i].value;
|
||||||
|
t["enabled"] = startTriggers[i].enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray stopArray = autoTrigger.createNestedArray("stopTriggers");
|
||||||
|
for (int i = 0; i < stopTriggerCount; i++) {
|
||||||
|
JsonObject t = stopArray.createNestedObject();
|
||||||
|
char idStr[10];
|
||||||
|
sprintf(idStr, "0x%03X", stopTriggers[i].canId);
|
||||||
|
t["canId"] = idStr;
|
||||||
|
t["startBit"] = stopTriggers[i].startBit;
|
||||||
|
t["bitLength"] = stopTriggers[i].bitLength;
|
||||||
|
t["op"] = stopTriggers[i].op;
|
||||||
|
t["value"] = (long)stopTriggers[i].value;
|
||||||
|
t["enabled"] = stopTriggers[i].enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
String autoJson;
|
||||||
|
serializeJson(autoTrigger, autoJson);
|
||||||
|
webSocket.sendTXT(num, autoJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == WStype_TEXT) {
|
||||||
DynamicJsonDocument doc(44384);
|
DynamicJsonDocument doc(44384);
|
||||||
DeserializationError error = deserializeJson(doc, payload);
|
DeserializationError error = deserializeJson(doc, payload);
|
||||||
|
|
||||||
@@ -2242,6 +2357,23 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
|||||||
serializeJson(response, json);
|
serializeJson(response, json);
|
||||||
webSocket.sendTXT(num, json);
|
webSocket.sendTXT(num, json);
|
||||||
}
|
}
|
||||||
|
// 🆕 CAN File Format 저장 명령 (메인 페이지용)
|
||||||
|
else if (strcmp(cmd, "saveCanFormat") == 0) {
|
||||||
|
const char* format = doc["format"];
|
||||||
|
if (format) {
|
||||||
|
savedCanLogFormatCSV = (strcmp(format, "csv") == 0);
|
||||||
|
saveSettings();
|
||||||
|
Serial.printf("💾 CAN File Format 저장: %s\n", savedCanLogFormatCSV ? "CSV" : "BIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument response(128);
|
||||||
|
response["type"] = "canFormatSaved";
|
||||||
|
response["format"] = savedCanLogFormatCSV ? "csv" : "bin";
|
||||||
|
|
||||||
|
String json;
|
||||||
|
serializeJson(response, json);
|
||||||
|
webSocket.sendTXT(num, json);
|
||||||
|
}
|
||||||
else if (strcmp(cmd, "setStartTriggers") == 0) {
|
else if (strcmp(cmd, "setStartTriggers") == 0) {
|
||||||
JsonArray triggers = doc["triggers"];
|
JsonArray triggers = doc["triggers"];
|
||||||
strcpy(startLogicOp, doc["logic"] | "OR");
|
strcpy(startLogicOp, doc["logic"] | "OR");
|
||||||
@@ -2698,6 +2830,9 @@ void webUpdateTask(void *parameter) {
|
|||||||
doc["lowVoltage"] = powerStatus.lowVoltage;
|
doc["lowVoltage"] = powerStatus.lowVoltage;
|
||||||
doc["mcpMode"] = (int)currentMcpMode;
|
doc["mcpMode"] = (int)currentMcpMode;
|
||||||
|
|
||||||
|
// 🆕 저장된 File Format 전송
|
||||||
|
doc["savedCanFormat"] = savedCanLogFormatCSV ? "csv" : "bin";
|
||||||
|
|
||||||
if (loggingEnabled && currentFilename[0] != '\0') {
|
if (loggingEnabled && currentFilename[0] != '\0') {
|
||||||
doc["currentFile"] = String(currentFilename);
|
doc["currentFile"] = String(currentFilename);
|
||||||
} else {
|
} else {
|
||||||
@@ -2925,11 +3060,19 @@ void setup() {
|
|||||||
|
|
||||||
mcp2515.reset();
|
mcp2515.reset();
|
||||||
delay(100);
|
delay(100);
|
||||||
|
// ✅ loadSettings()에서 이미 불러왔으므로 중복 제거
|
||||||
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
mcp2515.setBitrate(currentCanSpeed, MCP_8MHZ);
|
||||||
delay(10);
|
delay(10);
|
||||||
|
Serial.printf("🔧 Setup: MCP Mode = %d\n", (int)currentMcpMode);
|
||||||
|
|
||||||
|
// 5. 모드 설정 (Normal/Loopback/Listen Only)
|
||||||
|
if (currentMcpMode == MCP_MODE_NORMAL) {
|
||||||
|
mcp2515.setNormalMode();
|
||||||
|
} else if (currentMcpMode == MCP_MODE_LOOPBACK) {
|
||||||
|
mcp2515.setLoopbackMode();
|
||||||
|
} else {
|
||||||
mcp2515.setListenOnlyMode();
|
mcp2515.setListenOnlyMode();
|
||||||
//currentMcpMode = MCP_MODE_LISTEN_ONLY;
|
}
|
||||||
currentMcpMode =(MCP2515Mode)preferences.getInt("mcp_mode", 1);
|
|
||||||
|
|
||||||
delay(50);
|
delay(50);
|
||||||
|
|
||||||
@@ -3139,4 +3282,3 @@ void loop() {
|
|||||||
lastPrint = millis();
|
lastPrint = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
index.h
48
index.h
@@ -971,6 +971,8 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
<span class="format-info">(Text - Excel Ready)</span>
|
<span class="format-info">(Text - Excel Ready)</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<button onclick="saveFileFormat()" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 8px 16px;">💾 Save</button>
|
||||||
|
<span id="format-save-status" style="color: #11998e; font-size: 0.85em; font-weight: 600;"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-row">
|
<div class="control-row">
|
||||||
<button onclick="startLogging()" style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);">Start Logging</button>
|
<button onclick="startLogging()" style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);">Start Logging</button>
|
||||||
@@ -1153,6 +1155,9 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
let commentingFile = '';
|
let commentingFile = '';
|
||||||
// hasInitialSync 제거 - 매번 자동 동기화
|
// hasInitialSync 제거 - 매번 자동 동기화
|
||||||
|
|
||||||
|
// 🆕 File Format 동기화 플래그
|
||||||
|
window.canFormatSynced = false;
|
||||||
|
|
||||||
// 🎯 Auto Trigger 전역 변수
|
// 🎯 Auto Trigger 전역 변수
|
||||||
let startTriggers = [];
|
let startTriggers = [];
|
||||||
let stopTriggers = [];
|
let stopTriggers = [];
|
||||||
@@ -1236,6 +1241,7 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
document.getElementById('sync-status').textContent = '연결 끊김';
|
document.getElementById('sync-status').textContent = '연결 끊김';
|
||||||
document.getElementById('sync-status').style.color = '#f45c43';
|
document.getElementById('sync-status').style.color = '#f45c43';
|
||||||
mcpModeSynced = false; // 🆕 재연결 시 다시 동기화하도록 플래그 리셋
|
mcpModeSynced = false; // 🆕 재연결 시 다시 동기화하도록 플래그 리셋
|
||||||
|
window.canFormatSynced = false; // 🆕 File Format도 재동기화
|
||||||
setTimeout(initWebSocket, 3000);
|
setTimeout(initWebSocket, 3000);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1332,6 +1338,15 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
else if (data.type === 'stopTriggersSet') {
|
else if (data.type === 'stopTriggersSet') {
|
||||||
console.log('✅ Stop triggers saved:', data.count);
|
console.log('✅ Stop triggers saved:', data.count);
|
||||||
}
|
}
|
||||||
|
// 🆕 File Format 저장 결과 처리
|
||||||
|
else if (data.type === 'canFormatSaved') {
|
||||||
|
console.log('✅ CAN Format saved:', data.format);
|
||||||
|
const statusSpan = document.getElementById('format-save-status');
|
||||||
|
if (statusSpan) {
|
||||||
|
statusSpan.textContent = '✓ Saved: ' + data.format.toUpperCase();
|
||||||
|
setTimeout(() => { statusSpan.textContent = ''; }, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Auto Trigger 상태 업데이트 (update 메시지에서)
|
// Auto Trigger 상태 업데이트 (update 메시지에서)
|
||||||
if (data.autoTriggerEnabled !== undefined) {
|
if (data.autoTriggerEnabled !== undefined) {
|
||||||
@@ -1430,6 +1445,19 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 저장된 File Format 적용 (최초 접속 시 한 번만)
|
||||||
|
if (data.savedCanFormat && !window.canFormatSynced) {
|
||||||
|
const formatRadios = document.getElementsByName('can-format');
|
||||||
|
for (const radio of formatRadios) {
|
||||||
|
if (radio.value === data.savedCanFormat) {
|
||||||
|
radio.checked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.canFormatSynced = true;
|
||||||
|
console.log('✅ Loaded saved CAN format:', data.savedCanFormat);
|
||||||
|
}
|
||||||
|
|
||||||
// 현재 파일
|
// 현재 파일
|
||||||
currentLoggingFile = data.currentFile || '';
|
currentLoggingFile = data.currentFile || '';
|
||||||
if (data.currentFile) {
|
if (data.currentFile) {
|
||||||
@@ -1713,6 +1741,26 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
console.log('MCP2515 mode set to:', modeName);
|
console.log('MCP2515 mode set to:', modeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 File Format 저장 함수
|
||||||
|
function saveFileFormat() {
|
||||||
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
let canFormat = 'bin';
|
||||||
|
const formatRadios = document.getElementsByName('can-format');
|
||||||
|
for (const radio of formatRadios) {
|
||||||
|
if (radio.checked) {
|
||||||
|
canFormat = radio.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
cmd: 'saveCanFormat',
|
||||||
|
format: canFormat
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log('Save CAN format:', canFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function startLogging() {
|
function startLogging() {
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
|||||||
Reference in New Issue
Block a user