Fork of Farrukh's webserver. Tested on LPC1768 and STM32f401 but should work on almost any platform.
New version that has been tested on LPC1768 and STM32F401 Based on Farrukh's idea here: https://os.mbed.com/users/programmer5/code/STM32-ESP8266-WEBSERVER/
Enter your Wi-Fi SSID and PASSWORD and edit the espbaud to suit your ESP8266, Works fast and stable at 460800.
Use configuration program to reset and set up the ESP8266 if needed:
https://os.mbed.com/users/star297/code/ESP8266-configuaration-baudrate/
Limitations are no HTTPS.
Diff: main.cpp
- Revision:
- 4:7334688498cc
- Parent:
- 3:f7febfa77784
- Child:
- 5:efcfa9e61907
--- a/main.cpp Tue Feb 24 23:58:24 2015 +0000 +++ b/main.cpp Mon Apr 20 20:43:33 2020 +0000 @@ -1,330 +1,90 @@ -// ESP8266 Static page WEB server to control Mbed - #include "mbed.h" -#include "DS18B20.h" - -Serial pc(USBTX, USBRX); -Serial esp(PTE0, PTE1); // tx, rx - -DS18B20 thermom(A0, DS18B20::RES_12_BIT); - -// Standard Mbed LED definitions -DigitalOut led1(LED_RED); // (PTB18) -DigitalOut led2(LED_GREEN); // (PTB19) -DigitalOut led3(LED_BLUE); // (PTD1) - -// Digital Out and In pins, can be configured to any suitable pin depending on Platform -DigitalOut Out1(D7); -DigitalOut Out2(D8); -DigitalOut Out3(D4); - -DigitalIn In1(A2); -DigitalIn In2(A3); -DigitalIn In3(A4); - -PwmOut speaker(D5); -AnalogIn BATin(A1); - -Timer t1; -Timer t2; - -struct tm t; - -int bufflen, DataRX, count, getcount, replycount, servreq, timeout; -int bufl, ipdLen, linkID, weberror, webcounter; -float temperature, AdcIn, Ht; -float R1=100000, R2=10000; // resistor values to give a 10:1 reduction of measured AnalogIn voltage -char Vcc[10]; -char Temp[10]; -char temp[10]; -char webcount[8]; -char lasthit[30]; -char timebuf[30]; -char type[16]; -char type1[16]; -char channel[2]; -char cmdbuff[32]; -char replybuff[512]; -char webdata[1024]; // This may need to be bigger depending on WEB browser used -char webbuff[4096]; // Currently using 1986 characters, Increase this if more web page data added - -void SendCMD(),getreply(),ReadWebData(),startserver(),sendpage(),SendWEB(),sendcheck(); -void gettime(),gettemp(),getbattery(),setRTC(),beep(); - -// manual set RTC values -int minute =20; // 0-59 -int hour =9; // 2-23 -int dayofmonth =20; // 1-31 -int month =2; // 1-12 -int year =15; // last 2 digits - -int port =8266; // set server port -int SERVtimeout =5; // set server timeout in seconds incase link breaks. - -// Serial Interrupt read ESP data -void callback() { - while (esp.readable()) {webbuff[count] = esp.getc();count++;} - if(strlen(webbuff)>bufflen){DataRX=1;} -} -int main() { - led1=1,led2=1,led3=1; - pc.baud(115200); - esp.baud(115200); // ESP8266 baudrate. Maximum on KLxx' is 115200, 230400 works on K20 and K22F - if (time(NULL) < 1420070400) {setRTC();} - beep(); - startserver(); - - while(1){ - if(DataRX==1){ - ReadWebData(); - beep(); - if (servreq == 1 && weberror == 0){sendpage();} - esp.attach(&callback); - pc.printf(" IPD Data:\r\n\n Link ID = %d,\r\n IPD Header Length = %d \r\n IPD Type = %s\r\n", linkID, ipdLen, type); - pc.printf("\n\n HTTP Packet: \n\n%s\n", webdata); - pc.printf(" Web Characters sent : %d\n\n", bufl); - pc.printf(" -------------------------------------\n\n"); - strcpy(lasthit, timebuf); - servreq=0; - } - } -} -// Static WEB page -void sendpage() -{ - gettemp(); - getbattery();gettime(); - -// WEB page data - strcpy(webbuff, "<!DOCTYPE html>"); - strcat(webbuff, "<html><head><title>ESP8266 Mbed</title></head>"); - strcat(webbuff, "<body>"); - strcat(webbuff, "<div style=\"text-align:center; background-color:#F4F4F4; color:#00AEDB;\"><h1>ESP8266 Mbed Web Controller</h1>"); - strcat(webbuff, "Hit Count - "); - strcat(webbuff, webcount); - strcat(webbuff, "<br>Last Hit - "); - strcat(webbuff, lasthit); - strcat(webbuff, "</div><br /><hr>"); - strcat(webbuff, "<h3>Mbed RTC Time -  "); - strcat(webbuff, timebuf); - strcat(webbuff, "</h3>\r\n"); - strcat(webbuff, "<p><form method=\"POST\"><strong> Temperature:  <input type=\"text\" size=6 value=\""); - strcat(webbuff, Temp); - strcat(webbuff, "\"> <sup>O</sup>C <form method=\"POST\"> <strong>   Battery:  <input type=\"text\" size=4 value=\""); - strcat(webbuff, Vcc); - strcat(webbuff, "\"> </sup>V"); - if(led1==1){strcat(webbuff, "<p><input type=\"radio\" name=\"led1\" value=\"0\" checked> Red LED off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"led1\" value=\"1\" > Red LED on");} - else{strcat(webbuff, "<p><input type=\"radio\" name=\"led1\" value=\"0\" > Red LED off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"led1\" value=\"1\" checked> Red LED on");} - if(Out1==0){strcat(webbuff, "<p><input type=\"radio\" name=\"Out1\" value=\"0\" checked> Digital Out 1 off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"Out1\" value=\"1\" > Digital Out 1 on");} - else{strcat(webbuff, "<p><input type=\"radio\" name=\"Out1\" value=\"0\" > Digital Out 1 off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"Out1\" value=\"1\" checked> Digital Out 1 on");} - if(Out2==0){strcat(webbuff, "<p><input type=\"radio\" name=\"Out2\" value=\"0\" checked> Digital Out 2 off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"Out2\" value=\"1\" > Digital Out 2 on");} - else{strcat(webbuff, "<p><input type=\"radio\" name=\"Out2\" value=\"0\" > Digital Out 2 off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"Out2\" value=\"1\" checked> Digital Out 2 on");} - if(Out3==0){strcat(webbuff, "<p><input type=\"radio\" name=\"Out3\" value=\"0\" checked> Digital Out 3 off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"Out3\" value=\"1\" > Digital Out 3 on");} - else{strcat(webbuff, "<p><input type=\"radio\" name=\"Out3\" value=\"0\" > Digital Out 3 off"); - strcat(webbuff, "<br><input type=\"radio\" name=\"Out3\" value=\"1\" checked> Digital Out 3 on");} - if(In1==0){strcat(webbuff, "<p><input type=\"radio\" name=\"In1\" value=\"0\" > Digital In 1");} - else{strcat(webbuff, "<p><input type=\"radio\" name=\"In1\" value=\"1\" checked> Digital In 1");} - if(In2==0){strcat(webbuff, "<br><input type=\"radio\" name=\"In2\" value=\"0\" > Digital In 2");} - else{strcat(webbuff, "<br><input type=\"radio\" name=\"In2\" value=\"1\" checked> Digital In 2");} - if(In3==0){strcat(webbuff, "<br><input type=\"radio\" name=\"In3\" value=\"0\" > Digital In 3");} - else{strcat(webbuff, "<br><input type=\"radio\" name=\"In3\" value=\"1\" checked> Digital In 3");} - strcat(webbuff, "</strong><p><input type=\"submit\" value=\"send-refresh\" style=\"background: #3498db;"); - strcat(webbuff, "background-image:-webkit-linear-gradient(top, #3498db, #2980b9);"); - strcat(webbuff, "background-image:linear-gradient(to bottom, #3498db, #2980b9);"); - strcat(webbuff, "-webkit-border-radius:12;border-radius: 12px;font-family: Arial;color:#ffffff;font-size:20px;padding:"); - strcat(webbuff, "10px 20px 10px 20px; border:solid #103c57 3px;text-decoration: none;"); - strcat(webbuff, "background: #3cb0fd;"); - strcat(webbuff, "background-image:-webkit-linear-gradient(top,#3cb0fd,#1a5f8a);"); - strcat(webbuff, "background-image:linear-gradient(to bottom,#3cb0fd,#1a5f8a);"); - strcat(webbuff, "text-decoration:none;\"></form></span>"); - strcat(webbuff, "<p/><h2>How to use:</h2><ul>"); - strcat(webbuff, "<li>Select the Radio buttons to control the digital out pins.</li>"); - strcat(webbuff, "<li>Click 'Send-Refresh' to send.</li>"); - strcat(webbuff, "<li>Use the 'Send-Refresh' button to refresh the data.</li>"); - strcat(webbuff, "</ul>"); - strcat(webbuff, "</body></html>"); -// end of WEB page data - bufl = strlen(webbuff); // get total page buffer length - sprintf(cmdbuff,"AT+CIPSEND=%d,%d\r\n", linkID, bufl); // send IPD link channel and buffer character length. - timeout=200;getcount=7; - SendCMD(); - getreply(); - SendWEB(); // send web page - memset(webbuff, '\0', sizeof(webbuff)); - sendcheck(); -} +// LPC1768 +//Serial ports to be used +Serial pc(USBTX,USBRX);//TO BE used for debug info +Serial esp(p13,p14);//TX,RX TO BE CONNECTED TO ESP +Serial esp2(p13,p14);//TX,RX TO BE CONNECTED TO ESP +DigitalOut espreset(p25,1); +//Connections to relay +//relay works at logic LOW +DigitalOut digital_out_1(LED1,1);// High on initialization +DigitalOut digital_out_2(LED2,1);// High on initialization +DigitalOut digital_out_3(LED3,1);// High on initialization +DigitalOut digital_out_4(LED4,1);// High on initialization +//digital inputs, connected to push buttons +DigitalIn digital_in_1(p21); +DigitalIn digital_in_2(p22); +DigitalIn digital_in_3(p23); +DigitalIn digital_in_4(p24); +//Analog output +PwmOut analog_out_1(p26); +//Analog Input +AnalogIn tempSensor(p20); -// wait for ESP "SEND OK" reply, then close IP to load web page -void sendcheck() -{ - weberror=1;timeout=500;getcount=24; - t2.reset();t2.start(); - while(weberror==1 && t2.read() <5){ - getreply(); - if (strstr(replybuff, "SEND OK") != NULL) {weberror=0;} // wait for valid SEND OK - } - if(weberror==1){ // restart connection - strcpy(cmdbuff, "AT+CIPMUX=1\r\n"); - timeout=500;getcount=10; - SendCMD();getreply(); - sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port); - timeout=500;getcount=10; - SendCMD();getreply(); - } - else{ - sprintf(cmdbuff, "AT+CIPCLOSE=%s\r\n",channel); // close current connection - SendCMD();} - t2.reset(); -} +//F401 +/* +//Serial ports to be used +Serial pc(USBTX,USBRX);//TO BE used for debug info +Serial esp(D8,D2);//TX,RX TO BE CONNECTED TO ESP +Serial esp2(D8,D2);//TX,RX TO BE CONNECTED TO ESP +//Connections to relay +//relay works at logic LOW +DigitalOut digital_out_1(D3,1);// High on initialization +DigitalOut digital_out_2(D4,1);// High on initialization +DigitalOut digital_out_3(D5,1);// High on initialization +DigitalOut digital_out_4(D6,1);// High on initialization +//digital inputs, connected to push buttons +DigitalIn digital_in_1(A1); +DigitalIn digital_in_2(A2); +DigitalIn digital_in_3(A3); +DigitalIn digital_in_4(A4); +//Analog output +PwmOut analog_out_1(D15); +//Analog Input +AnalogIn tempSensor(A0); +*/ + +char ssid[32] = "ssid"; // enter your router ssid inside the quotes +char pwd[32] = "password"; // enter your router password inside the quotes + -// Reads and processes GET and POST web data -void ReadWebData() - { - wait_ms(200); - esp.attach(NULL); - count=0;DataRX=0;weberror=0; - memset(webdata, '\0', sizeof(webdata)); - int x = strcspn (webbuff,"+"); - if(x){ - strcpy(webdata, webbuff + x);weberror=0; - int numMatched = sscanf(webdata,"+IPD,%d,%d:%s", &linkID, &ipdLen, type); - if( strstr(webdata, "led1=1") != NULL ) {led1=0;} - if( strstr(webdata, "led1=0") != NULL ) {led1=1;} - if( strstr(webdata, "Out1=1") != NULL ) {Out1=1;} - if( strstr(webdata, "Out1=0") != NULL ) {Out1=0;} - if( strstr(webdata, "Out2=1") != NULL ) {Out2=1;} - if( strstr(webdata, "Out2=0") != NULL ) {Out2=0;} - if( strstr(webdata, "Out3=1") != NULL ) {Out3=1;} - if( strstr(webdata, "Out3=0") != NULL ) {Out3=0;} - sprintf(channel, "%d",linkID); - if (strstr(webdata, "GET") != NULL) {servreq=1;} - if (strstr(webdata, "POST") != NULL) {servreq=1;} - webcounter++; - sprintf(webcount, "%d",webcounter); - } - else { - memset(webbuff, '\0', sizeof(webbuff)); - esp.attach(&callback);weberror=1; - } -} -// Starts and restarts webserver if errors detected. -void startserver() -{ - gettemp();gettime(); - pc.printf("\n\n RTC time %s\r\n\n",timebuf); - pc.printf("++++++++++ Resetting ESP ++++++++++\r\n"); - strcpy(cmdbuff,"AT+RST\r\n"); - timeout=2000;getcount=600; - SendCMD(); - getreply(); - pc.printf(replybuff); - pc.printf("%d",count); - if (strstr(replybuff, "OK") != NULL) { - pc.printf("\n++++++++++ Starting Server ++++++++++\r\n"); - strcpy(cmdbuff, "AT+CIPMUX=1\r\n"); // set multiple connections. - timeout=500;getcount=10; - SendCMD(); - getreply(); - sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port); - timeout=500;getcount=10; - SendCMD(); - getreply(); - sprintf(cmdbuff,"AT+CIPSTO=%d\r\n",SERVtimeout); - timeout=500;getcount=50; - SendCMD(); - getreply(); - pc.printf("\n Getting Server IP \r\n"); - strcpy(cmdbuff, "AT+CIFSR\r\n"); - timeout=1000;getcount=50; - while(weberror==0){ - SendCMD();getreply(); - if (strstr(replybuff, "0.0.0.0") == NULL) {weberror=1;} // wait for valid IP - } - pc.printf("\n Enter WEB address in your browser \r\n\n"); - replybuff[strlen(replybuff) - 8] = '\0'; - char* IP = replybuff + 5; - sprintf(webdata," http://%s:%d", IP, port); - pc.printf(webdata); - led2=0;wait(2);led2=1; - bufflen=200;count=0; - pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n"); - esp.attach(&callback); - } - else{ - pc.printf("\n++++++++++ ESP8266 error, check power/connections ++++++++++\r\n"); - while(1){} - } - t2.reset();t2.start();beep(); -} -// ESP Command data send -void SendCMD() -{ - esp.printf("%s", cmdbuff); -} -// Large WEB buffer data send -void SendWEB() -{ - int i=0; - if(esp.writeable()) { - while(webbuff[i]!='\0') {esp.putc(webbuff[i]);i++;} - } -} -// Get Cammand and ESP status replies -void getreply() -{ - memset(replybuff, '\0', sizeof(replybuff)); - t1.reset(); t1.start();replycount=0; - while(t1.read_ms()< timeout && replycount < getcount) { - if(esp.readable()) { - replybuff[replycount] = esp.getc();replycount++; - } - } - t1.stop(); -} -// Analog in example -void getbattery() -{ - AdcIn=BATin.read(); - Ht = (AdcIn*3.328f*(R1+R2)/R2); // set the numeric to the exact MCU analog reference voltage for greater accuracy - sprintf(Vcc,"%2.3f",Ht); -} -// Temperature example -void gettemp() -{ - temperature=thermom.GetTemperature(); // comment this out if no sensor connected - //temperature = 21.357; // include for dummy value - sprintf(Temp,"%3.3f",temperature); -} -// Get RTC time -void gettime() -{ - time_t seconds = time(NULL); - strftime(timebuf,50,"%H:%M:%S %a %d %b %y", localtime(&seconds)); -} +#define BUFFER_SIZE 3000 +#define REQ_LINE_BUFF_SIZE 100 +#define UNKNOWN 0 +#define OK 1 +#define ERROR 2 +#define FAIL 3 +#define READY 4 +#define READY_TO_WRITE_TCP 5 + -void beep() -{ - speaker.period(1.0/2000); // 2000hz period - speaker = 0.5; //50% duty cycle - max volume - wait_ms(60); - speaker=0.0; // turn off audio -} +const char get_analog_outputs_status[]="/analog_outputs"; +const char get_Toggle_Output[]="/digital_outputs/toggle"; +const char get_analog_inputs_status[]="/analog_inputs"; +const char get_analog_output_update[]="/analog_outputs/update"; +const char get_digital_output_status[]="/digital_outputs"; +const char get_digital_inputs_html[]="/dinputs.html"; +const char get_digital_input_status[]="/digital_inputs"; +const char get_index_html[]="/index.html"; +const char get_analog_outputs[]="/anoutputs.html"; +const char get_analog_inputs_html[]="/aninputs.html"; + + +const char jsonHeader[]="HTTP/1.1 200 OK\n" + "Content-type: application/json\r\n\r\n"; -void setRTC() -{ - t.tm_sec = (0); // 0-59 - t.tm_min = (minute); // 0-59 - t.tm_hour = (hour); // 0-23 - t.tm_mday = (dayofmonth); // 1-31 - t.tm_mon = (month-1); // 0-11 "0" = Jan, -1 added for Mbed RCT clock format - t.tm_year = ((year)+100); // year since 1900, current DCF year + 100 + 1900 = correct year - set_time(mktime(&t)); // set RTC clock -} +const char textPlainHeader[]="HTTP/1.1 200 OK\n" + "Content-type: text/plain\r\n\r\n"; + +const char index_html[]="HTTP/1.1 200 OK\n" + "Content-type: text/html\r\n\r\n" + "<!DOCTYPE html>\n<html>\n<head>\n<title>esp</title>\n<link rel=stylesheet type=text/css href=css/style.css>\n<script src=https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js></script>\n<script>$(document).ready(function(){setInterval(\"get_digital_output_status()\",2000)});function get_digital_output_status(){var a=\"/digital_outputs\";$.ajax({url:a,dataType:\"json\",success:function(b){if(b.digital_outputs.dout1==1){$(\"#dout1\").html(\"HIGH\")}else{$(\"#dout1\").html(\"LOW\")}if(b.digital_outputs.dout2==1){$(\"#dout2\").html(\"HIGH\")}else{$(\"#dout2\").html(\"LOW\")}if(b.digital_outputs.dout3==1){$(\"#dout3\").html(\"HIGH\")}else{$(\"#dout3\").html(\"LOW\")}if(b.digital_outputs.dout4==1){$(\"#dout4\").html(\"HIGH\")}else{$(\"#dout4\").html(\"LOW\")}},timeout:2000})}function digital_output_toggle(a){var b=\"/digital_outputs/toggle?pin=\"+a;$.ajax({url:b,dataType:\"text\",success:function(c){if(c==\"1\"){$(\"#\"+a).html(\"HIGH\")}else{if(c==\"0\"){$(\"#\"+a).html(\"LOW\")}else{alert(\"failed to toggle digital output\")}}},timeout:2000})};</script>\n</head>\n<body>\n<header>\n<img src=images/logo.jpg>\n<h1>ESP8266 BASED WEBSERVER</h1>\n</header>\n<nav>\n<ul>\n<li><a class=active href=index.html>Digital Outputs</a></li>\n<li><a href=dinputs.html>Digital inputs</a></li>\n<li><a href=anoutputs.html>Analog Outputs</a></li>\n<li><a href=aninputs.html>Analog Inputs</a></li>\n</ul>\n</nav>\n<section>\n<table>\n<tr>\n<th>Digital Ouput</th>\n<th>Status</th>\n<th>Option</th>\n</tr>\n<tr>\n<td>DOut1</td>\n<td id=dout1>waiting..</td>\n<td><button class=button onclick=\"digital_output_toggle('dout1')\">Toggle</button>\n</td>\n</tr>\n<tr>\n<td>DOut2</td>\n<td id=dout2>waiting..</td>\n<td><button class=button onclick=\"digital_output_toggle('dout2')\">Toggle</button>\n</tr>\n<tr>\n<td>DOut3</td>\n<td id=dout3>waiting..</td>\n<td><button class=button onclick=\"digital_output_toggle('dout3')\">Toggle</button>\n</tr>\n<tr>\n<td>DOut4</td>\n<td id=dout4>waiting..</td>\n<td><button class=button onclick=\"digital_output_toggle('dout4')\">Toggle</button>\n</tr>\n</table>\n</section>\n</body>\n</html>"; + +const char digitalInputs_html[]="HTTP/1.1 200 OK\n" + "Content-type: text/html\r\n\r\n" + "<!DOCTYPE html>\n<html>\n<head>\n<title>esp</title>\n<link rel=stylesheet type=text/css href=css/style.css>\n<script src=https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js></script>\n<script>$(document).ready(function(){setInterval(\"get_digital_input_status()\",2000)});function get_digital_input_status(){var a=\"/digital_inputs\";$.ajax({url:a,dataType:\"json\",success:function(b){if(b.digital_inputs.din1==1){$(\"#din1\").html(\"HIGH\")}else{$(\"#din1\").html(\"LOW\")}if(b.digital_inputs.din2==1){$(\"#din2\").html(\"HIGH\")}else{$(\"#din2\").html(\"LOW\")}if(b.digital_inputs.din3==1){$(\"#din3\").html(\"HIGH\")}else{$(\"#din3\").html(\"LOW\")}if(b.digital_inputs.din4==1){$(\"#din4\").html(\"HIGH\")}else{$(\"#din4\").html(\"LOW\")}},timeout:2000})};</script>\n</head>\n<body>\n<header>\n<img src=images/logo.jpg>\n<h1>ESP8266 BASED WEBSERVER</h1>\n</header>\n<nav>\n<ul>\n<li><a href=index.html>Digital Outputs</a></li>\n<li><a class=active href=dinputs.html>Digital inputs</a></li>\n<li><a href=anoutputs.html>Analog Outputs</a></li>\n<li><a href=aninputs.html>Analog Inputs</a></li>\n</ul>\n</nav>\n<section>\n<table id=inputsTable>\n<tr>\n<th>Digital Input</th>\n<th>Status</th>\n</tr>\n<tr>\n<td>DIn1</td>\n<td id=din1>waiting..</td>\n</td>\n</tr>\n<tr>\n<td>DIn2</td>\n<td id=din2>waiting..</td>\n</tr>\n<tr>\n<td>DIn3</td>\n<td id=din3>waiting..</td>\n</tr>\n<tr>\n<td>DIn4</td>\n<td id=din4>waiting..</td>\n</tr>\n</table>\n</section>\n</body>\n</html>"; + +const char analog_outputs_html[]="HTTP/1.1 200 OK\n" + "Content-type: text/html\r\n\r\n" + "<!DOCTYPE html>\n<html>\n<head>\n<title>esp</title>\n<link rel=stylesheet type=text/css href=css/style.css>\n<script src=https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js></script>\n<script type=text/javascript src=https://www.gstatic.com/charts/loader.js></script>\n<script>$(document).ready(function(){setInterval(\"getAnalogOutputStatus()\",2000);displayVoltageLevel()});var voltage_level=0;function getAnalogOutputStatus(){var a=\"/analog_outputs\";$.ajax({url:a,dataType:\"text\",success:function(b){voltage_level=parseFloat(b)},timeout:2000})}function setNewVoltageLevel(a){var b=\"/analog_outputs/update?value=\"+a;$.ajax({url:b,dataType:\"text\",success:function(c){voltage_level=parseFloat(c)},timeout:2000})}function displayVoltageLevel(){google.charts.load(\"current\",{packages:[\"gauge\"]});google.charts.setOnLoadCallback(a);function a(){var d=google.visualization.arrayToDataTable([[\"Label\",\"Value\"],[\"Volts\"%2 \ No newline at end of file