Skip to content

Sending temperature data from the arduino to a server

2010 Juni 24

Hey, folks.

Today i finished somewhat of a 0.8 version of my attempt to read temperature data from several DS18B20 temperature sensors with the arduino and to send them to my “kitchenserver”. Why kitchenserver? Because its running all night long and therefore had to go to kitchen.

What is my goal?

To read temperature data and store it in a database for further processing.

My father always says: “Die Sprache des Ingenieurs ist die Zeichnung” what means as much as ” the language of an engineer is drawings” so i made a little “graphic”:

DS18B20—–>Patchpanel—–>(Arduino—>Ethernetshield)—->Network—–>(Server(Apache—->PHP—>MySQL)

Edit: I found out that my first code is only working for one sensor, due to some Arduino->PHP inconsistencies (Arduino called the script for every temperature, but script wants to write all data in one call) So I rewrote the code to send all temperatures in one call. I have now 5 sensors up and running and storing data to my database. I would try the setup with more sensors but i have only 5 of them so i first have to buy some. If you want to build a system like this, use the newer code, the old code is only for educational purposes now ;)

In the last two months i figured out how to set up a linux server with ubuntu and get a “LAMP” system running (Linux, Apache, mySQL, PHP) and to install phpmyadmin and learn how to set up and administer a database. Its really easy with ubuntu server and some basic Linux skills. I tinkered around a while with the Arduino and some sensors and its not as easy as i thought, but what did i expect? It´s microcontrollers!

So here´s what i used:

DS18B20

ethernet cable

12-port Patchpanel

Arduino Duemilanove

Arduino Ethernet Shield

acer travelmate 290 with LAMP

First the hardware. the easy part:

I use a patchpanel like Dirk Melchers did (thanks for sharing) to have a secure and fast way to connect sensors to the bus and  to be able to expand the number of sensors quickly.

To have the possibility to add up to 12 sensors i laid the three the wires for the one-wire bus through all the wiring fields:

To use the system with a patchpanel i have to solder the three pins from the sensors to three stranded wires of a cut up ethernet cable. I chose the first three wires of the connector.

Now i can connect the wires from the patchpanel to the Arduino. Here are the wires:

To get the DS18B20 to work one needs a so called “pull-up” resistor. I made a simple “shield” to  add the pull-up resistor and to make all neccesary connections. Here you can see how the 18B20 has to be connected (click the image to make it bigger ;)

Here´s my  “shield”  layout, i used a 10kOhm potentiometer set to 4,7kOhm as pull-up because i found it right on my desk.

soldered and in action:

Line 1 goes to VCC on the Arduino, line 2 is GND and line 3 is the BUS (on pin 7).

This is all for assembly of the Arduino, and here comes the Code:
( There are many comments to make it easier for beginners to read the code)

Attention: Old Code!:


#include <Ethernet.h>           //library for ethernet functions
#include <Client.h>             //library for client functions
#include <DallasTemperature.h>  //library for temperature sensors
//#include <stdint.h>
#include <OneWire.h>            //library for the onewire bus

#define ONE_WIRE_BUS     7      //the onewire bus is connected to pin 7 on arduino
#define TEMPERATURE_PRECISION  10 //resolution of the sensors is set to 10bit

// Ethernet settings
uint8_t hwaddr[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xBE}; // mac-adress of arduino
uint8_t ipaddr[4] = {192, 168, 0, 17};                    // IP-adress of arduino
uint8_t gwaddr[4] = {192, 168, 0, 1};                     // IP-adress of gateway ( for later DNS implementation)
uint8_t subnet[4] = {255, 255, 255, 0};                   // subnetmask           ( for later DNS implementation)
uint8_t serverip[4] = {192, 168, 0, 4};                   // IP-adress of server arduino sends data to

uint8_t serverport = 80;                                  // the port the arduino talks to

Client client(serverip, serverport);                      // make a new instance from type "Client" named "client", giving it
                                                          // serverip and serverport

OneWire oneWire(ONE_WIRE_BUS);                            // setup a oneWire instance to communicate with any OneWire devices
                                                          // (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);                      // Pass our oneWire reference to Dallas Temperature

int numSensors;                                           // variable to store the number of sensors

bool connected = false;                                   // yes-no variable (boolean) to store if the arduino is connected to the server
int i = 0;                                                // variable to count the sendings to the server

