Trouble getting temps onto webpage

It would seem that the serial connection gives me the temps no problem at all, but, when I serve from the arduino it will not print the temps as the serial has been doing, I suspect I have a formatting problem. When I try to write anything else after client.print I come up with an error of various types.

I suppose I am just not sure of what I have done wrong, the following code compiles but does not print the temps out to the webpage.

Any hints for a newbie?

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Ethernet.h>

// Data wire is plugged into pin 4 on the Arduino
#define ONE_WIRE_BUS 6

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);


// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 20); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80

EthernetClient client;

//Device addresses

DeviceAddress RumFerment = { 0x28, 0x2E, 0x27, 0xE1, 0x06, 0x00, 0x00, 0x05 };
DeviceAddress UJFerment = { 0x28, 0x37, 0x43, 0xE1, 0x06, 0x00, 0x00, 0xC6 };
DeviceAddress NeutralFerment = { 0x28, 0x2F, 0x42, 0xE0, 0x06, 0x00, 0x00, 0x7E };
DeviceAddress FermenterTop = { 0x28, 0x6E, 0x8E, 0xDF, 0x06, 0x00, 0x00, 0xED };
DeviceAddress FermenterBottom = { 0x28, 0x6B, 0xE0, 0xE0, 0x06, 0x00, 0x00, 0x67 };

void setup(void)
{
  // Start server and ethernet
  Ethernet.begin(mac, ip);
  server.begin();
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(RumFerment, 10);
  sensors.setResolution(UJFerment, 10);
  sensors.setResolution(NeutralFerment, 10);
  sensors.setResolution(FermenterTop, 10);
  sensors.setResolution(FermenterBottom, 10);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    Serial.print("C: ");
    Serial.print(tempC);

  }
}

void loop(void)
{
  delay(2000);
  Serial.print("Getting temperatures...\n\r");
  sensors.requestTemperatures();

  Serial.print("Rum Ferment Temp is: ");
  printTemperature(RumFerment);
  Serial.print("\n\r");
  Serial.print("UJ Ferment Temp is: ");
  printTemperature(UJFerment);
  Serial.print("\n\r");
  Serial.print("Neutral Ferment Temp is: ");
  printTemperature(NeutralFerment);
  Serial.print("\n\r");
  Serial.print("Fermenter Top Temp is: ");
  printTemperature(FermenterTop);
  Serial.print("\n\r");
  Serial.print("Fermanter Bottom Temp is: ");
  printTemperature(FermenterBottom);
  Serial.print("\n\r");

   listenForEthernetClients();


}



void listenForEthernetClients() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Got a client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          // print the current readings, in HTML format:
          client.println("Rum Ferment Temp is: ");
          printTemperature(RumFerment);
          client.print("\n");
          client.println("UJ Ferment Temp is: ");
          printTemperature(UJFerment);
          client.print("\n");
          client.println("Neutral Ferment Temp is: ");
          printTemperature(NeutralFerment);
          client.print("\n");
          client.println("Fermenter Top Temp is: ");
          printTemperature(FermenterTop);
          client.print("\n");
          client.println("Fermanter Bottom Temp is: ");
          printTemperature(FermenterBottom);
          client.print("\n\r");

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

The below test code prints the current analog input pin values to the web page. You might make something similar to start with.

// zoomkat's meta refresh data frame test page 5/25/13
// use http://192.168.1.102:84 in your brouser for main page
// http://192.168.1.102:84/data static data page
// http://192.168.1.102:84/datastart meta refresh data page
// for use with W5100 based ethernet shields
// set the refresh rate to 0 for fastest update
// use STOP for single data updates

#include <SPI.h>
#include <Ethernet.h>

const int analogInPin0 = A0;
const int analogInPin1 = A1;
const int analogInPin2 = A2;
const int analogInPin3 = A3;
const int analogInPin4 = A4;
const int analogInPin5 = A5;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
unsigned long int x=0; //set refresh counter to 0
String readString; 

//////////////////////

