Send array from Arduino to html page on AsyncWebServer (ESP8266)

Hi together,

I have an AsyncWebServer running on an ESP8266 (with CP340).

It's no problem to send single values to the server:

Ardunio Sketch:

server.on("/vTemperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(vTemperature).c_str());
  });

Html code:

<!DOCTYPE HTML><html>
<head>
 <link rel="shortcut icon" href="#" />
</head>
 <body>
 <h2><span id="test">test</span></h2>
 <h2><span id="vTemperature">vTemperature</span></h2>
 </body>
<script>
 var vTest= 50;
 document.getElementById("test").textContent = vTest;
 
 var xhttp = new XMLHttpRequest();
 xhttp.onreadystatechange = function() {
 if (this.readyState == 4 && this.status == 200) {
 document.getElementById("vTemperature").innerHTML = this.responseText;
 }
 };
 xhttp.open("GET", "/vTemperature", true);
 xhttp.send(); 
</script>
</html>

So far so good. Now I would like to change this part, to read a complete array at once (in one loop). Can someone help me with this? Im really struggling with the syntax :smiley:

Thank you in advance!

Best regards
Noyen

Hi together,

I would like to concatenate a string and a variable to a new variablename. This name should not be written. The resulting variablename should be 'called' and the content of the variable should be shown. But I don't know how to 'call' it in this case:

Simple Example:

This line is my problem:

Serial.println("vPin0"+String(i));

It should print the content of the variable "vPin00". And not the string "vPin00".

Complete code:

//E8266 I/O Pinout
int vPin00 = 16;
int vPin01 = 5;
int vPin02 = 4;
int vPin03 = 0;
int vPin04 = 2;
int vPin05 = 14;
int vPin06 = 12;
int vPin07 = 13;
int vPin08 = 15;

void setup() {
  Serial.begin(115200);
  delay(200);
  Serial.println("###Setup###");
  //Set all pins to out pins
  pinMode(vPin00, OUTPUT);
  pinMode(vPin01, OUTPUT);
  pinMode(vPin02, OUTPUT);
  pinMode(vPin03, OUTPUT);
  pinMode(vPin04, OUTPUT);
  pinMode(vPin05, OUTPUT);
  pinMode(vPin06, OUTPUT);
  pinMode(vPin07, OUTPUT);
  pinMode(vPin08, OUTPUT);
}

void loop() {
  Serial.println("###Loop###");
  //loop all pins and set power on for 2 seconds
  for(int i=0; i <= 8; i++)
  {
    Serial.println("vPin0"+String(i)+": ");
    Serial.println("vPin0"+String(i));   //Here the variable content should be printed in the serial. But how :D
//    digitalWrite("vPin0"+String(i),HIGH);
//    delay(2000);
//    digitalWrite("vPin0"+String(i),LOW);
//    delay(2000);
  }
  delay(60000);
}

(Of course, for this example I could also write the pin i/o in an array and access just the array in the loop. But this is just a small example to explain the problem :))

Best regards
Noyen

To my knowledge, you can't do that in C/C++. Variable names are not dynamic.

int vPin00 = 16;
int vPin01 = 5;
int vPin02 = 4;
int vPin03 = 0;
int vPin04 = 2;
int vPin05 = 14;
int vPin06 = 12;
int vPin07 = 13;
int vPin08 = 15;

That looks like it would be a whole lot better as an array. Then, given the value of the second digit, use it as an index to the array and print the value at that array level.

const byte vPins[] = {16, 5, 4, 0, 2, 14, 12, 13, 14};
const byte NUMBER_OF_PINS = sizeof(vPins);

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  for (int pin = 0; pin < NUMBER_OF_PINS; pin++)
  {
    Serial.println(vPins[pin]);
  }
}

void loop()
{
}

noyen:
(Of course, for this example I could also write the pin i/o in an array and access just the array in the loop. But this is just a small example to explain the problem :))

Then you need to better explain your problem. The solution to this problem IS an array.

