Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
|
The greenhouse environmental conditions change continuously, for this reason we need an efficient monitoring.
There are a lot of benefits of using an automatic system, for example less work or most important the users can check their own investments from their house by PC or smartphone.
Another important advantage is the possibility to store data into a DataBase. This can make the difference between gaining or losing money.
Furthermore, thanks to a real-time system control we can intervene immediately, preventing problems for cultivation.
The automatic monitoring system in greenhouses is composed of sensors that read environment data and actuators, called “Slaves”. They communicate via Wireless with central device, called “Master”. The latter sends possible changes to slaves (like change of thresholds) and data via WiFi to webserver as well.
1. How does it Work?We can split this project in three different parts:
- Master
- Slave
- Web Server
We’ve used an Arduino/Genuino MKR1000 for the Master, an Arduino/Genuino Uno for the Slave.
The Master communicates with a Web Server via WiFi (WINC1500 integrated), the Slave acquires temperature and humidity with DHT22 sensor, and then it sends these data to the Master via WiFi (WiFi shield WINC1500).
2. Master
The Master is on “Access Point mode” and it waits for the Slave connection to receive the temperature and humidity that are elaborated and sent to the Web Server.
The Master checks if there are data available, in this case it creates an UDP packet formed by new thresholds and CRC. Infacts, it calculates the CRC that will be used by the Slave to validate the setting received.
After the Master gets out of “Access Point mode”, it connects to the WiFi, in order to send data to WebServer where they will be put in a graph.
The Slave acquires temperature and humidity by DHT22 sensor and after 5 minutes it sends data to the Master. It also creates an UDP packet, it connects to the Master and then sends the data.
Later it waits if there are some data available, such as new thresholds. In this case, the Slave receives new settings and calculates the CRC using the Dallas-Maxim formulas.
Subsequently the CRC calculated is compared with the CRC received from the Master. If the two CRC are the same, the Slave saves the new setting in the EEPROM.
The Web Server saves all the data that later can be stored in a history.
In order to do that, we have used a PHP script that connects to database and shows data in two different ways
- in a graph, using another PHP script
- in an Android app, in JSON format using another PHP script
The App allows us to consult the data into a Data Base.
In the first screen, we can select the timing range to show and with the button "GRAPHIC", it contacts the web service and gets the data.
The App shows data into graphic.
<?php // content="text/plain; charset=utf-8"
define('__ROOT__', dirname(dirname(__FILE__)));
require_once ('../jpgraph.php');
require_once ('../jpgraph_line.php');
require_once ('../jpgraph_error.php');
$parameter1 = array();
$parameter2 = array();
$time_axis = array();
$i = 0;
$con=mysqli_connect("localhost","user","pass","my_db");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT your_parameter FROM your_raw");
while($row = mysqli_fetch_array($result)) {
$parameter1[$i] = $row["parameter1"];
$parameter2[$i] = $row["parameter2"];
$time_axis[$i] = $row["date"];
$i++;
}
mysqli_close($con);
// Setup the graph
$graph = new Graph(300,250);
$graph->SetScale("textlin");
$theme_class=new UniversalTheme;
$graph->SetTheme($theme_class);
$graph->img->SetAntiAliasing(false);
$graph->title->Set('Title');
$graph->SetBox(false);
$graph->img->SetAntiAliasing();
$graph->yaxis->HideZeroLabel();
$graph->yaxis->HideLine(false);
$graph->yaxis->HideTicks(false,false);
$graph->xgrid->Show();
$graph->xgrid->SetLineStyle("solid");
$graph->xaxis->SetTickLabels($time_axis);
$graph->xgrid->SetColor('#E3E3E3');
$graph->xaxis->SetLabelAngle(90);
$graph->legend->SetPos(0.5,0.08,'center','top');
// Create the first line
$p1 = new LinePlot($parameter1);
$graph->Add($p1);
$p1->SetColor("#6495ED");
$p1->SetLegend('your_parameter1');
$graph->yscale->SetGrace(0);
// Create the second line
$p2 = new LinePlot($parameter2);
$graph->Add($p2);
$p2->SetColor("#B22222");
$p2->SetLegend('your_parameter2');
$graph->yscale->SetGrace(0);
$graph->legend->SetFrameWeight(1);
// Output line
$graph->Stroke();
?>
<?php
$servername = "localhost";
$username = "user";
$password = "pass";
$dbname = "my_db";
$id = $_GET["name"];
$temp = $_GET["parameter1"];
$umid = $_GET["parameter2"];
echo "name ". $_GET['name']. "<br />";
echo "parameter1 ". $_GET['parameter1']. "<br />";
echo "parameter2 ". $_GET['parameter2']. "<br />";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "INSERT INTO greenhouse (name, parameter1, parameter2)
VALUES ('".$name."', '".$parameter1."', '".$parameter2."')";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
?>
CREATE TABLE IF NOT EXISTS `greenhouse` (
`id` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`temp` float NOT NULL,
`umid` float NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*Automation greenhouse project*/
/*Autors: Antonio La Mura, Umberto Festa*/
/*Date: 03/03/2016*/
/*Our idea is to allow users, who buy fruits and vegetables grown in greenhouses, to know exactly all the plantation steps that products have had,
such as the use of chemical fertilizers and other similar products.
A QR code will be put on the sold products that will be read by a specific smartphone app.
It provides information about environment conditions where products have been grown and the chemical products used.
The automatic monitoring system in greenhouses is composed of sensors that read environment data and actuators, called Slaves.
They communicate via Wireless with central device, called Master. The latter sends possible changes to slaves
(like change of thresholds) and data via WiFi to webserver as well.
When the product is ready to be sold, QR code generation is requested to the webservice and it will be put on the package.
The last part of the system is the mobile app that is responsible for the QR codes scanning and shows the relative informations to the user.*/
/*Master*/
/*DEVO AGGIUNGERE SOLO LA PARTE CHE MI SERVE PER RICEVERE LE NUOVE SOGLIE CHE VENGONO INVIATE DALL'APP*/
/*Libraries used*/
#include <SPI.h>
#include <WiFi101.h>
#include <RTCZero.h>
#include <WiFiUDP.h>
#include <RTCZero.h>
/*Variables for connection*/
char ssid[] = "SSID"; /*Your network SSID (name)*/
char pass[] = "pass"; /*Uour network password (use for WPA, or use as key for WEP)*/
int keyIndex = 0; /* Your network key Index number (needed only for WEP)*/
char ssid_ap[] = "Arduino"; /*Created AP name*/
char pass_ap[] = ""; /*(Not supported yet)*/
int status = WL_IDLE_STATUS;
unsigned int localPort = 2390; /*Local port to listen on*/
char server[] = "www.cormaz.altervista.org"; /*Name address for Google (using DNS)*/
WiFiServer server_ap(80);
WiFiClient client_ap;
WiFiUDP Udp;
RTCZero rtc;
WiFiClient client;
char packetBuffer[255]; /*Buffer to hold incoming packet*/
char ReplyBuffer[255]; /*A string to send back*/
/*Variables for new thresholds*/
float humax = 0;
float humin = 0;
float tumax = 0;
float tumin = 0;
/*Works like Access Point (flag = false), connects to WebServer (flag = true)*/
boolean flag = false;
boolean threeshold_available = false;
void setup() {
/*Initialize serial and wait for port to open:*/
Serial.begin(9600);
while (!Serial) {
; /*Wait for serial port to connect. Needed for native USB port only*/
}
Serial.println();
}
void loop() {
int packetSize;
double temp;
double hum;
int id;
byte crc;
String strURL;
//Check for the presence of the shield:
/**************************************************************************************/
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
/*Don't continue:*/
while (true);
}
/**************************************************************************************/
//Attempt to connect to WiFi network:
/**************************************************************************************/
while (status != WL_CONNECTED) {
Serial.print("Creating Network named: ");
Serial.println(ssid_ap);
/*Connect to WPA/WPA2 network. Change this line if using open or WEP network:*/
status = WiFi.beginAP(ssid_ap);
/*Wait 10 seconds for connection:*/
delay(10000);
server_ap.begin();
}
Serial.println("Connected to wifi");
/**************************************************************************************/
//Start UDP communication
/**************************************************************************************/
Udp.begin(localPort);
printWifiStatus();
client_ap = server_ap.available();
if (client_ap) { /*If you get a client*/
/*I'm waitinf for some information*/
Serial.println("new client"); /*Print a message out the serial port*/
/*If there's data available, read a packet*/
packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remoteIp = Udp.remoteIP();
Serial.print(remoteIp);
Serial.print(", port ");
Serial.println(Udp.remotePort());
/*Read the packet into packetBuffer*/
int len = Udp.read(packetBuffer, 255);
if (len > 0) packetBuffer[len] = 0;
Serial.println("Contents:");
Serial.println(packetBuffer);
char* command = strtok((char *)packetBuffer, ";");
int count = 0;
while (command != 0) {
/*Divide the information*/
switch (count) {
case 0:
id = atoi(command);
break;
case 1:
temp = atof(command) / 10;
break;
case 2:
hum = atof(command) / 10;
break;
}
command = strtok(0, ";");
count++;
}
Serial.print("Package received from ");
Serial.print(id);
Serial.print(" T: ");
Serial.print(temp, 1);
Serial.print(" H: ");
Serial.println(hum, 1);
/**************************************************************************************/
delay(20);
/*Calculate the CRC-8, so create byte array*/
/********************************************************************************/
byte bhmax = (byte)humax;
byte bhmin = (byte)humin;
byte btmax = (byte)tumax;
byte btmin = (byte)tumin;
byte crc32_str[4] = {
bhmax, bhmin, btmax, btmin
};
crc = CRC8(crc32_str);
Serial.println("CRC: ");
Serial.println(crc);
/********************************************************************************/
if (threeshold_available == true) {
snprintf(ReplyBuffer, sizeof(ReplyBuffer), "%d;%d;%d;%d;%d;%d", id, (int)humax, (int)humin, (int)tumax, (int)tumin, (int)crc);
/*Send a reply, to the IP address and port that sent us the packet we received*/
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
} /*Print it out the serial monitor*/
/*Close the connection:*/
client_ap.stop();
Serial.println("client disconnected");
flag = true;
}/*Fine AP*/
/********************************************************************************/
/*Connect to the server and send data to DataBase*/
/********************************************************************************/
if (flag == true) {
/*Attempt to connect to Wifi network:*/
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
/*Connect to WPA/WPA2 network. Change this line if using open or WEP network:*/
status = WiFi.begin(ssid, pass);
/*Wait 10 seconds for connection:*/
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
strURL = "GET /YourAddress.php?id=";
strURL += id;
strURL += "¶meter1=";
strURL += temp;
strURL += "¶meter2=";
strURL += hum;
strURL += " HTTP/1.1";
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected to server");
// Make a HTTP request:
client.println(strURL);
client.println("Host: www.cormaz.altervista.org");
client.println("Connection: close");
client.println();
client.stop();
Serial.println("Ok!");
}
/*If the server's disconnected, stop the client:*/
if (!client.connected()) {
Serial.println();
Serial.println("Disconnecting from server.");
client.stop();
/*Do nothing forevermore:*/
while (true);
}
flag = false;
}
/********************************************************************************/
}
/*Calculate algorithm CRC-8 - based on Dallas/Maxim formules*/
byte CRC8(const byte * data) {
byte crc = 0x00;
while (*data) {
byte extract = *data++;
for (byte tempI = 8; tempI; tempI--) {
byte sum = (crc ^ extract) & 0x01;
crc >>= 1;
if (sum) {
crc ^= 0x8C;
}
extract >>= 1;
}
}
return crc;
}
void printWifiStatus() {
/*Print the SSID of the network you're attached to:*/
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
/*Print your WiFi shield's IP address:*/
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
/*Print the received signal strength:*/
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
/*Automation greenhouse project*/
/*Autors: Antonio La Mura, Umberto Festa*/
/*Date: 21/03/2016*/
/*Our idea is to allow users, who buy fruits and vegetables grown in greenhouses, to know exactly all the plantation steps that products have had,
such as the use of chemical fertilizers and other similar products.
A QR code will be put on the sold products that will be read by a specific smartphone app.
It provides information about environment conditions where products have been grown and the chemical products used.
The automatic monitoring system in greenhouses is composed of sensors that read environment data and actuators, called Slaves.
They communicate via Wireless with central device, called Master. The latter sends possible changes to slaves
(like change of thresholds) and data via WiFi to webserver as well.
When the product is ready to be sold, QR code generation is requested to the webservice and it will be put on the package.
The last part of the system is the mobile app that is responsible for the QR codes scanning and shows the relative informations to the user.*/
/*Slave*/
/*Libraries used*/
#include <SPI.h>
#include <WiFi101.h>
#include <WiFiUdp.h>
#include <EEPROM.h>
#include <DHT22.h>
//Define all PIN
#define HUMIDIFIER A4
#define HEATER A5
#define DHT22_PIN 4
//Define motor
#define IS_1 0
#define IS_2 1
#define IN_1 3
#define IN_2 11
#define INH_1 12
#define INH_2 13
#define TCONST 100 //Delay Time between Steps
//Variable to reset millis()
extern unsigned long timer0_millis;
int status = WL_IDLE_STATUS;
char ssid[] = "Arduino"; // your network SSID (name)
char pass[] = ""; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
unsigned int localPort = 2390; // local port to listen on
char packetBuffer[255]; //buffer to hold incoming packet
WiFiUDP Udp;
//Define DHT22
DHT22 myDHT22(DHT22_PIN);
//Variable to send
float hmin = 0;
float hmax = 0;
float tmin = 0;
float tmax = 0;
int duty_motor = 0;
float humidity;
float temperature;
//Variable to send every 10 seconds
unsigned long interval = 600000;
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
//Initialize PIN (INPUT - OUTPUT)
pinMode(HEATER, OUTPUT);
digitalWrite(HEATER, LOW);
pinMode(HUMIDIFIER, OUTPUT);
digitalWrite(HUMIDIFIER, LOW);
//Set the PIN for the fan
pinMode(IN_1, OUTPUT);
pinMode(IN_2, OUTPUT);
pinMode(INH_1, OUTPUT);
pinMode(INH_2, OUTPUT);
//Reset
reset_ports();
digitalWrite(INH_1, 1);
digitalWrite(INH_2, 1);
Serial.println("Beginning ... ");
delay(2000);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
unsigned long time = millis();
unsigned long currentMillis = millis();
DHT22_ERROR_t errorCode;
int i = 0;
char name[] = "clie1";
humidity = myDHT22.getHumidity() * 10;
temperature = myDHT22.getTemperatureC() * 10;
char toSend[32];
errorCode = myDHT22.readData();
byte crc;
int crc_ric;
//Check sensor humidity and temperature DHT22 errors
/********************************************************************************/
switch (errorCode)
{
case DHT_ERROR_NONE:
char buf[128];
sprintf(buf, "Integer-only reading: Temperature %hi.%01hi C, Humidity %i.%01i %% RH",
myDHT22.getTemperatureCInt() / 10, abs(myDHT22.getTemperatureCInt() % 10),
myDHT22.getHumidityInt() / 10, myDHT22.getHumidityInt() % 10);
break;
case DHT_ERROR_CHECKSUM:
break;
case DHT_BUS_HUNG:
break;
case DHT_ERROR_NOT_PRESENT:
break;
case DHT_ERROR_ACK_TOO_LONG:
break;
case DHT_ERROR_SYNC_TIMEOUT:
break;
case DHT_ERROR_DATA_TIMEOUT:
break;
case DHT_ERROR_TOOQUICK:
break;
}
/********************************************************************************/
//Print the values, when it changes
/********************************************************************************/
if (humidity != myDHT22.getHumidity() * 10 || temperature != myDHT22.getTemperatureC() * 10) {
Serial.print("T: ");
Serial.print(myDHT22.getTemperatureC(), 1);
Serial.print("C");
Serial.print(" H: ");
Serial.print(myDHT22.getHumidity(), 1);
Serial.println("%");
}
/********************************************************************************/
//Send the parameters every 10 minutes
/********************************************************************************/
if (millis() > interval) {
//Connection to AP
/********************************************************************************/
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
/********************************************************************************/
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
Udp.begin(localPort);
snprintf(toSend, sizeof(toSend), "%s;%d;%d", name, (int)humidity, (int)temperature);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(toSend);
Udp.endPacket();
Serial.println("Finished sending");
resetMillis();
while (millis() < 10000) {
packetSize = Udp.parsePacket();
if (packetSize) {
/*Read the packet into packetBuffer*/
int len = Udp.read(packetBuffer, 255);
if (len > 0) packetBuffer[len] = 0;
Serial.println("Contents:");
Serial.println(packetBuffer);
char* command = strtok((char *)packetBuffer, ";");
int count = 0;
while (command != 0) {
/*Divide the information*/
switch (count) {
case 0:
snprintf(name, sizeof(name), "%s", command);
break;
case 1:
hmax = atof(command) / 10; //atof(char* ) mi converte un tipo char* in double
break;
case 2:
hmin = atof(command) / 10;
break;
case 3:
tmax = atof(command) / 10;
break;
case 4:
tmin = atof(command) / 10;
break;
case 5:
crc_ric = atoi(command);
break;
}
command = strtok(0, ";");
count++;
}
Serial.print("Answer: ");
Serial.print(name);
Serial.print(";");
Serial.print(hmax, 1);
Serial.print(";");
Serial.print(hmin, 1);
Serial.print(";");
Serial.print(tmax, 1);
Serial.print(";");
Serial.println(tmin, 1);
Serial.print("CRC recived: ");
Serial.println(crc_ric);
//calculate CRC-8, and I obtain the byte's array
/********************************************************************************/
byte bhmax = (byte)hmax;
byte bhmin = (byte)hmin;
byte btmax = (byte)tmax;
byte btmin = (byte)tmin;
byte crc32_str[4] = {
bhmax, bhmin, btmax, btmin
};
crc = CRC8(crc32_str);
Serial.println("CRC: ");
Serial.println(crc);
/********************************************************************************/
if (crc_ric == (int)crc) {
//Save in the EEPROM
EEPROM_writeDouble(0, tmax);
EEPROM_writeDouble(4, tmin);
EEPROM_writeInt(8, hmax);
EEPROM_writeInt(10, hmin);
}
}
}
delay(10);
}
/********************************************************************************/
WiFi.disconnect();
//Manage the HUMIDIFIER, HEATER and fan according to the sensor's value
/**************************************************************************************/
//HEATER
if (myDHT22.getTemperatureC() >= tmax) {
digitalWrite(HEATER, HIGH);
}
if (myDHT22.getTemperatureC() <= tmin + 1) {
digitalWrite(HEATER, LOW);
}
//HUMIDIFIER
if ((int)myDHT22.getHumidity() >= hmax) {
digitalWrite(HUMIDIFIER, HIGH);
}
if ((int)myDHT22.getHumidity() <= hmin + 1) {
digitalWrite(HUMIDIFIER, LOW);
}
//Fan, Brushless motor
if (myDHT22.getTemperatureC() >= tmax + 4) {
//Rotation of the motor according to with temperature, duty -> 0 per t = tmax+4 and duty -> 100 per t > tmax+10
//Rotazione del motore al variare della temperatura, duty -> 0 per t = tmax+4 e duty -> 100 per t > tmax+10
duty_motor = map(i , tmax + 4, tmax + 10, 0, 100);
if (tmax > tmax + 10) {
duty_motor = 100;
}
analogWrite(IN_2, duty_motor);
delay(TCONST);
}
if (myDHT22.getTemperatureC() <= (tmax + tmin) / 2) {
reset_ports();
//Rotation of the motor according to with temperature, duty -> 0 per t = tmax+4 and duty -> 255 per t > tmax+10
duty_motor = 0;
analogWrite(IN_2, duty_motor);
delay(TCONST);
}
/**************************************************************************************/
delay(1000);
}
//Save double in EEPROM
void EEPROM_writeDouble(int ee, double value) {
byte* p = (byte*)(void*)&value;
for (int i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
}
//Save int in EEPROM
void EEPROM_writeInt(int ee, int value) {
byte* p = (byte*)(void*)&value;
for (int i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
}
//Read double to EEPROM
double EEPROM_readDouble(int ee) {
double value = 0.0;
byte* p = (byte*)(void*)&value;
for (int i = 0; i < 4; i++)
*p++ = EEPROM.read(ee++);
return value;
}
//Read int to EEPROM
int EEPROM_readInt(int ee) {
int value = 0;
byte* p = (byte*)(void*)&value;
for (int i = 0; i < 2; i++)
*p++ = EEPROM.read(ee++);
return value;
}
//Reset input
void reset_ports()
{
digitalWrite(IN_1, 0);
digitalWrite(IN_2, 0);
}
//Algorithm for CRC-8 based on Dallas/Maxim's farmulas
byte CRC8(const byte * data) {
byte crc = 0x00;
while (*data) {
byte extract = *data++;
for (byte tempI = 8; tempI; tempI--) {
byte sum = (crc ^ extract) & 0x01;
crc >>= 1;
if (sum) {
crc ^= 0x8C;
}
extract >>= 1;
}
}
return crc;
}
//It uses to reset millis()
void resetMillis() {
cli();
timer0_millis = 0;
sei();
}
<?php
$username = "root";
$password = "";
$hostname = "localhost";
//connection to the database
$dbhandle = mysql_connect($hostname, $username, $password)
or die("Unable to connect to MySQL");
//echo "Connected to MySQL<br>";
//select a database to work with
$selected = mysql_select_db("serra",$dbhandle)
or die("Could not select examples");
$datada = $_GET["datada"];
$dataa = $_GET["dataa"];
//execute the SQL query and return records
$result = mysql_query("SELECT hum,temp,date FROM record WHERE date >= '".$datada."' and date <='".$dataa."'");
$records=array();
//fetch tha data from the database
while ($row = mysql_fetch_array($result)) {
$tmp = array("hum"=>$row{'hum'}, "temp"=>$row{'temp'}, "date"=>$row{'date'});
array_push($records,$tmp);
//echo "HUM:".$row{'hum'}." TEMP:".$row{'temp'}."Date: ". //display the results
$row{'date'}."<br>";
}
echo json_encode($records);
//close the connection
mysql_close($dbhandle);
?>
Comments