m5core-ovmsWSclient.ino 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. /*
  2. * WebSocketClient.ino
  3. *
  4. * Created on: 24.05.2015
  5. *
  6. */
  7. //#include <Arduino.h>
  8. #include <M5Stack.h>
  9. #include <ArduinoJson.h>
  10. #include <WiFi.h>
  11. #include <WiFiMulti.h>
  12. #include <WiFiClientSecure.h>
  13. #include <HttpClient.h>
  14. #include <WebSocketsClient.h>
  15. WiFiMulti WiFiMulti;
  16. WebSocketsClient webSocket;
  17. HttpClient htclient;
  18. bool localTesting = true;
  19. bool genRandomVals = false;
  20. const char* OVMSUSER = "admin";
  21. const char* OVMSPASS = "OVMSP455w0rd"; // Change this to your password
  22. const int LCDBrightnessSteps[] = {60, 120, 250};
  23. int LCDBrightnessStep = 0;
  24. const int heightBarGraphSOC = 72;
  25. const int widthBarGraphSOC = 300;
  26. const int leftBarGraphSOC = (320-widthBarGraphSOC-4)/2;
  27. const int topBarGraphSOC = 0;
  28. const int SOCtextSize = 7;
  29. const int SOCtextWidth = M5.Lcd.textWidth("99%")*SOCtextSize;
  30. const int heightBarGraphPWR = 32;
  31. const int widthBarGraphPWR = 220;
  32. const int PWRtextSize = 3;
  33. const int PWRtextWidth = M5.Lcd.textWidth("100kW")*PWRtextSize;
  34. const int leftBarGraphPWR = (320-widthBarGraphPWR-4);
  35. const int topBarGraphPWR = 80;
  36. const int topTextLineRange = topBarGraphPWR + heightBarGraphPWR + 16;
  37. const int topTextLineConsumption = topTextLineRange + 32;
  38. const int topTextLineTemps = topTextLineConsumption + 32;
  39. const float MAXINPOWER = 100;
  40. const float MAXOUTPOWER = 200;
  41. const float MAXRANGEPWR = 300;
  42. float vbsoc = 90.5;
  43. float vbrangeideal = 402 ;
  44. float vbrangefull = 450 ;
  45. float vetemp = 13 ;
  46. float vbtemp = 15 ;
  47. float xknbinlettemp = 14 ;
  48. float vbpower = 1 ;
  49. float vbconsumption = 160 ;
  50. const uint16_t DARKERCYAN = 0x0124;
  51. const size_t jsonCapacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(38) + 910;
  52. DynamicJsonDocument jsonDoc(jsonCapacity);
  53. DeserializationError payloadDecodeError;
  54. uint8_t M5triggerUpdate = 0;
  55. uint8_t dummyCounter = 0;
  56. unsigned long prevTimer = millis();
  57. unsigned long displayTimer = millis();
  58. unsigned long spentTimer = 0;
  59. bool slowRefreshTrigger = false;
  60. unsigned long slowRefreshTimer = 0;
  61. unsigned long slowRefreshMax = 5000;
  62. bool mildRefreshTrigger = false;
  63. unsigned long mildRefreshTimer = 0;
  64. unsigned long mildRefreshMax = 2000;
  65. bool fastRefreshTrigger = false;
  66. unsigned long fastRefreshTimer = 0;
  67. unsigned long fastRefreshMax = 100;
  68. #define USE_SERIAL Serial
  69. void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
  70. const uint8_t* src = (const uint8_t*) mem;
  71. USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
  72. for(uint32_t i = 0; i < len; i++) {
  73. if(i % cols == 0) {
  74. USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
  75. }
  76. USE_SERIAL.printf("%02X ", *src);
  77. src++;
  78. }
  79. USE_SERIAL.printf("\n");
  80. }
  81. void draw_vbsoc(float vbsoc) {
  82. M5.Lcd.setTextSize(SOCtextSize);
  83. uint16_t SOCcolor = GREEN;
  84. uint16_t SOCtextColor = 0x0720; // Slightly Darker Green
  85. uint16_t BorderColor = WHITE;
  86. uint16_t BGcolor = 0x2970; //BLUE;
  87. if(vbsoc<25){ SOCcolor = YELLOW; SOCtextColor = YELLOW; BorderColor = YELLOW; }
  88. if(vbsoc<10){ SOCcolor = RED; SOCtextColor = RED; BorderColor = RED; BGcolor = MAROON; }
  89. M5.Lcd.fillRoundRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+6, heightBarGraphSOC+4 , 6, BGcolor);
  90. //M5.Lcd.fillRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+4, heightBarGraphSOC+4 , BGcolor);
  91. M5.Lcd.drawRoundRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+4, heightBarGraphSOC+4 , 6, BorderColor);
  92. M5.Lcd.fillRoundRect(leftBarGraphSOC+2, topBarGraphSOC+2, widthBarGraphSOC*(vbsoc/100), heightBarGraphSOC , 4, SOCcolor);
  93. if(vbsoc>=50){
  94. M5.Lcd.setTextColor(BLACK);
  95. M5.Lcd.setCursor(leftBarGraphSOC+6+3*vbsoc-SOCtextWidth-6, topBarGraphSOC+14);
  96. M5.Lcd.print(vbsoc,0); M5.Lcd.print('%');
  97. }else{
  98. M5.Lcd.setTextColor(SOCtextColor);
  99. M5.Lcd.setCursor(leftBarGraphSOC+6+3*vbsoc+8, topBarGraphSOC+12);
  100. M5.Lcd.print(vbsoc,0); M5.Lcd.print('%');
  101. }
  102. //M5.Lcd.printf("%*s", 5, vbsoc);
  103. M5triggerUpdate++;
  104. }
  105. void draw_vbpower(float vbpower) {
  106. M5.Lcd.setTextSize(PWRtextSize);
  107. uint16_t PWRcolor;
  108. uint16_t BorderColor = LIGHTGREY; //WHITE;
  109. uint16_t BGcolor = 0x528A;
  110. // Draw empty full bar
  111. M5.Lcd.fillRoundRect(leftBarGraphPWR, topBarGraphPWR, widthBarGraphPWR+6, heightBarGraphPWR+4 , 6, BGcolor);
  112. //M5.Lcd.fillRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+4, heightBarGraphSOC+4 , BGcolor);
  113. M5.Lcd.drawRoundRect(leftBarGraphPWR, topBarGraphPWR, widthBarGraphPWR+4, heightBarGraphPWR+4 , 6, BorderColor);
  114. float barOffset;
  115. float barWidth;
  116. if(vbpower>0){
  117. PWRcolor = YELLOW; if(vbpower>25) PWRcolor = RED;
  118. barWidth = (widthBarGraphPWR*vbpower)/MAXRANGEPWR;
  119. // (220*140)/220
  120. barOffset = (widthBarGraphPWR*(float)MAXINPOWER)/MAXRANGEPWR;
  121. } else {
  122. PWRcolor = GREEN;
  123. barWidth = (widthBarGraphPWR*-vbpower)/MAXRANGEPWR;
  124. barOffset = (widthBarGraphPWR*((float)MAXINPOWER+vbpower))/MAXRANGEPWR;
  125. }
  126. // USE_SERIAL.print(barOffset); USE_SERIAL.print(" "); USE_SERIAL.println(barWidth);
  127. // Draw Power Bar
  128. //M5.Lcd.fillRoundRect(leftBarGraphPWR+2+barOffset, topBarGraphPWR+2, barWidth, heightBarGraphPWR , 4, PWRcolor);
  129. M5.Lcd.fillRect(leftBarGraphPWR+2+barOffset, topBarGraphPWR+2, barWidth, heightBarGraphPWR, PWRcolor);
  130. // Clean text
  131. M5.Lcd.fillRoundRect(4, topBarGraphPWR, PWRtextWidth, heightBarGraphPWR+4 , 6, BLACK);
  132. // Place 0 line
  133. M5.Lcd.drawLine(
  134. leftBarGraphPWR+2+(widthBarGraphPWR*(float)MAXINPOWER)/MAXRANGEPWR,
  135. topBarGraphPWR,
  136. leftBarGraphPWR+2+(widthBarGraphPWR*(float)MAXINPOWER)/MAXRANGEPWR,
  137. topBarGraphPWR+heightBarGraphPWR+2,
  138. BorderColor);
  139. M5.Lcd.setCursor(4, topBarGraphPWR+8);
  140. if(vbpower>0){
  141. M5.Lcd.setTextColor(RED);
  142. }else{
  143. M5.Lcd.setTextColor(GREEN);
  144. }
  145. if(vbpower > 0 && vbpower < 10 ) M5.Lcd.print(" ");
  146. if(vbpower > -10 && vbpower < 100 ) M5.Lcd.print(" ");
  147. M5.Lcd.print(vbpower,0); M5.Lcd.print("kW");
  148. //M5.Lcd.drawFloat(vbpower, 0, 4, topBarGraphPWR+8);
  149. //M5.Lcd.drawNumber(vbpower, 4, topBarGraphPWR+8);
  150. //M5.Lcd.print('kW');
  151. //M5.Lcd.printf("%*s", 5, vbpower);
  152. M5triggerUpdate++;
  153. }
  154. void draw_vbrange() {
  155. M5.Lcd.setTextSize(3);
  156. M5.lcd.fillRect(0, topTextLineRange, 320,32, DARKERCYAN);
  157. M5.Lcd.setCursor(4, topTextLineRange+4);
  158. M5.Lcd.setTextColor(LIGHTGREY);
  159. M5.Lcd.print("range: "); M5.Lcd.print(vbrangeideal,0); M5.Lcd.print("/");
  160. M5.Lcd.print(vbrangefull,0); M5.Lcd.print(" km");
  161. M5triggerUpdate++;
  162. }
  163. void draw_vbconsumption() {
  164. uint16_t textColor = GREEN;
  165. if(vbconsumption>150) textColor = YELLOW;
  166. if(vbconsumption>200) textColor = RED;
  167. M5.Lcd.setTextSize(3);
  168. M5.lcd.fillRect(0, topTextLineConsumption, 320,32, DARKERCYAN);
  169. M5.Lcd.setCursor(4, topTextLineConsumption+4);
  170. M5.Lcd.setTextColor(LIGHTGREY);
  171. M5.Lcd.print("cons: ");
  172. M5.Lcd.setTextColor(textColor);
  173. M5.Lcd.print(vbconsumption,0);
  174. M5.Lcd.setTextColor(LIGHTGREY);
  175. M5.Lcd.print(" Wh/km");
  176. M5triggerUpdate++;
  177. }
  178. void draw_temps() {
  179. M5.Lcd.setTextSize(2);
  180. M5.lcd.fillRect(0, topTextLineTemps,320 , 24, DARKERCYAN);
  181. M5.Lcd.setCursor(4, topTextLineTemps+4);
  182. M5.Lcd.setTextColor(LIGHTGREY); M5.Lcd.print("temps ext:");
  183. M5.Lcd.print(vetemp,0);
  184. M5.Lcd.setTextColor(LIGHTGREY); M5.Lcd.print(" in:");
  185. M5.Lcd.print(xknbinlettemp,0);
  186. M5.Lcd.setTextColor(LIGHTGREY); M5.Lcd.print(" bt:");
  187. M5.Lcd.print(vbtemp,0);
  188. M5triggerUpdate++;
  189. }
  190. void tickerBox(uint16_t tickerColor) {
  191. M5.lcd.fillRect(0,240-6 ,4 ,4 , tickerColor);
  192. M5triggerUpdate++;
  193. }
  194. void changeLCDBrightness() {
  195. LCDBrightnessStep++;
  196. if(LCDBrightnessStep==3) LCDBrightnessStep=0;
  197. M5.Lcd.setBrightness(LCDBrightnessSteps[LCDBrightnessStep]);
  198. if(localTesting) USE_SERIAL.printf("[LCD] Setting Brightness to : %u (step %u)\n", LCDBrightnessSteps[LCDBrightnessStep], LCDBrightnessStep);
  199. }
  200. void sendButtonA() {
  201. sendEvent("event+raise+M5.button.A");
  202. }
  203. void sendButtonB() {
  204. sendEvent("event+raise+M5.button.B");
  205. }
  206. void sendEvent(char* event){
  207. M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
  208. M5.Lcd.setCursor(6, 222);
  209. M5.Lcd.setTextColor(YELLOW);
  210. M5.Lcd.setTextSize(2);
  211. M5.Lcd.print(event);
  212. M5.update();
  213. M5triggerUpdate = 0;
  214. WiFiClient client;
  215. if (!client.connect("192.168.4.1", 80 )) {
  216. Serial.println("connection failed");
  217. return;
  218. }
  219. String url = "/api/execute?apikey=";
  220. url += OVMSPASS;
  221. url += "&command=";
  222. url += event;
  223. USE_SERIAL.print("Requesting URL: ");
  224. USE_SERIAL.println(url);
  225. client.print(String("GET ") + url + " HTTP/1.1\r\n" +
  226. "Host: 192.168.4.1\r\n" +
  227. "Connection: close\r\n\r\n");
  228. unsigned long timeout = millis();
  229. while (client.available() == 0) {
  230. if (millis() - timeout > 5000) {
  231. USE_SERIAL.println(">>> Client Timeout !");
  232. client.stop();
  233. return;
  234. }
  235. }
  236. while(client.available()) {
  237. String line = client.readStringUntil('\r');
  238. USE_SERIAL.print(line);
  239. }
  240. Serial.println();
  241. Serial.println("closing connection");
  242. M5.Lcd.fillRect(0, 220, 320, 32, BLACK);
  243. M5.update();
  244. M5triggerUpdate = 0;
  245. }
  246. void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
  247. // Timer control
  248. prevTimer=displayTimer;
  249. displayTimer=millis();
  250. spentTimer=displayTimer-prevTimer;
  251. slowRefreshTimer+=spentTimer;
  252. mildRefreshTimer+=spentTimer;
  253. fastRefreshTimer+=spentTimer;
  254. slowRefreshTrigger = (slowRefreshTimer>=slowRefreshMax) ? true : false;
  255. mildRefreshTrigger = (mildRefreshTimer>=mildRefreshMax) ? true : false;
  256. fastRefreshTrigger = (fastRefreshTimer>=fastRefreshMax) ? true : false;
  257. switch(type) {
  258. case WStype_DISCONNECTED:
  259. USE_SERIAL.printf("[WSc] Disconnected!\n");
  260. tickerBox(RED); M5.update();
  261. break;
  262. case WStype_CONNECTED:
  263. tickerBox(YELLOW); M5.update();
  264. if(localTesting) USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
  265. // send message to server when Connected
  266. //webSocket.sendTXT("M5 Stack Connected");
  267. sendEvent("event+raise+M5.websocket.connected");
  268. break;
  269. case WStype_TEXT:
  270. //if(localTesting) USE_SERIAL.printf("[WSc] get text: %s\n", payload);
  271. payloadDecodeError = deserializeJson(jsonDoc, payload);
  272. // Test if parsing succeeds.
  273. if (payloadDecodeError) {
  274. USE_SERIAL.printf("deserializeJson() failed: \n");
  275. USE_SERIAL.println(payloadDecodeError.c_str());
  276. }else{
  277. //USE_SERIAL.printf("parseObject() succeeded\n");
  278. JsonObject metrics = jsonDoc["metrics"];
  279. if (!metrics.isNull()) {
  280. if(localTesting && genRandomVals){
  281. metrics["v.b.soc"] = random(0,200)/2;
  282. metrics["v.b.power"] = random(-MAXINPOWER*10,MAXOUTPOWER*10+1)/10;
  283. metrics["v.b.range.ideal"] = random(360*10,400*10)/10;
  284. metrics["v.b.range.ideal"] = random(360*10,400*10)/10;
  285. metrics["v.e.temp"] = random(12*10,17*10)/10;
  286. metrics["v.b.temp"] = random(18*10,21*10)/10;
  287. metrics["xkn.b.inlet.temp"] = random(14*10,19*10)/10;
  288. metrics["v.b.consumption"] = random(130,240);
  289. }
  290. // v.b.soc
  291. if(metrics.containsKey("v.b.soc") && metrics["v.b.soc"]!=vbsoc){
  292. vbsoc = metrics["v.b.soc"];
  293. //USE_SERIAL.printf("[json] v.b.soc: %f\n", vbsoc);
  294. }
  295. if(slowRefreshTrigger) draw_vbsoc(vbsoc);
  296. // v.b.range.ideal
  297. if(metrics.containsKey("v.b.range.ideal") && metrics["v.b.range.ideal"]!=vbrangeideal){
  298. vbrangeideal = metrics["v.b.range.ideal"];
  299. }
  300. // v.b.range.full
  301. if(metrics.containsKey("v.b.range.full") && metrics["v.b.range.full"]!=vbrangefull){
  302. vbrangefull = metrics["v.b.range.full"];
  303. }
  304. if(slowRefreshTrigger) draw_vbrange();
  305. // v.e.temp
  306. if(metrics.containsKey("v.e.temp") && metrics["v.e.temp"]!=vetemp){
  307. vetemp = metrics["v.e.temp"];
  308. }
  309. // v.b.temp
  310. if(metrics.containsKey("v.b.temp") && metrics["v.b.temp"]!=vbtemp){
  311. vbtemp = metrics["v.b.temp"];
  312. }
  313. // xkn.b.inlet.temp
  314. if(metrics.containsKey("xkn.b.inlet.temp") && metrics["xkn.b.inlet.temp"]!=xknbinlettemp){
  315. xknbinlettemp = metrics["xkn.b.inlet.temp"];
  316. }
  317. if(mildRefreshTrigger) draw_temps();
  318. // xkn.b.inlet.temp
  319. if(metrics.containsKey("v.b.consumption") && metrics["v.b.consumption"]!=vbconsumption){
  320. vbconsumption = metrics["v.b.consumption"];
  321. }
  322. if(mildRefreshTrigger) draw_vbconsumption();
  323. // v.b.power
  324. if(metrics.containsKey("v.b.power")){
  325. vbpower = metrics["v.b.power"];
  326. //USE_SERIAL.printf("[json] v.b.power: %f\n", vbpower);
  327. }
  328. if(fastRefreshTrigger) draw_vbpower(vbpower);
  329. if(metrics.containsKey("m.monotonic")){
  330. //JsonVariant _mmonotonic=metrics["m.monotonic"];
  331. //int mmonotonic=_mmonotonic.as<int>();
  332. int mmonotonic=metrics["m.monotonic"].as<int>();
  333. if(mmonotonic % 2){
  334. tickerBox(DARKGREEN);
  335. }else{
  336. tickerBox(BLUE);
  337. }
  338. }
  339. if(M5.BtnA.wasReleased()) sendButtonA();
  340. if(M5.BtnB.wasReleased()) sendButtonB();
  341. if(M5.BtnC.wasReleased()) changeLCDBrightness();
  342. }
  343. if(M5triggerUpdate){
  344. M5.update();
  345. M5triggerUpdate = 0;
  346. }
  347. if(slowRefreshTrigger){
  348. slowRefreshTimer=0;
  349. //USE_SERIAL.printf("slowRefreshTimer reset\n");
  350. }
  351. if(mildRefreshTrigger){
  352. mildRefreshTimer=0;
  353. //USE_SERIAL.printf("mildRefreshTimer reset\n");
  354. }
  355. if(fastRefreshTrigger){
  356. fastRefreshTimer=0;
  357. //USE_SERIAL.printf("fastRefreshTimer reset\n");
  358. }
  359. }
  360. // send message to server
  361. // webSocket.sendTXT("message here");
  362. break;
  363. case WStype_BIN:
  364. USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
  365. hexdump(payload, length);
  366. // send data to server
  367. // webSocket.sendBIN(payload, length);
  368. break;
  369. case WStype_ERROR:
  370. case WStype_FRAGMENT_TEXT_START:
  371. case WStype_FRAGMENT_BIN_START:
  372. case WStype_FRAGMENT:
  373. case WStype_FRAGMENT_FIN:
  374. break;
  375. }
  376. }
  377. void setup() {
  378. M5.begin();
  379. M5.Power.begin();
  380. M5.Lcd.setBrightness(LCDBrightnessSteps[LCDBrightnessStep+1]);
  381. // USE_SERIAL.begin(921600);
  382. // USE_SERIAL.begin(115200);
  383. USE_SERIAL.begin(230400);
  384. //Serial.setDebugOutput(true);
  385. USE_SERIAL.setDebugOutput(true);
  386. USE_SERIAL.println();
  387. //M5.Lcd.fillScreen(BLACK);
  388. ledcDetachPin(SPEAKER_PIN);
  389. pinMode(SPEAKER_PIN, INPUT);
  390. for(uint8_t t = 5; t > 0; t--) {
  391. USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
  392. USE_SERIAL.flush();
  393. delay(500);
  394. }
  395. WiFiMulti.addAP("OVMSWifi", "W1f1P4ssW0rd"); // Change This to your OVMS
  396. USE_SERIAL.printf("[Wifi] Added APs...\n");
  397. WiFi.disconnect();
  398. if(WiFiMulti.run() != WL_CONNECTED){
  399. M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
  400. M5.Lcd.setCursor(6, 222);
  401. M5.Lcd.setTextColor(WHITE);
  402. M5.Lcd.setTextSize(2);
  403. M5.Lcd.print("[Wifi] Connecting...");
  404. USE_SERIAL.printf("[Wifi] Connecting...\n");
  405. dummyCounter = 1;
  406. tickerBox(RED);
  407. while(WiFiMulti.run() != WL_CONNECTED) {
  408. USE_SERIAL.printf("[Wifi] Connecting... count %d\n",dummyCounter++);
  409. M5.Lcd.print(".");
  410. M5.update();
  411. delay(500);
  412. if (M5.BtnC.wasReleased()) changeLCDBrightness();
  413. }
  414. //hexdump(WiFi.SSID().c_str(), sizeof(WiFi.SSID().c_str()));
  415. USE_SERIAL.printf("[Wifi] Connected: %s\n",WiFi.SSID().c_str());
  416. M5.Lcd.fillRect(0, 220, 320, 32, BLACK);
  417. M5.update();
  418. }
  419. // server address, port and URL
  420. webSocket.begin("192.168.4.1", 80, "/");
  421. // event handler
  422. webSocket.onEvent(webSocketEvent);
  423. // use HTTP Basic Authorization this is optional remove if not needed
  424. webSocket.setAuthorization(OVMSUSER, OVMSPASS);
  425. // try ever 5000 again if connection has failed
  426. webSocket.setReconnectInterval(2000);
  427. }
  428. void loop() {
  429. webSocket.loop();
  430. if(WiFiMulti.run() != WL_CONNECTED){
  431. M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
  432. M5.Lcd.setCursor(6, 222);
  433. M5.Lcd.setTextColor(WHITE);
  434. M5.Lcd.setTextSize(2);
  435. M5.Lcd.print("[Wifi] Reconnecting...");
  436. while(WiFiMulti.run() != WL_CONNECTED) {
  437. USE_SERIAL.printf("[Wifi] Connecting...\n");
  438. M5.Lcd.print(".");
  439. M5.update();
  440. delay(500);
  441. if (M5.BtnC.wasReleased()) changeLCDBrightness();
  442. }
  443. USE_SERIAL.printf("Wifi: %s\n",WiFi.SSID().c_str());
  444. M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
  445. M5.Lcd.setCursor(6, 222);
  446. M5.Lcd.print("[Wifi] : ");
  447. M5.Lcd.print(WiFi.SSID().c_str());
  448. M5.update();
  449. M5.Speaker.mute();
  450. delay(500);
  451. M5.Lcd.fillRect(0, 220, 320, 32, BLACK);
  452. M5.update();
  453. }
  454. //M5.Lcd.fillScreen(BLACK);
  455. if(M5triggerUpdate){
  456. M5.update();
  457. M5triggerUpdate = 0;
  458. }
  459. //USE_SERIAL.printf("end of loop\n");
  460. }