void setup(void)                                          // setup-function runs at the startup of the arduino
{

Serial.begin(9600);                                       // start the serial port
Serial.println("I2C-to-Ethernet Bridge.");
Serial.println("Initializing Ethernet.");

Ethernet. begin(hwaddr, ipaddr);                          // start up ethernet
sensors.begin();                                          // start up the library

Serial.println("Enumerating and scanning for I2C sensors.");

numSensors = sensors.getDeviceCount();                    // store the number of sensors to the variable numSensors,
// "sensors.getDeviceCount" is a function in the library

if(numSensors > 0)                                        // if there is at least one sensor:
{
Serial.print("Enumerated ");                              //print the number of sensors to serial port
Serial.print(numSensors);
Serial.println( " sensors.");

}
else                                                      //if there is no sensor:
{
Serial.println("No sensors enumerated.");                 // tell the serial port
}

}

void loop(void)                                           // loop function runs over and over again
{
if(!connected)   {                                        // if "not" connected print: not connected ;)
Serial.println("Not connected");

if (client.connect()){                                    // if connected, set variable connected to "true" and
connected = true;
sensors.requestTemperatures();                            // send the request for temperature to sensors (all sensors)

for(i=0; i<numSensors; i++)                               // as long as "i" ( chosen number, starts at 0) is smaller than
                                                          //"numSensors" (number of sensors) do the "for" cycle
{
int temp = sensors.getTempCByIndex(i);                    // take temperature reading from sensor "i" and store it to the variable "temp"
Serial.print("Temp is ");                                 // just to see if the reading was succesful in serial console
Serial.println(temp);
Serial.println("Sending to Server: ");                    // all the "Serial.print" is for debugging and to show other people what arduino does
client.print("GET /writetemplocalserv.php?t");            // send this to apache on server to call the script "writetemplocalserv.php"
Serial.print("GET /writetemplocalserv.php?t");            //
client.print(i);                                          // give it the temp on sensor "i" to the script
Serial.print(i);
client.print("=");
Serial.print("=");
client.print(temp);
Serial.print(temp);
client.println(" HTTP/1.1");                  //
Serial.println(" HTTP/1.1");                  //
client.println("Host: www.jfkreuter.com");    //
Serial.println("Host: www.jfkreuter.com");    //
client.println("User-Agent: Arduino");        // ethernet related stuff
Serial.println("User-Agent: Arduino");        //
client.println("Accept: text/html");          //
Serial.println("Accept: text/html");          //
//client.println("Connection: close");        //
//Serial.println("Connection: close");        //
client.println();                             //
Serial.println();
delay(599500);                                            // send the temperature every 10 minutes 599500 + 500 milliseconds (down below)
}
}
else{
Serial.println("Cannot connect to Server");               //  else block if the server connection fails (debugging)

}
}
else {

delay(500);                                               //
while (client.connected() && client.available()) {        // when connected and availabe:
char c = client.read();                                   // read the answer of the server and
Serial.print(c);                                          // print it to serial port
}                                                         //
Serial.println();                                         //
client.stop();                                            //  stop the connection and set
connected = false;                                        //  "connected" to false

}
}

Here is the new code (for multiple Sensors):


#include <Ethernet.h>           //library for ethernet functions 
#include <Client.h>             //library for client functions
#include <DallasTemperature.h>  //library for temperature sensors 
//#include <stdint.h>          
#include <OneWire.h>            //library for the onewire bus
 
#define ONE_WIRE_BUS     7      //the onewire bus is connected to pin 7 on arduino
#define TEMPERATURE_PRECISION  10 //resolution of the sensors is set to 10bit
 
// Ethernet settings
uint8_t hwaddr[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xBE}; // mac-adress of arduino
uint8_t ipaddr[4] = {192, 168, 0, 17};                    // IP-adress of arduino
uint8_t gwaddr[4] = {192, 168, 0, 1};                     // IP-adress of gateway ( for later DNS implementation)
uint8_t subnet[4] = {255, 255, 255, 0};                   // subnetmask           ( for later DNS implementation)
uint8_t serverip[4] = {192, 168, 0, 4};                   // IP-adress of server arduino sends data to
 
uint8_t serverport = 80;                                  // the port the arduino talks to
 
 
Client client(serverip, serverport);                      // make a new instance from type "Client" named "client", giving it 
 // serverip and serverport
 
OneWire oneWire(ONE_WIRE_BUS);                            // setup a oneWire instance to communicate with any OneWire devices 
 // (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);                      // Pass our oneWire reference to Dallas Temperature
 
 // variable to store the number of sensors 

bool connected = false;                                   // yes-no variable (boolean) to store if the arduino is connected to the server
int i = 0;                                                // variable to count the sendings to the server 

 
 