void setup(){
  Serial.begin(9600);
    // disable SD SPI if memory card in the uSD slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();
  Serial.println("meta refresh data frame test 5/25/13"); // so I can keep track of what is loaded
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         if (readString.length() < 100) {
          readString += c; 
         } 
        //check if HTTP request has ended
        if (c == '\n') {

          //check get atring received
          Serial.println(readString);

          //output HTML data header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //generate data page
          if(readString.indexOf("data") >0) {  //checks for "data" page
            x=x+1; //page upload counter
            client.print("<HTML><HEAD>");
            //meta-refresh page every 1 seconds if "datastart" page
            if(readString.indexOf("datastart") >0) client.print("<meta http-equiv='refresh' content='1'>"); 
            //meta-refresh 0 for fast data
            if(readString.indexOf("datafast") >0) client.print("<meta http-equiv='refresh' content='0'>"); 
            client.print("<title>Zoomkat's meta-refresh test</title></head><BODY>
");
            client.print("page refresh number: ");
            client.print(x); //current refresh count
            client.print("

");
            
              //output the value of each analog input pin
            client.print("analog input0 is: ");
            client.print(analogRead(analogInPin0));
            
            client.print("
analog input1 is: ");
            client.print(analogRead(analogInPin1));
                        
            client.print("
analog input2 is: ");
            client.print(analogRead(analogInPin2));
            
            client.print("
analog input3 is: ");
            client.print(analogRead(analogInPin3));
                                    
            client.print("
analog input4 is: ");
            client.print(analogRead(analogInPin4));
            
            client.print("
analog input5 is: ");
            client.print(analogRead(analogInPin5));
            client.println("
</BODY></HTML>");
           }
          //generate main page with iframe
          else
          {
            client.print("<HTML><HEAD><TITLE>Zoomkat's frame refresh test</TITLE></HEAD>");
            client.print("Zoomkat's Arduino frame meta refresh test 5/25/13");
            client.print("

Arduino analog input data frame:
");
            client.print("&nbsp;&nbsp;<a href='http://192.168.1.102:84/datastart' target='DataBox' title=''yy''>META-REFRESH</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://192.168.1.102:84/data' target='DataBox' title=''xx''>SINGLE-STOP</a>");
            client.print("&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://192.168.1.102:84/datafast' target='DataBox' title=''zz''>FAST-DATA</a>
");
            client.print("<iframe src='http://192.168.1.102:84/data' width='350' height='250' name='DataBox'>");
            client.print("</iframe>
</HTML>");
          }
          delay(1);
          //stopping client
          client.stop();
          //clearing string for next read
          readString="";
        }
      }
    }
  }
}

That is cool thank you, I shall see if I can not nut it out :slight_smile:

The below site has info on inputting values into web pages that might be of use.

http://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/AJAX-read-switches-analog/

Awesome, thanks again for the help.

I will see if I can cobble it together. I am starting to think I should be using the sd card on the Ethernet shield to serve from. Eventually I am wanting to drop the values to a database and read from there. It is kind of an easy first project before I get into something a little more advanced.

I will also run an SSR from it for the fermentation chamber to keep the temp stable..

I will update as I find more. Or, if anyone has anything to add I am all ears (eyes, in this particular case).

Can't you see that printTemperature() only sends data to the serial port? Expecting that data to magically make its way to the client is unrealistic.

Frankly, the example that you started from is close to the worst example anywhere on the internet. The function printTemperature() is stupidly named. It would have been FAR better if it had been named properly - readPrintAndDiscardTemperature().

At least that way, no one would be trying to use it the way you are.

No, no I couldn't see that and your summary at the end there pretty much sums it up.

Thanks for the tip, hopefully everyone will chime in telling me how not to do things and then the only way left will be a workable one.

Excuse my ignorance, I am new at this and learning. Perhaps you could use your exceeding mastery of the code to help me out?

Excuse my ignorance, I am new at this and learning. Perhaps you could use your exceeding mastery of the code to help me out?

Given that the function reads and sends data to the serial port, what would you name it?

Now, given that you want a similar version of the function to send to the client instead, what would you need to change, in the name, in the inputs and in the outputs?

Suppose that you wanted to send the data to any kind of stream, instead. What would you make the function do? What would it be called?

What I would do is make the function name readTemperature(), and I would make it return a value. I would then make the sketch use the returned value sending it where it wanted.

Once we know what you want to do, its easy to change the code to do it.

That, thank you, was very helpful.

I am just reading an article that suggests I start the code from scratch rather than reuse stuff off the net.

This seems to match what you are saying :-)

I shall keep you updated with my journey.

I am just reading an article that suggests I start the code from scratch rather than reuse stuff off the net.

There is nothing wrong with using stuff from the net, if it works for you. If it doesn't, its still OK as long as you understand why it doesn't, AND you can fix it.

The advantage of writing the code yourself is that you WILL understand it.

Use meaningful names for variables and functions, unlike the author of the code you started with.

I mean suppose that, knowing it makes no difference to the compiler, digitalRead() was called f6783(). You'd have a hell of a time reading code like that. Suppose that the function to set the mode of a pin was called printTemperature(). That name does NOT reflect what the functio actually does, so it is much harder to figure what to change to make it do something different. Don't let yourself fall into that quagmire.

OK, so I have hit my first snag.....

Here is the skinny.

I have five DS18B20 Temp sensors running on a 1wire that is not using parasitic power. I am supposing it is a star topology and am able to get the serial output to give me the temps I am asking for (12 bit), which is a bit of overkill but I will need this function in a further project so want to nail it down now.

I know the addresses of the sensors, and, have assigned them in the setup.

I am thinking along the lines of creating a subroutine called GetTemp which would give me the ability to use the temp value anywhere.

The thing I can not get my head around is how I find the particular address of the known sensor?

Could anyone point me in the direction of what I should most probably be trying to do here?

I am thinking along the lines of creating a subroutine called GetTemp which would give me the ability to use the temp value anywhere.

Excellent idea. The question, of course, is what the inputs and outputs will be.

The thing I can not get my head around is how I find the particular address of the known sensor?

You assigned them:

DeviceAddress RumFerment = { 0x28, 0x2E, 0x27, 0xE1, 0x06, 0x00, 0x00, 0x05 };
DeviceAddress UJFerment = { 0x28, 0x37, 0x43, 0xE1, 0x06, 0x00, 0x00, 0xC6 };
DeviceAddress NeutralFerment = { 0x28, 0x2F, 0x42, 0xE0, 0x06, 0x00, 0x00, 0x7E };
DeviceAddress FermenterTop = { 0x28, 0x6E, 0x8E, 0xDF, 0x06, 0x00, 0x00, 0xED };
DeviceAddress FermenterBottom = { 0x28, 0x6B, 0xE0, 0xE0, 0x06, 0x00, 0x00, 0x67 };

My getTemp function would look like:

float printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  return tempC;
}