Esp 32 ap keep turning off

Hi i have this code and the ap is turning off

#include <WiFi.h>
#include <WebServer.h>
#include <LittleFS.h>
#include <ArduinoJson.h>

// ======= WiFi AP =======
String ap_ssid = "Inventář_součástek";
String ap_pass = "12345678";

WebServer server(80);

// ======= HTML MENU =======
const char html_menu[] PROGMEM = R"rawliteral(
<nav>
  <button onclick="showPage('inventory')">📦 Inventář</button>
  <button onclick="showPage('esp')">📡 ESP</button>
  <button onclick="showPage('pc')">🖥️ PC</button>
  <button onclick="showPage('desk')">💡 Stůl</button>
  <button onclick="showPage('light')">💡 Light</button>
  <button onclick="showPage('temp')">🌡️ Teplota</button>
  <button onclick="showPage('wifi')">🌐 WiFi</button>
  <button onclick="showPage('theme')">🎨 Vzhled</button>
</nav>
<style>
nav { background:#1e293b; display:flex; justify-content:center; flex-wrap:wrap; gap:10px; padding:10px; }
nav button { background:#3b82f6; color:#fff; border:none; padding:6px 12px; border-radius:6px; cursor:pointer; transition:0.2s; }
nav button:hover { background:#2563eb; }
</style>
)rawliteral";

// ======= HTML MAIN PAGE =======
const char html_main[] PROGMEM = R"rawliteral(
<!DOCTYPE html><html lang="cs"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Inventář a WiFi</title>
<style>
:root {
  --bg: #111827;
  --text: #f1f5f9;
  --nav-bg: #1e293b;
  --nav-btn: #3b82f6;
  --nav-btn-hover: #2563eb;
  --btn-bg: #22d3ee;
  --btn-text: #111827;
  --btn-hover: #0891b2;
  --btn-hover-text: #fff;
  --table-border: #334155;
}
body { font-family: Arial,sans-serif; margin:0; padding:0; background:var(--bg); color:var(--text); }
nav { display:flex; justify-content:center; flex-wrap:wrap; gap:15px; padding:10px; background:var(--nav-bg); }
nav button { background:var(--nav-btn); color:#fff; border:none; padding:6px 12px; border-radius:6px; cursor:pointer; transition:0.2s; }
nav button:hover { background:var(--nav-btn-hover); }
.container { padding:20px; }
input,button,select { padding:8px; margin:4px 2px; border-radius:6px; border:none; font-size:16px; }
button { background:var(--btn-bg); color:var(--btn-text); cursor:pointer; transition:0.2s; }
button:hover { background:var(--btn-hover); color:var(--btn-hover-text); }
table { border-collapse:collapse; width:100%; margin-top:10px; table-layout:fixed; }
th,td { border:1px solid var(--table-border); padding:6px; text-align:left; word-wrap:break-word; font-size:14px; }
.qty-box { display:flex; gap:4px; align-items:center; justify-content:center; }
input[type=number] { width:60px; text-align:center; }
.form-row { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:10px; }
.form-row input,.form-row button { flex:1 1 120px; min-width:80px; }
#search,#filterCat { width:100%; margin-bottom:10px; box-sizing:border-box; }
@media(max-width:600px){ th,td{font-size:12px;padding:4px;} input,button,select{font-size:14px;padding:6px;} .qty-box input[type=number]{width:40px;} }
.centered { display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:80vh; text-align:center; }
</style>
</head>
<body>
%MENU%
<div class="container">
<!-- INVENTÁŘ -->
<div id="inventory" class="page">
<h1>Inventář součástek</h1>
<div class="form-row">
<input id="name" placeholder="Název">
<input id="category" placeholder="Kategorie">
<input id="qty" type="number" placeholder="Množství" value="1">
<input id="note" placeholder="Poznámka">
<button onclick="addItem()">Přidat</button>
</div>
<input id="search" placeholder="Hledat…" oninput="render()">
<select id="filterCat" onchange="render()"><option value="">Všechny kategorie</option></select>
<table>
<thead><tr><th>#</th><th>Název</th><th>Kategorie</th><th>Množství</th><th>Poznámka</th><th>Akce</th></tr></thead>
<tbody id="tbody"></tbody>
</table>
</div>

<!-- ESP -->
<div id="esp" class="page centered" style="display:none;">
<h1>Seznam ESP modulů</h1>
<ul id="espList"></ul>
<button onclick="refreshESP()">🔄 Aktualizovat</button>
</div>

<!-- PC -->
<div id="pc" class="page centered" style="display:none;">
<h1>Ovládání PC</h1>
<button onclick="alert('PC zapnuto!')">Zapnout PC</button>
<button onclick="alert('PC vypnuto!')">Vypnout PC</button>
</div>

<!-- DESK -->
<div id="desk" class="page centered" style="display:none;">
<h1>Světlo na stole</h1>
<button onclick="alert('Světlo na stole zapnuto!')">Zapnout</button>
<button onclick="alert('Světlo na stole vypnuto!')">Vypnout</button>
</div>

<!-- LIGHT -->
<div id="light" class="page centered" style="display:none;">
<h1>Ovládání světla</h1>
<button onclick="fetch('/light/on')">Zapnout</button>
<button onclick="fetch('/light/off')">Vypnout</button>
</div>

<!-- TEMP -->
<div id="temp" class="page centered" style="display:none;">
<h1>Aktuální teplota</h1>
<p id="tempVal">Načítám…</p>
<button onclick="updateTemp()">Aktualizovat</button>
</div>

<!-- WIFI -->
<div id="wifi" class="page centered" style="display:none;">
<h1>Nastavení WiFi</h1>
<input id="ssid" placeholder="SSID" value="%SSID%"><br>
<input id="pass" placeholder="Heslo" value="%PASS%"><br>
<button onclick="updateWiFi()">Uložit a restartovat AP</button>
</div>

<!-- THEME -->
<div id="theme" class="page centered" style="display:none;">
<h1>Nastavení barev</h1>
<label>Barva pozadí: <input type="color" id="bgColor"></label><br><br>
<label>Barva textu: <input type="color" id="textColor"></label><br><br>
<label>Navigace: <input type="color" id="navColor"></label><br><br>
<label>Tlačítko: <input type="color" id="btnColor"></label><br><br>
<label>Text tlačítka: <input type="color" id="btnTextColor"></label><br><br>
<label>Ohraničení tabulky: <input type="color" id="tableBorder"></label><br><br>
<button onclick="resetColors()">♻️ Resetovat barvy</button>
<button onclick="saveTheme()">💾 Uložit barvy</button>
</div>
</div>

<script>
function showPage(id){
  document.querySelectorAll('.page').forEach(p=>p.style.display='none');
  document.getElementById(id).style.display='block';
}

// --------- Inventář ----------
let items=[];
async function loadItems(){ let r=await fetch('/load'); if(r.ok){ items=await r.json(); render(); } }
async function saveItems(){ await fetch('/save',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(items)}); }
function addItem(){ const n=document.getElementById('name').value.trim(); const c=document.getElementById('category').value.trim(); const q=parseInt(document.getElementById('qty').value)||0; const note=document.getElementById('note').value.trim(); if(!n) return; items.unshift({name:n,category:c,qty:q,note:note}); saveItems(); render(); document.getElementById('name').value=''; document.getElementById('category').value=''; document.getElementById('qty').value=1; document.getElementById('note').value=''; }
function deleteItem(i){ items.splice(i,1); saveItems(); render(); }
function updateQty(i,d){ items[i].qty=Math.max(0,items[i].qty+d); saveItems(); render(); }
function updateQtyInput(i,v){ items[i].qty=Math.max(0,parseInt(v)||0); saveItems(); render(); }
function updateCategoryFilter(){ const sel=document.getElementById('filterCat'); const cur=sel.value; let cats=[...new Set(items.map(it=>it.category).filter(c=>c))]; sel.innerHTML='<option value="">Všechny kategorie</option>'+cats.map(c=>`<option value="${c}" ${c===cur?'selected':''}>${c}</option>`).join(''); }
function render(){ const t=document.getElementById('tbody'); const q=document.getElementById('search').value.toLowerCase().trim(); const cat=document.getElementById('filterCat').value; t.innerHTML=''; items.filter(it=>(it.name.toLowerCase().includes(q)||it.category.toLowerCase().includes(q)||it.note.toLowerCase().includes(q))&&(cat===''||it.category===cat)).forEach((it,i)=>{ t.innerHTML+=`<tr><td>${i+1}</td><td>${it.name}</td><td>${it.category}</td><td><div class="qty-box"><button onclick="updateQty(${i},-1)">−</button><input type="number" value="${it.qty}" onchange="updateQtyInput(${i},this.value)"><button onclick="updateQty(${i},1)">+</button></div></td><td>${it.note}</td><td><button onclick="deleteItem(${i})">🗑️</button></td></tr>` }); updateCategoryFilter(); }
loadItems();

// --------- ESP ----------
let espModules=[{name:"ESP-01",status:"✅ Online"},{name:"ESP-32",status:"❌ Offline"},{name:"ESP-C3",status:"✅ Online"}];
function refreshESP(){ let ul=document.getElementById('espList'); ul.innerHTML=''; espModules.forEach(m=>{ let li=document.createElement('li'); li.textContent=m.name+" - "+m.status; ul.appendChild(li); }); }

// --------- TEMP ----------
async function updateTemp(){ let r=await fetch('/tempval'); if(r.ok){ let t=await r.text(); document.getElementById('tempVal').innerText=t+' °C'; } }

// --------- WiFi ----------
function updateWiFi(){
  const ssid=document.getElementById('ssid').value;
  const pass=document.getElementById('pass').value;
  if(pass.length>0 && pass.length<8){ alert("Heslo musí mít alespoň 8 znaků!"); return; }
  fetch('/wifi_update?ssid='+encodeURIComponent(ssid)+'&pass='+encodeURIComponent(pass)).then(()=>alert("AP aktualizováno!"));
}

// --------- THEME ----------
const defaultColors={"--bg":"#111827","--text":"#f1f5f9","--nav-bg":"#1e293b","--btn-bg":"#22d3ee","--btn-text":"#111827","--table-border":"#334155"};
function setColor(varName,value){ document.documentElement.style.setProperty(varName,value); }
async function saveTheme(){   
  const theme={bg:document.getElementById('bgColor').value,text:document.getElementById('textColor').value,nav:document.getElementById('navColor').value,btn:document.getElementById('btnColor').value,btnText:document.getElementById('btnTextColor').value,tableBorder:document.getElementById('tableBorder').value};
  await fetch('/saveTheme',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(theme)});
  alert('Barvy uloženy!');
}
async function resetColors(){
  for(const k in defaultColors) setColor(k, defaultColors[k]);
  const theme = {bg: defaultColors['--bg'], text: defaultColors['--text'], nav: defaultColors['--nav-bg'], btn: defaultColors['--btn-bg'], btnText: defaultColors['--btn-text'], tableBorder: defaultColors['--table-border']};
  await fetch('/saveTheme',{method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(theme)});
  document.getElementById('bgColor').value = theme.bg;
  document.getElementById('textColor').value = theme.text;
  document.getElementById('navColor').value = theme.nav;
  document.getElementById('btnColor').value = theme.btn;
  document.getElementById('btnTextColor').value = theme.btnText;
  document.getElementById('tableBorder').value = theme.tableBorder;
  alert('Barvy resetovány a uloženy!');
}
async function loadTheme(){ let r=await fetch('/loadTheme'); if(r.ok){ let t=await r.json(); setColor('--bg',t.bg||defaultColors['--bg']); setColor('--text',t.text||defaultColors['--text']); setColor('--nav-bg',t.nav||defaultColors['--nav-bg']); setColor('--btn-bg',t.btn||defaultColors['--btn-bg']); setColor('--btn-text',t.btnText||defaultColors['--btn-text']); setColor('--table-border',t.tableBorder||defaultColors['--table-border']); document.getElementById('bgColor').value=t.bg||defaultColors['--bg']; document.getElementById('textColor').value=t.text||defaultColors['--text']; document.getElementById('navColor').value=t.nav||defaultColors['--nav-bg']; document.getElementById('btnColor').value=t.btn||defaultColors['--btn-bg']; document.getElementById('btnTextColor').value=t.btnText||defaultColors['--btn-text']; document.getElementById('tableBorder').value=t.tableBorder||defaultColors['--table-border']; } }
loadTheme();
</script>
</body></html>
)rawliteral";