void setup(void)                                          // setup-function runs at the startup of the arduino
{
 
 
 Serial.begin(9600);                               // start the serial port       
 Serial.println("I2C-to-Ethernet Bridge.");
 Serial.println("Initializing Ethernet.");
 
 Ethernet. begin(hwaddr, ipaddr);                  // start up ethernet   
 sensors.begin();                                  // start up the library    
 int numSensors = sensors.getDeviceCount();               // store the number of sensors to the variable numSensors, 
 int temparray[numSensors];            // array with "numSensors" storage places for the temperature of each sensor
 // "sensors.getDeviceCount" is a function in the library  
 Serial.println("Enumerating and scanning for I2C sensors.");
 
 
 
 if(numSensors > 0)                              // if there is at least one sensor:
 {
 Serial.print("Enumerated ");            //print the number of sensors to serial port 
 Serial.print(numSensors);
 Serial.println( " sensors.");
 
 }
 else                                              //if there is no sensor:        
 {
 Serial.println("No sensors enumerated."); // tell the serial port
 }
 
}      
 
void loop(void)                                        // loop function runs over and over again    
 {
 int numSensors = sensors.getDeviceCount();
 int temparray[numSensors];            // array with "numSensors" storage places for the temperature of each sensor
 // "sensors.getDeviceCount" is a function in the library  
 
 if(!connected)   {                                    // if "not" connected print: not connected ;)
 Serial.println("Not connected");   
 
 if (client.connect()){                             // if connected, set variable connected to "true" and    
 connected = true;                              
 sensors.requestTemperatures();                  // send the request for temperature to sensors (all sensors)       
 delay(100);
 for(i=0; i<numSensors; i++)                    // as long as "i" ( chosen number, starts at 0) is smaller than 
 //"numSensors" (number of sensors) do the "for" cycle
 {
 int temp = sensors.getTempCByIndex(i); // take temperature reading from sensor "i" and store it to the variable "temp"
 temparray[i] = temp;                   // store the temperature from sensor i to storage place i in the array 
 
 }
 
 
 client.print("GET /writetemplocalserv.php?");
 Serial.print("GET /writetemplocalserv.php?");     
 for (i=0; i<numSensors; i++)
 {
 client.print("t");
 Serial.print("t");
 client.print(i);
 Serial.print(i);
 client.print("=");
 Serial.print("=");
 client.print(temparray[i]);
 Serial.print(temparray[i]);
 if (i < numSensors-1)
 {
 client.print("&&");
 Serial.print("&&");
 }
 else
 {
 }    
 
 }  
 
 client.println(" HTTP/1.1");
 Serial.println(" HTTP/1.1");
 client.println("Host: www.jfkreuter.com");
 Serial.println("Host: www.jfkreuter.com");
 client.println("User-Agent: Arduino");
 Serial.println("User-Agent: Arduino");
 client.println("Accept: text/html");
 Serial.println("Accept: text/html");
 client.println("Connection: close");
 Serial.println("Connection: close");
 client.println();
 Serial.println();
 
 }
 else{
 Serial.println("Cannot connect to Server");         //  else block if the server connection fails (debugging)
 
 }
 }
 else {
 
 delay(500);                                                //
 while (client.connected() && client.available()) {          // when connected and availabe: 
 char c = client.read();                                    // read the answer of the server and
 Serial.print(c);                                            // print it to serial port     
 }                                                           //   
 Serial.println();                                            //      
 client.stop();                                              //  stop the connection and set
 connected = false;                                           //  "connected" to false
 
 }
delay(599400);

}

Then one has to write a PHP-Script which will receive the data sent from the arduino and write it to my database:

Old PHP-Script:

<?php
header('Content-type: text/plain');
echo date("d.m.Y-H:i:s") . " Temperatur= " . $_GET['t0']; 

$link = mysql_connect("SQL-host", "user", "password") or die("Keine Verbindung möglich: " . mysql_error()); //connect to the MySQL-Server 
mysql_select_db("tempdb") or die("Auswahl der Datenbank fehlgeschlagen"); // select the database
$query = "INSERT INTO table1(`temp1`) values(" . $_GET['t0'] . ")";          // insert the value from GET request of arduino into column "temp1" in table "table1"
$result = mysql_query($query) or die("Anfrage fehlgeschlagen: " . mysql_error()); //give the browser feedback (if it worked: send the SQL-Query, if it didn´t send "Anfrage fehlgeschlagen" plus the SQL error  

mysql_close($link); //close link to MySQL-Server 
?>

New PHP-Script:



<?php
header('Content-type: text/plain');
echo date("d.m.Y-H:i:s") . " Temperatur 1 = " . $_GET['t0'];
echo date("d.m.Y-H:i:s") . " Temperatur 2 = " . $_GET['t1'];
echo date("d.m.Y-H:i:s") . " Temperatur 3 = " . $_GET['t2'];
echo date("d.m.Y-H:i:s") . " Temperatur 4 = " . $_GET['t3'];
echo date("d.m.Y-H:i:s") . " Temperatur 5 = " . $_GET['t4'];