When you compile a C/C++ program all knowledge of the variable names are lost. Variables are just translated to memory addresses. So what you are suggesting (runtime evaluation of variable names) simply is not possible.

noyen:

Serial.println("vPin0"+String(i));

It should print the content of the variable "vPin00". And not the string "vPin00".

Nope, not in C/C++ it's compiled so the executed code knows nothing about vPin00.

But think about it: As written, I would expect it to do exactly what you observe, which in another situation might be what was desired. If such a feature existed, you would need something to tell the compiler "I'm building a variable name here", and the language has no such construct.

If the names are not in a neat pattern you would need an array of the values and an array of the names. Each time you had a string representing a name you would have to search for the name in the array of names and read the corresponding value from the value array.

It is hard to see a case where there is sufficient benefit to using constructed names instead of array indexes.

Hi together,

thank you all for your fast answeres. Sorry, I can't develop as much as I want. So my answere took a little longer :slight_smile:

Ok, if this is not possible, that's a pitty :smiley:

Well, my Problem is this:
I want to hand over a complete array with one function to an (Async)Webserver:

noyen:
Hi together,

I have an AsyncWebServer running on an ESP8266 (with CP340).

It's no problem to send single values to the server:

Ardunio Sketch:

server.on("/vTemperature", HTTP_GET, [](AsyncWebServerRequest *request){

request->send_P(200, "text/plain", String(vTemperature).c_str());
  });




Html code:


test

vTemperature

> ``` > > > > So far so good. Now I would like to change this part, to read a complete array at once (in one loop). Can someone help me with this? Im really struggling with the syntax :D > > Thank you in advance! > > Best regards > Noyen

I think the only solution for this is to hand over a string, that contains the array content, correct?

Best regards
Noyen

Topics merged

It makes more sense to have these topics merged into one so that the questions can be seen in context

Hi together,

thanks for the discussion and hints. Well, with that knowledge I was able to write my own solution based on an array:

String ArrayToString(byte *vAdressOfArray, int vPositionInArray)
{ 
  int i = 0;
  String vArrayContent;
  
  while(i<vPositionInArray)
  {
    vArrayContent = vArrayContent +String("|")+ String(*(vAdressOfArray + i));
    i++;
  }
  //Debugging
  Serial.print("Read from vArrayContent: ");
  Serial.println(vArrayContent);

  return vArrayContent;
}

(Hint: Also the delimiter ("|") and the start position (i) could be easily included in the method parameters, if needed.)

I call the function on browser request:

server.on("/ArrayHistTemperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(ArrayToString(HistTemperature, vHistTemperature_PositionInArray)).c_str());
  });

HERE I would like to add the possibility to call different arrays. E.g. HistHumidity. Or even define the start and end position of the 'array reading' by the browser request.
e.g. server.on("/Array<HistTemperature><0><50>", HTTP_GET, ...
-> And the microcontroller Returns the Array from Position 0 till 50.

That's why I was asking the Question in "Posted by noyen

  • Jul 12, 2020, 11:55 pm"

But if I can't split the name of the html request (currently: "/ArrayHistTemperature") I need to write several functions:

  • one request, that returns the complete array (initial load)
  • one for the incremente (delta load)
  • and one read just the array header, to get several settings (data history start date and time, intervall, array length)

Currently I hace 3 data vales -> 3 Arrays -> 9 functions. Possible, but it's limited.

By the way, if someone would like to use this sketch: In the html file I just call that function in a 10s intervall:

setInterval(function ( )
 {
 var xhttp = new XMLHttpRequest();
 xhttp.onreadystatechange = function() {
 if (this.readyState == 4 && this.status == 200) {
 document.getElementById("ArrayHistTemperature").innerHTML = this.responseText;
 }
 };
 xhttp.open("GET", "/ArrayHistTemperature", true);
 xhttp.send();
 }, 10000 ) ;

So still, if someone knows a hint, how to solve the issue I mentioned in my first post, it would help, to improve this method, wich could by used by a lot of projects I guess.

Best regards
Noyen