Trying to post multiple temperature sensors' values on a wifi shield server

Hi all,

I'm trying to use an ESP8266 WiFi Shield to show the temperature of a couple of my aquarium sumps. My DS18B20 temperature sensors are all set up, I'm using a bus to get the water temperature from four sensors. I tried to combine the codes for the WiFi shield and the temp probes, however I'm having trouble referencing the temperature under the html tags (towards the bottom, under void serverDemo). The original code for the temperature sensors use the Serial Monitor to display it's results, and somehow I can't get that transferred over to the shield.

My current code tries to use html += String(getTemp(Probe01)) to show that temperature, however I get a "invalid use of void expression" error. You may be able to tell that I'm pretty new to Arduino and coding in general, I'm not even confident that the String bit is set up correctly. Could anyone point me in the right direction?

I was able to post the temperature of one sensor, with it being defined as a float as per this code.

/*-----( WiFi Definitions )-----*/
#include <SoftwareSerial.h>
#include <SparkFunESP8266WiFi.h>

const char mySSID[] = "my SSID";
const char myPSK[] = "my password";
ESP8266Server server = ESP8266Server(80);
const char destServer[] = "example.com";
const String htmlHeader = "HTTP/1.1 200 OK\r\n"
                          "Content-Type: text/html\r\n"
                          "Connection: close\r\n\r\n"
                          "<!DOCTYPE HTML>\r\n"
                          "<html>\r\n";
const String httpRequest = "GET / HTTP/1.1\n"
                           "Host: example.com\n"
                           "Connection: close\n\n";

/*-----( Temp Probe Definitions)-----*/
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_PIN 2
OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);

DeviceAddress Probe01 = { 0x28, 0xFF, 0x73, 0x01, 0xA2, 0x16, 0x05, 0x24 }; // 1
DeviceAddress Probe02 = { 0x28, 0xFF, 0xA4, 0xF0, 0xA1, 0x16, 0x05, 0x31 }; // 2
DeviceAddress Probe03 = { 0x28, 0xFF, 0x99, 0x10, 0xA2, 0x16, 0x05, 0xF4 }; // 3
DeviceAddress Probe04 = { 0x28, 0xFF, 0x4A, 0x0A, 0xA2, 0x16, 0x05, 0xC7 }; // 4

void setup() {
  Serial.begin(9600);
  /*-----( WiFi Setup )-----*/
  initializeESP8266();
  connectESP8266;
  displayConnectInfo();
  clientDemo();
  serverSetup();
  /*-----( Temp Probe Setup )-----*/
  sensors.begin();
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);
  sensors.setResolution(Probe03, 10);
  sensors.setResolution(Probe04, 10);
}

void loop() {
  /*-----( WiFi Loop )-----*/
  serverDemo();
  /*-----( Temp Probe Loop )-----*/
  sensors.requestTemperatures();
  getTemp(Probe01);
  getTemp(Probe02);
  getTemp(Probe03);
  getTemp(Probe04);
}

/*-----( Temp Probe Main )-----*/

void getTemp(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
}

/*-----( WiFi Voids )-----*/
void initializeESP8266() //checks if wifi is working, sets it up for rest of sketch
{
  int test = esp8266.begin();
  if (test != true)
  {
    Serial.println(F("Error initiating ESP8266"));
    errorLoop(test);
  }
  Serial.println(F("ESP8266 Shield Online"));

}

void connectESP8266() //connects to network
{
  int retVal = esp8266.getMode(); //checks which mode shield is in.
  if (retVal != ESP8266_MODE_STA)
  { retVal = esp8266.setMode(ESP8266_MODE_STA); //sets mode to station only
    if (retVal < 0)
    {
      Serial.println(F("Error setting mode."));
      errorLoop(retVal);
    }
  }
  Serial.println(F("Mode set to station"));
  retVal = esp8266.status();
  if (retVal <= 0) //1 means already connected. 0 means disconnected. <0 means communication error
  {
    Serial.print(F("Connecting to"));
    Serial.println(mySSID);
    retVal = esp8266.connect(mySSID, myPSK); //connects to network
    if (retVal < 0)
    {
      Serial.println(F("Error connecting"));
      errorLoop(retVal);
    }
  }
}

void displayConnectInfo() //gets IP
{
  char connectedSSID[24];
  memset(connectedSSID, 0, 24);
  int retVal = esp8266.getAP(connectedSSID); //checks which Access Point wifi is connected to
  if (retVal > 0)
  {
    Serial.print(F("Connected to: "));
    Serial.println(connectedSSID);
  }

  IPAddress myIP = esp8266.localIP(); //returns current local IP as IPAddress
  Serial.print(F("My IP: ")); Serial.println(myIP);
}

void clientDemo()
{
  ESP8266Client client; //uses shield as client
  int retVal = client.connect(destServer, 80); //connects to server, put IP here
  if (retVal <= 0)
  {
    Serial.println(F("Did not connect to server"));
    return;
  }
  client.print(httpRequest); // print and write used to send data to a connected client connection
  while (client.available()) //returns number of characters in receive buffer
    Serial.write(client.read()); //gets the FIFO char
  if (client.connected()) //connected is 1 if connection active, 0 if it's closed
    client.stop(); //stop closes TCP connection
}