// ======= Helper =======
String withMenu(const char* page){ 
  String out(page); 
  out.replace("%MENU%", String(FPSTR(html_menu))); 
  return out; 
}

// ======= WiFi CONFIG SAVE/LOAD =======
void saveWiFiConfig() {
  DynamicJsonDocument doc(256);
  doc["ssid"] = ap_ssid;
  doc["pass"] = ap_pass;
  File f = LittleFS.open("/wifi.json", "w");
  if (!f) { Serial.println("Chyba zápisu WiFi config"); return; }
  serializeJson(doc, f);
  f.close();
  Serial.println("WiFi config uložen");
}

void loadWiFiConfig() {
  if (!LittleFS.exists("/wifi.json")) return;
  File f = LittleFS.open("/wifi.json","r");
  if(!f){ Serial.println("Chyba čtení WiFi config"); return; }
  DynamicJsonDocument doc(256);
  DeserializationError err = deserializeJson(doc,f);
  f.close();
  if(err){ Serial.println("Chyba parsování WiFi config"); return; }
  if (doc.containsKey("ssid")) ap_ssid = doc["ssid"].as<String>();
  if (doc.containsKey("pass")) ap_pass = doc["pass"].as<String>();
  Serial.println("WiFi config načten: " + ap_ssid);
}

// ======= Handlery =======
void handleRoot(){ 
  server.sendHeader("Location","/main");
  server.send(302, "text/plain", "");
}

void handleMain(){
  String page = String(FPSTR(html_main));
  page.replace("%SSID%", ap_ssid);
  page.replace("%PASS%", ap_pass);
  server.send(200,"text/html", withMenu(page.c_str()));
}

void handleLightOn(){ server.send(200,"text/plain","ON"); }
void handleLightOff(){ server.send(200,"text/plain","OFF"); }
void handleTempVal(){ float t=23.5; server.send(200,"text/plain",String(t)); }

// ======= Inventory =======
void handleLoad(){   
  if(!LittleFS.exists("/inventory.json")){ server.send(200,"application/json","[]"); return; }
  File f=LittleFS.open("/inventory.json","r"); 
  if(!f){ server.send(500,"text/plain","Chyba čtení"); return; }
  String d=f.readString(); 
  f.close(); 
  server.send(200,"application/json",d);
}

void handleSave(){   
  // očekává JSON v těle požadavku (plain)
  if(!server.hasArg("plain")){ server.send(400,"text/plain","Žádná data"); return; }
  File f=LittleFS.open("/inventory.json","w"); 
  if(!f){ server.send(500,"text/plain","Chyba zápisu"); return; }
  f.print(server.arg("plain")); 
  f.close(); 
  server.send(200,"text/plain","OK");
}