$link = mysql_connect("localhost", "username", "password") or die("Keine Verbindung möglich: " . mysql_error());
mysql_select_db("tempdb") or die("Auswahl der Datenbank fehlgeschlagen");
$query = "INSERT INTO table1(temp1, temp2, temp3, temp4, temp5) VALUES ('" . $_GET['t0'] . "', '" . $_GET['t1'] . "','" . $_G
ET['t2'] . "','" . $_GET['t3'] . "', '" . $_GET['t4'] . "')";$result = mysql_query($query) or die("Anfrage fehlgeschlagen: " . mysql_error());

mysql_close($link);
?>

I´m learning php at the moment, so the script is very insecure and should not be out in the wild. I have no restrictions what (t0) should be, and where it comes from, so everybody can write data to the database or maybe execute SQL commands( i dont know, i´m learning ;)

This ist the sytem up and running:

And this is what it looks like looked like in the phpmyadmin:

The 21 degrees C are my ambience temperature, and the 35 degrees is the air coming out of my sweet little laptop.

There is a column named “temp2″ for  a second sensor. So, if i want i could attach a second one and write the data to the database. For more than 2 sensors i have to alter the table but thats not a big deal.

This is the new (altered) database in the phpmyadmin:

Next to come:

- Read multiple sensors (up to twelve would be perfect) done for up to 5 Sensors

- Create a website  w/ script to read and visualise the data without having to log in into phpmyadmin

-Put everything together in a strong housing for use in the wild (e.g. not my desk)

Feel free to leave some constructive critics and questions and have fun building it yourself!

8 Responses leave one →
  1. transfinite permalink
    Juni 24, 2010

    Jan,

    Nice job documenting your project. For plotting data for a website you may want to look at digitemp.com
    for some ideas and code.

    -transfinite

  2. Nicola permalink
    Juni 25, 2010

    Hi

    Nice project. I’ve done some similar with graph. If you want, we can collaborate to improve this project. contact Me via Email.

    Nicola

  3. Juni 29, 2010

    Nice stuff. Check out my project, I’m doing something similar – I use jpgraph for the data visualisation.

  4. Daniel permalink
    Juli 2, 2010

    jpgraph is pretty good. I have used it in the past for a few projects.

    I think it was mentioned on the arduino forum, but use the $_SERVER global variable to restrict it to certain IP addys. Also, PHP has some builtin validation to strip tags, etc. It is almost imperative to use validation if you are going to use the mail() function in php.

    Also, for the database, you may want to make it relational. I would create a table just for the sensor information. I would have at least two fields: id, name. (this way, for your web portion instead of wondering where sensor 3 is, it may say room x) Then, for storing the temp, you would just need 4 column: id, sensor id (this is the id from the first table), date/time, and temp (make this a decimal format 5,2 so you get accuracy to two decimal points). This also makes it very scalable. You can have 1 sensor, or however many mysql can handle.

    Also, you may look into using mysqli instead of mysql scripts. You can then use OOP instead of procedural programming.

    BTW, love the ASUS in the background.

    Once I get my arduino board, I will have to come back and look at your code. (hopefully it gets here this week) If you need any help with PHP or MySQL, let me know.

  5. Februar 23, 2012

    … does this program run well on Arduino Ethernet /not shield/?? without any changes?

    BM

  6. nobbi permalink
    März 1, 2012

    Hi Jan,
    im planning a temperature monitoring of my heating-System with about 16 Temp. gauges. Attached like yours with a patchpanel. Length of the single gauges will differ between 5 and 15 Meters each. Do you see any problems in realization?

    Greetz,
    Nobbi

  7. Nobbi permalink
    März 2, 2012

    Hey,
    i want to build a tempsensor similar to yours, with 15 Gauges between 5 and 15 Meters Length each. Do you see any problems in getting data from these long lines?

    Thx in advance,
    Nobbi

  8. Juni 4, 2012

    Hi Jan,

    Just found this post – amazing work!

    I’m wondering if you can help me. I’m trying to feed sensor data (from 8 photoreflective sensors) into an Arduino UNO via one or more network cables (Cat6, around 10 ft long). I have one such cable currently, plugged into an RJ45 connector + breadboard-friendly breakout board at both ends. Whereas with jumper wire the sensor signal is clean, I get a very different signal (noise?) when using the network cable.

    Any tips on how to connect the sensor outputs to the cable would be greatly appreciated. Congrats again on your work.

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS