APSTA모드 추가

This commit is contained in:
2025-11-09 13:56:03 +00:00
parent c707644c6a
commit d6c74f1b06
2 changed files with 229 additions and 20 deletions

View File

@@ -159,6 +159,11 @@ enum MCP2515Mode {
char wifiSSID[32] = "Byun_CAN_Logger";
char wifiPassword[64] = "12345678";
// WiFi Station 모드 설정 (추가)
bool enableSTAMode = false; // APSTA 모드 활성화 여부
char staSSID[32] = ""; // 연결할 WiFi SSID
char staPassword[64] = ""; // 연결할 WiFi 비밀번호
// 전역 변수
SPIClass hspi(HSPI);
SPIClass vspi(VSPI);
@@ -233,10 +238,15 @@ int commentCount = 0;
void loadSettings() {
preferences.begin("can-logger", false);
// WiFi 설정 로드
// WiFi AP 설정 로드
preferences.getString("wifi_ssid", wifiSSID, sizeof(wifiSSID));
preferences.getString("wifi_pass", wifiPassword, sizeof(wifiPassword));
// WiFi STA 모드 설정 로드 (추가)
enableSTAMode = preferences.getBool("sta_enable", false);
preferences.getString("sta_ssid", staSSID, sizeof(staSSID));
preferences.getString("sta_pass", staPassword, sizeof(staPassword));
// 설정이 없으면 기본값 사용
if (strlen(wifiSSID) == 0) {
strcpy(wifiSSID, "Byun_CAN_Logger");
@@ -260,21 +270,37 @@ void loadSettings() {
}
preferences.end();
// STA 모드 설정 출력
if (enableSTAMode && strlen(staSSID) > 0) {
Serial.printf("✓ WiFi STA 모드: 활성화 (SSID: %s)\n", staSSID);
}
}
void saveSettings() {
preferences.begin("can-logger", false);
// WiFi 설정 저장
// WiFi AP 설정 저장
preferences.putString("wifi_ssid", wifiSSID);
preferences.putString("wifi_pass", wifiPassword);
// WiFi STA 모드 설정 저장 (추가)
preferences.putBool("sta_enable", enableSTAMode);
preferences.putString("sta_ssid", staSSID);
preferences.putString("sta_pass", staPassword);
preferences.end();
Serial.println("\n✓ 설정 저장 완료:");
Serial.println("----------------------------------------");
Serial.printf(" WiFi SSID : %s\n", wifiSSID);
Serial.printf(" WiFi Password : %s\n", wifiPassword);
Serial.printf(" WiFi AP SSID : %s\n", wifiSSID);
Serial.printf(" WiFi AP Password : %s\n", wifiPassword);
if (enableSTAMode && strlen(staSSID) > 0) {
Serial.printf(" STA Mode : 활성화\n");
Serial.printf(" STA SSID : %s\n", staSSID);
} else {
Serial.printf(" STA Mode : 비활성화\n");
}
Serial.println("----------------------------------------");
Serial.println("⚠️ 재부팅 후 WiFi 설정이 적용됩니다.");
}
@@ -1287,7 +1313,12 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
// 설정 전송
String settings = "{\"type\":\"settings\",";
settings += "\"ssid\":\"" + String(wifiSSID) + "\",";
settings += "\"password\":\"" + String(wifiPassword) + "\"}";
settings += "\"password\":\"" + String(wifiPassword) + "\",";
settings += "\"staEnable\":" + String(enableSTAMode ? "true" : "false") + ",";
settings += "\"staSSID\":\"" + String(staSSID) + "\",";
settings += "\"staPassword\":\"" + String(staPassword) + "\",";
settings += "\"staConnected\":" + String(WiFi.status() == WL_CONNECTED ? "true" : "false") + ",";
settings += "\"staIP\":\"" + WiFi.localIP().toString() + "\"}";
webSocket.sendTXT(num, settings);
@@ -1301,6 +1332,26 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
int passEnd = message.indexOf("\"", passStart);
String password = message.substring(passStart, passEnd);
// STA 모드 설정 파싱
int staEnableIdx = message.indexOf("\"staEnable\":");
if (staEnableIdx >= 0) {
String staEnableStr = message.substring(staEnableIdx + 12, staEnableIdx + 16);
enableSTAMode = (staEnableStr.indexOf("true") >= 0);
if (enableSTAMode) {
int staSSIDStart = message.indexOf("\"staSSID\":\"") + 11;
int staSSIDEnd = message.indexOf("\"", staSSIDStart);
String staSsid = message.substring(staSSIDStart, staSSIDEnd);
int staPassStart = message.indexOf("\"staPassword\":\"") + 15;
int staPassEnd = message.indexOf("\"", staPassStart);
String staPass = message.substring(staPassStart, staPassEnd);
strncpy(staSSID, staSsid.c_str(), sizeof(staSSID) - 1);
strncpy(staPassword, staPass.c_str(), sizeof(staPassword) - 1);
}
}
strncpy(wifiSSID, ssid.c_str(), sizeof(wifiSSID) - 1);
strncpy(wifiPassword, password.c_str(), sizeof(wifiPassword) - 1);
@@ -1638,18 +1689,60 @@ void setup() {
Serial.println("✗ SD 카드 초기화 실패");
}
// WiFi AP 시작
WiFi.softAP(wifiSSID, wifiPassword);
// WiFi 설정 - APSTA 모드 지원
if (enableSTAMode && strlen(staSSID) > 0) {
// APSTA 모드 (AP + Station 동시 동작)
Serial.println("\n📶 WiFi APSTA 모드 시작...");
WiFi.mode(WIFI_AP_STA);
// AP 모드 시작
WiFi.softAP(wifiSSID, wifiPassword);
Serial.print("✓ AP SSID: ");
Serial.println(wifiSSID);
Serial.print("✓ AP IP: ");
Serial.println(WiFi.softAPIP());
// Station 모드로 WiFi 연결 시도
Serial.printf("📡 WiFi 연결 시도: %s\n", staSSID);
WiFi.begin(staSSID, staPassword);
// 연결 대기 (최대 10초)
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.println("✓ WiFi 연결 성공!");
Serial.print("✓ STA IP: ");
Serial.println(WiFi.localIP());
Serial.print("✓ Gateway: ");
Serial.println(WiFi.gatewayIP());
Serial.print("✓ DNS: ");
Serial.println(WiFi.dnsIP());
} else {
Serial.println("✗ WiFi 연결 실패 (AP 모드는 정상 동작)");
}
} else {
// AP 모드만 사용
Serial.println("\n📶 WiFi AP 모드 시작...");
WiFi.mode(WIFI_AP);
WiFi.softAP(wifiSSID, wifiPassword);
Serial.print("✓ AP SSID: ");
Serial.println(wifiSSID);
Serial.print("✓ AP IP: ");
Serial.println(WiFi.softAPIP());
}
// WiFi 성능 최적화
WiFi.setSleep(false); // WiFi 절전 모드 비활성화 (신호 강도 개선)
esp_wifi_set_max_tx_power(84); // TX 출력 최대화 (20.5dBm = 84/4)
Serial.print("✓ AP SSID: ");
Serial.println(wifiSSID);
Serial.print("✓ AP IP: ");
Serial.println(WiFi.softAPIP());
// WebSocket 시작
webSocket.begin();
webSocket.onEvent(webSocketEvent);

View File

@@ -99,11 +99,11 @@ const char settings_html[] PROGMEM = R"rawliteral(
input[type="password"] {
width: 100%;
padding: 12px 15px;
border: 2px solid #ddd;
border: 2px solid #e1e8ed;
border-radius: 8px;
font-size: 1em;
font-size: 0.95em;
transition: all 0.3s;
font-family: inherit;
background: white;
}
input[type="text"]:focus,
@@ -113,6 +113,38 @@ const char settings_html[] PROGMEM = R"rawliteral(
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
input[type="checkbox"] {
width: 20px;
height: 20px;
cursor: pointer;
margin-right: 10px;
}
.checkbox-group {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.checkbox-group label {
margin-bottom: 0;
cursor: pointer;
user-select: none;
}
.sta-settings {
background: #f0f4f8;
padding: 20px;
border-radius: 8px;
margin-top: 15px;
border-left: 4px solid #667eea;
}
.sta-settings.disabled {
opacity: 0.5;
pointer-events: none;
}
.button-group {
display: flex;
gap: 15px;
@@ -273,17 +305,49 @@ const char settings_html[] PROGMEM = R"rawliteral(
<span>WiFi Configuration</span>
</div>
<h3 style="color: #333; font-size: 1.1em; margin-bottom: 15px;">AP Mode (Access Point)</h3>
<div class="form-group">
<label for="wifi-ssid">WiFi SSID ( )</label>
<label for="wifi-ssid">AP SSID ( )</label>
<input type="text" id="wifi-ssid" placeholder="Byun_CAN_Logger" maxlength="31">
<div class="help-text">ESP32가 WiFi ( 31)</div>
</div>
<div class="form-group">
<label for="wifi-password">WiFi Password ()</label>
<label for="wifi-password">AP Password ()</label>
<input type="password" id="wifi-password" placeholder="최소 8자 이상" minlength="8" maxlength="63">
<div class="help-text">WiFi (8-63)</div>
</div>
<hr style="margin: 25px 0; border: none; border-top: 1px solid #ddd;">
<h3 style="color: #333; font-size: 1.1em; margin-bottom: 15px;">APSTA Mode (AP + Station)</h3>
<div class="checkbox-group">
<input type="checkbox" id="sta-enable" onchange="toggleSTASettings()">
<label for="sta-enable">Station ( WiFi에 )</label>
</div>
<div class="help-text" style="margin-left: 30px; margin-bottom: 15px;">
AP와 Station을
</div>
<div id="sta-settings" class="sta-settings disabled">
<div class="form-group">
<label for="sta-ssid"> WiFi SSID</label>
<input type="text" id="sta-ssid" placeholder="공유기 이름 입력" maxlength="31">
<div class="help-text"> WiFi </div>
</div>
<div class="form-group">
<label for="sta-password"> WiFi Password</label>
<input type="password" id="sta-password" placeholder="공유기 비밀번호 입력" maxlength="63">
<div class="help-text"> WiFi </div>
</div>
<div id="sta-status" style="display: none; margin-top: 15px; padding: 12px; background: #e8f5e9; border-radius: 6px; color: #2e7d32; font-weight: 600;">
WiFi : <span id="sta-ip"></span>
</div>
</div>
</div>
<div class="button-group">
@@ -298,8 +362,9 @@ const char settings_html[] PROGMEM = R"rawliteral(
</div>
<div class="info-box-text">
WiFi , ESP32를 SSID/ .<br>
"Sync from Phone" .<br>
RTC , .<br>
<strong>APSTA :</strong> Station ESP32가 AP와 Station을 .<br>
Station WiFi에 .<br>
Station AP .<br>
ESP32의 .
</div>
</div>
@@ -335,6 +400,22 @@ const char settings_html[] PROGMEM = R"rawliteral(
document.getElementById('wifi-ssid').value = data.ssid || 'Byun_CAN_Logger';
document.getElementById('wifi-password').value = data.password || '';
// STA 모드 설정 로드
document.getElementById('sta-enable').checked = data.staEnable || false;
document.getElementById('sta-ssid').value = data.staSSID || '';
document.getElementById('sta-password').value = data.staPassword || '';
// STA 설정 표시/숨김
toggleSTASettings();
// STA 연결 상태 표시
if (data.staConnected && data.staIP && data.staIP !== '0.0.0.0') {
document.getElementById('sta-ip').textContent = data.staIP;
document.getElementById('sta-status').style.display = 'block';
} else {
document.getElementById('sta-status').style.display = 'none';
}
hideAlert('alert-loading');
console.log('Settings loaded:', data);
} else if (data.type === 'settingsSaved') {
@@ -359,6 +440,11 @@ const char settings_html[] PROGMEM = R"rawliteral(
const ssid = document.getElementById('wifi-ssid').value.trim();
const password = document.getElementById('wifi-password').value;
// STA 모드 설정
const staEnable = document.getElementById('sta-enable').checked;
const staSSID = document.getElementById('sta-ssid').value.trim();
const staPassword = document.getElementById('sta-password').value;
// 입력 검증
if (ssid.length === 0) {
alert('WiFi SSID를 .');
@@ -380,10 +466,29 @@ const char settings_html[] PROGMEM = R"rawliteral(
return;
}
// STA 모드 검증
if (staEnable) {
if (staSSID.length === 0) {
alert('Station WiFi SSID를 .');
return;
}
if (staSSID.length > 31) {
alert('Station WiFi SSID는 31 .');
return;
}
if (staPassword.length > 0 && staPassword.length < 8) {
alert('Station WiFi 8 .');
return;
}
}
const settings = {
cmd: 'saveSettings',
ssid: ssid,
password: password
password: password,
staEnable: staEnable,
staSSID: staSSID,
staPassword: staPassword
};
if (ws && ws.readyState === WebSocket.OPEN) {
@@ -422,6 +527,17 @@ const char settings_html[] PROGMEM = R"rawliteral(
}
}
function toggleSTASettings() {
const staEnable = document.getElementById('sta-enable').checked;
const staSettings = document.getElementById('sta-settings');
if (staEnable) {
staSettings.classList.remove('disabled');
} else {
staSettings.classList.add('disabled');
}
}
// 페이지 로드 시 WebSocket 연결
window.addEventListener('load', function() {
initWebSocket();