// ======= THEME =======
void handleSaveTheme(){
  if(!server.hasArg("plain")){ server.send(400,"text/plain","Žádná data"); return; }
  File f=LittleFS.open("/theme.json","w"); 
  if(!f){ server.send(500,"text/plain","Chyba zápisu"); return; }
  f.print(server.arg("plain")); 
  f.close(); 
  server.send(200,"text/plain","OK");
}

void handleLoadTheme(){
  if(!LittleFS.exists("/theme.json")){ server.send(200,"application/json","{}"); return; }
  File f=LittleFS.open("/theme.json","r"); 
  if(!f){ server.send(500,"text/plain","Chyba čtení"); return; }
  String d=f.readString(); 
  f.close(); 
  server.send(200,"application/json",d);
}

// ======= WiFi UPDATE =======
void handleWiFiUpdate(){
  if(server.hasArg("ssid")) ap_ssid = server.arg("ssid");
  if(server.hasArg("pass")) ap_pass = server.arg("pass");
  // restart AP se provede restartem modulu nebo opětovným voláním softAP
  WiFi.softAP(ap_ssid.c_str(), ap_pass.c_str());
  saveWiFiConfig();
  server.send(200,"text/plain","AP updated");
  Serial.println("AP updated via web: SSID=" + ap_ssid + " PASS=" + ap_pass);
}