void serverSetup()
{
  server.begin(); //initializes shield object. Starts server on port specified in global area
  Serial.print(F("I'm online! Go to "));
  Serial.println(esp8266.localIP());
  Serial.println();
}

/*-----( WiFi HTML )-----*/
void serverDemo()
{

  ESP8266Client client = server.available(500); //available returns object for printing and reading. 500 is milliseconds the function waits, checking for conneciton

  if (client)
  {
    Serial.println(F("Client connected!!!"));
    boolean currentLineIsBlank = true; //http request ends with a blank line
    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) //if line is blank at end of line, http request ended. So send reply
        {
          Serial.println(F("Sending HTML page"));
          client.print(htmlHeader); //sends standard http response header
          String htmlBody;
          for (int a = 0; a < 1; a++)
          {
            htmlBody += "Temperature of water at location ";
            htmlBody += " is: ";
            htmlBody += String(getTemp(Probe01));
            htmlBody += "C";
            htmlBody += "
 The water level reached ";
            htmlBody += String(analogRead(A0));
            htmlBody += "mm above the sensor";
            htmlBody += "
\n";
          }
          htmlBody += "<html>\n";
          client.print(htmlBody);
          break;
        }
        if (c == '\n')
        {
          currentLineIsBlank = true; //start a new line
        }
        else if (c != '\r')
        {
          currentLineIsBlank = false; //got a character on the current line
        }
      }
    }
    delay(1); //gives browser time to receive data
    client.stop(); //closes connection
    Serial.println(F("Client disconnected"));
  }
}

void errorLoop(int error) //prints error code then loops forever
{
  Serial.print(F("Error: ")); Serial.println(error);
  Serial.println(F("Looping forever."));
  for (;;)
    ;
}

void serialTrigger(String message) //prints message, then waits for input from serial port
{
  Serial.println();
  Serial.println(message);
  Serial.println();
  while (!Serial.available())
    ;
  while (Serial.available())
    Serial.read();
}

This sounds like a really cool project. Unfortunately, I too am new to C/C++.

I think this is because your function getTemp() doesn't actually return anything when when you try to convert it to a String, the String class complains.

Right now, all getTemp does is create a local variable tempC and set the value to sensors.getTempC(deviceAddress);

You have two options, return the value or skip that function entirely and call sensors.getTempC(Probe01), as such:

html += String(sensors.getTempC(Probe01))

Furthermore, you may not even need the String class for that line, so if the above code doesn't work, try html += sensors.getTempC(Probe01); instead.

Good luck.

One step would be to have your getTemp function return a value:

float getTemp(DeviceAddress deviceAddress) {
  return sensors.getTempC(deviceAddress);
}

Either that or use sensors.getTemp() in place of your getTemp() function.

smacaroni:
This sounds like a really cool project. Unfortunately, I too am new to C/C++.

I think this is because your function getTemp() doesn't actually return anything when when you try to convert it to a String, the String class complains.

Right now, all getTemp does is create a local variable tempC and set the value to sensors.getTempC(deviceAddress);

You have two options, return the value or skip that function entirely and call sensors.getTempC(Probe01), as such:

html += String(sensors.getTempC(Probe01))

Furthermore, you may not even need the String class for that line, so if the above code doesn't work, try html += sensors.getTempC(Probe01); instead.

Good luck.

Actually, you were right! Using sensors.getTempC(Probe01) did the trick, although it only worked for 2/4 temperature probes. I think there must be a character limit? Because when I shortened my text to just "Location 1: xC" then it showed all 4 probes, but when it was a longer sentence like "The temperature at Location 1 is xC" then the last two probes were cut off.

johnwasser:
One step would be to have your getTemp function return a value:

float getTemp(DeviceAddress deviceAddress) {

return sensors.getTempC(deviceAddress);
}




Either that or use sensors.getTemp() in place of your getTemp() function.

sensors.getTempC worked, however what is the reason that my getTemp() function didn't? I was under the impression that   float tempC = sensors.getTempC(deviceAddress); assigns the value that getTempC gets from my request (so, Probe01) to tempC?

scardu:
what is the reason that my getTemp() function didn't? I was under the impression that

  float tempC = sensors.getTempC(deviceAddress);

assigns the value that getTempC gets from my request (so, Probe01) to tempC?

You declare tempC in your function. That makes it a local variable that only exists inside that function. You don't use that value for anything and it disappears as soon as the function ends.
If tempC had been a global variable (declared outside any function) you could have removed the 'float' declaration in your function and stored the value in the global variable. Then you could use:

            htmlBody += "Temperature of water at location 1 is ";
            getTemp(Probe01);
            htmlBody += String(tempC);
            htmlBody += "Temperature of water at location 2 is ";
            getTemp(Probe02);
            htmlBody += String(tempC);

It is cleaner to have getTemp() return the value and write:

            htmlBody += "Temperature of water at location 1 is ";
            htmlBody += String(getTemp(Probe01));
            htmlBody += "Temperature of water at location 2 is ";
            htmlBody += String(getTemp(Probe02));

But since your function doesn't do much you can eliminate it and just write:

            htmlBody += "Temperature of water at location 1 is ";
            htmlBody += String(sensors.getTemp(Probe01));
            htmlBody += "Temperature of water at location 2 is ";
            htmlBody += String(sensors.getTemp(Probe02));