// ======= Serial vstup (pro Update přes sérií) =======
void handleSerialInput(){
  if(Serial.available()){
    String line = Serial.readStringUntil('\n'); line.trim();
    if(line.startsWith("SSID:")){
      String newSSID = line.substring(5);
      newSSID.trim();
      if(newSSID.length()>=1){ ap_ssid = newSSID; WiFi.softAP(ap_ssid.c_str(), ap_pass.c_str()); saveWiFiConfig(); Serial.println("SSID updated to: " + ap_ssid); }
    } else if(line.startsWith("PASS:")){
      String newPass = line.substring(5);
      newPass.trim();
      if(newPass.length()>=8){ ap_pass = newPass; WiFi.softAP(ap_ssid.c_str(), ap_pass.c_str()); saveWiFiConfig(); Serial.println("Password updated"); }
    }
  }
}

// ======= Setup AP & server =======
void startAP(){
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ap_ssid.c_str(), ap_pass.c_str());
  Serial.println("");
  Serial.println("===== WiFi AP =====");
  Serial.print("SSID: "); Serial.println(ap_ssid);
  Serial.print("Heslo: "); Serial.println(ap_pass);
  Serial.println("🌐 Připoj se a otevři: http://192.168.4.1");
  Serial.println("HTTP server běží.");
}

void setup() {
  Serial.begin(115200);
  delay(100);

  if(!LittleFS.begin()){
    Serial.println("Chyba při startu LittleFS");
    // i když FS selže, pokračujeme, ale některé funkce nebudou fungovat
  } else {
    Serial.println("LittleFS inicializován");
  }

  loadWiFiConfig();  // načti uložené SSID a heslo (pokud jsou)

  startAP();

  // routy
  server.on("/", handleRoot);
  server.on("/main", handleMain);
  server.on("/light/on", handleLightOn);
  server.on("/light/off", handleLightOff);
  server.on("/tempval", handleTempVal);
  server.on("/load", handleLoad);
  server.on("/save", HTTP_POST, handleSave);
  server.on("/saveTheme", HTTP_POST, handleSaveTheme);
  server.on("/loadTheme", handleLoadTheme);
  server.on("/wifi_update", handleWiFiUpdate);

  server.begin();
  Serial.println("HTTP server spuštěn na portu 80");
}

// ======= Loop =======
void loop() {
  server.handleClient();
  handleSerialInput();
}

What do you by “off”
Turning off something connected to it ?
Processor shutting down ?
Wi fi disconnects ?
Software crashes?

Did you write that stuff yourself ?

Please explain and show details of your board , how it’s powered and what is connected to it.

1 Like

The ap is turning of the esp 32 is connected to pc by usbc and i coencent my phone to the ap then i turn my phone of and the ap turn of too. And the code is 50/50 with ai

You are not very clear! Pretend you are talking to someone who has never heard of Arduino

How do you connect the phone to the app - by wires, blue tooth, wifi ??
The App looks very complex - you might need to start with something simple that illustrates the problem

Do you mean when you switch your phone off (with the power button) the ESP32 also powers down?
of ==Off
ap ==App

Sorry im trying my best im using wifi and the ap will turn on and i will conect to it with my mobile than i turn off my mobile and the ap turn off as well

I’m unsure but this maybe (?) because once the link to you phone is switched off the Arduino code doesn’t look for a connection again ( I haven’t waded through the code) and so does nothing .
You need to write some very simple basic code to just connect to the phone and see how it operates and if this is the case .

It does look like this might be the case as code links up in setup - which of course only runs once , so if the link fails , it’s not re established .

I don’t know how to sort this in your code but others or google might help

Post an annotated schematic showing exactly how you wired it, be sure to show all connections, power, ground and power sources.

1 Like