5 temp sensors AM2301 - strange reading

Hi everyone,

is my first post on arduino forum so I hope will do it right.

I have an arduino UNO and I have connected 5 sensors AM2301 because I will like to check temp in 5 location. now the sensors are on my desk one next to other but the readings are different around 1.5 degrease from min to max and on humidity around 3%

I try to read all sensors and display the data and I do not understand why there is so big difference.

Is there any mistakes in my code? I am a beginner of software development and I do have basic understanding.

here is the code


#include “DHT.h”
//—
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac = {
0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36 }; //MAC address found on the back of your ethernet shield.
IPAddress ip(192,168,2,177); // IP address dependent upon your network addresses.

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
//—

#define DHT1PIN 2 // what pin we’re connected to
#define DHT2PIN 3
#define DHT3PIN 5
#define DHT4PIN 6
#define DHT5PIN 7

// Uncomment whatever type you’re using!
//#define DHT1TYPE DHT11 // DHT 11
#define DHT2TYPE DHT22 // DHT 22 (AM2302)
#define DHTTYPE DHT21 // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht1(DHT1PIN, DHTTYPE);
DHT dht2(DHT2PIN, DHTTYPE);
DHT dht3(DHT3PIN, DHTTYPE);
DHT dht4(DHT4PIN, DHTTYPE);
DHT dht5(DHT5PIN, DHTTYPE);

void setup() {
Serial.begin(9600);
Serial.println(“DHTxx test!”);

delay(5000);
dht1.begin();
dht2.begin();
dht3.begin();
dht4.begin();
dht5.begin();

Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}

void loop() {
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds ‘old’ (its a very slow sensor)
float h1 = dht1.readHumidity();
float t1 = dht1.readTemperature();
float h2 = dht2.readHumidity();
float t2 = dht2.readTemperature();
float h3 = dht3.readHumidity();
float t3 = dht3.readTemperature();
float h4 = dht4.readHumidity();
float t4 = dht4.readTemperature();
float h5 = dht5.readHumidity();
float t5 = dht5.readTemperature();
// check if returns are valid, if they are NaN (not a number) then something went wrong!

if (isnan(t1) || isnan(h1)) {
Serial.println(“Failed to read from DHT #1”);
} else {
Serial.print(“Humidity 1: “);
Serial.print(h1);
Serial.print(” %\t”);
Serial.print(“Temperature 1: “);
Serial.print(t1);
Serial.println(” *C”);
}
if (isnan(t2) || isnan(h2)) {
Serial.println(“Failed to read from DHT #2”);
} else {
Serial.print(“Humidity 2: “);
Serial.print(h2);
Serial.print(” %\t”);
Serial.print(“Temperature 2: “);
Serial.print(t2);
Serial.println(” *C”);
}
if (isnan(t3) || isnan(h3)) {
Serial.println(“Failed to read from DHT #3”);
} else {
Serial.print(“Humidity 3: “);
Serial.print(h3);
Serial.print(” %\t”);
Serial.print(“Temperature 3: “);
Serial.print(t3);
Serial.println(” *C”);
}

if (isnan(t4) || isnan(h4)) {
Serial.println(“Failed to read from DHT #4”);
} else {
Serial.print(“Humidity 4: “);
Serial.print(h4);
Serial.print(” %\t”);
Serial.print(“Temperature 4: “);
Serial.print(t4);
Serial.println(” *C”);
}

if (isnan(t5) || isnan(h5)) {
Serial.println(“Failed to read from DHT #5”);
} else {
Serial.print(“Humidity 5: “);
Serial.print(h5);
Serial.print(” %\t”);
Serial.print(“Temperature 5: “);
Serial.print(t5);
Serial.println(” *C”);
}
Serial.println();

// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println(“new client”);
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// 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(“Connection: close”); // the connection will be closed after completion of the response
client.println(“Refresh: 5”); // refresh the page automatically every 5 sec
client.println();
client.println("");
client.println("");

client.print(“H1= “);
client.print(h1);
client.print(” %\t”);
client.print(“T1= “);
client.print(t1);
client.println(”

”);

client.print(“H2= “);
client.print(h2);
client.print(” %\t”);
client.print(“T2= “);
client.print(t2);
client.println(”

”);

client.print(“H3= “);
client.print(h3);
client.print(” %\t”);
client.print(“T3= “);
client.print(t3);
client.println(”

”);

client.print(“H4= “);
client.print(h4);
client.print(” %\t”);
client.print(“T4= “);
client.print(t4);
client.println(”

”);

client.print(“H5= “);
client.print(h5);
client.print(” %\t”);
client.print(“T5= “);
client.print(t5);
client.println(”

”);

client.println("");
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();
Serial.println(“client disonnected”);
}
}

reading example:

H1= 56.80 % T1= 20.30
H2= 56.60 % T2= 21.20

H3= 57.90 % T3= 20.90

H4= 57.90 % T4= 20.80

H5= 56.40 % T5= 21.60

all 5 sensors are very close to each other... do I have to calibrate de sensors??

The AM2301 has +/- 3% accuracy on humidity if powered at 5V so you could see variance of up to 6% between 2 sensors if you are unlucky

On the temperature side the accuracy is typically +/-0.3 degree but can go as high as +/-1 degree. So seeing 1.5 degree difference between two units is kinda within spec error range (a bit atypical though)

Ideally it’s best for accurate readings to ensure that at least 2 seconds separate two consecutive readings. So I would add a non blocking if (millis()-lastReading < 2000) type of approach in the loop and not read the sensors at every loop

(Please use the code tags around your code)

Thank you very much for you answer,

i’vew check in dht.cpp and found
if (currenttime < _lastreadtime) {
// ie there was a rollover
_lastreadtime = 0;
}
if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
return true; // return last correct measurement
//delay(2000 - (currenttime - _lastreadtime));
}
firstreading = false;

is not similar with what you told me?

I am thinking that reading sequential each sensors, starting with S1 … S5 and then it return to S1 will add some time… will not pass 2 seconds?

not rely sure how to use the "if (millis()-lastReading < 2000) ":slight_smile:

Yes you are right the library is waiting for you

otherwise no, not long enough 5 sensors x 250ms does not make 2 seconds wait

So I think you are within precision error of your modules (ensure they all get a full clean 5v)

In this moment i connect all 5 to arduino bord, (data and 5V + and ground) and arduino powered via USB but when i will move them to their location ( one in each room)
i am planning to power them and arduino uno from external 5V source.

thank you for your time.

Do you plan to have super long wires going to each room? Or 1 arduino + sensor per room reporting centrally over Ethernet?

Hi,

need more help or advise.... the main goal is to read the 5 am2301 sensors and control 5 LED/relay from same arduino board + Ethernet shield

  • I want to read temp/humidity every 30 seconds or 1 minute and to send it to a PHP using GET - but I do want to control the LED real time using the Ethernet shield.

I manage to read the 5 sensors using webclient and do GET but I don't know to control LED so I have tried with webserver mode but how can I read the sensors every 1 minute and control LED real time?

can someone guild me to right direction or help me with the code structure... I apologies I am beginner and try to learn

Thank you J-M-L for replay,

I do have the cable in place 4X0.22 shielded from each room to a central location ( not longer then 10 meters) (heating system) where I do have a LAN (UTP) cable as well, I do plan to read the 5 sensors temp/humidity and transmit the data to my MySQL server and based on temp reading to activate relays.
this is my home project description:)

So the structure of your program should not be very difficult to set up:

basically the loop() does as follow:

if it is time to do something (every 30 seconds for example)
    - read the sensors
    - build a GET or POST request to your / PHP service
    - send the HTTP request
    - based on the data received, decide to perform an action (relay etc)
    - save the time
end if

and if you want to control the arduino from the web as well then it starts the same way:

if it is time to do something (every 30 seconds for example)
    - read the sensors
    - build a GET or POST request to your / PHP service
    - send the HTTP request
    - based on the data received, decide to perform an action (relay etc)
    - save the time
end if

if there is a web client request
   decode the request
   perform associated actions
  close connection
end if

And on the server side it's a simple PHP program that is triggered and if you have done a GET then just parse the info and dump it into the database.

there are tons of example of web client and web server to be inspired from

Hi,

thank you for your answer, it start to become more clear in my mind the structure and the way should work but, I can set up the arduino as web client or web server that is what I understood, if I set it as web client how can I trieger an action from external via http? let's say I get the data in MySQL and if temp received will be less than I want I want to trigger a relay on same arduino board. ( I understood that if I set up arduino as web server I can do http:\x.x.x.x/?ping=0 or 1)

what do you mean by save the time?
will have something like:
if current time >= previous time + 30 seconds {
read, get....
previous time = current time
} else

You can set up the Arduino to act both as a web client and as a web server.

When it's a client, you send a well formed HTTP GET request to your PHP program running on your web server

When it's a server, you listen to see if there is a client request and if there is, then the library can help you receive that request. You listen from the client doing client.read(); and build up a message buffer (a well formed request you would get would ends with a blank line and a carriage return)

Once you've got your string in the buffer, you need to parse it to understand what the request is. The request is usually build from a PHP program offering an HTML interface with buttons, sliders, text boxes etc and sending a GET or POST request to the arduino server. so depending on how you configure this, then you know what the request you get on the arduino looks like and this is what you need to parse.

Once you've identified which action you want to do, then just set the pins in the right way to trigger a LED, a relay etc...

read the code in the two links above for web client and web server.

what do you mean by save the time?

given your code needs to continually loop() as fast as possible to listen for HTTP incoming requests when it's a server, you can't use delay()or whatever to send the temperature measures to your PHP/SQL server but you don't want to send Temperature every 10 milliseconds either, it's likely that the T° won't change that fast.. usually it's OK to send a temperature like every 5 minutes for example. so to do this you need to record in a variable at what time you have done the last action and compare the current time to that last time. if it's more than 5 minutes, then send the data and update the fact that this is now sent. would look something like this:

unsigned long currentTime, previousTime;
const unsigned long reportingPeriod = 300000UL; // 5 minutes

void setup() {
  previousTime = 0;
  //... other setup() stuff
}

void loop() {

  if (((currentTime = millis()) - previousTime) >= reportingPeriod) {
    // time to do something

    // read the sensors
    // send the GET request to your PHP service

    previousTime = millis();
  }


  // do your web server check here

}

Hi,

I did created the attached code (I apologies don’t know to attached it right), but I do have a problem with the client mode because is doing the GET only first time, is not going inside the IF any more ( if (client.connect(“192.168.1.21”,80)))

  • what could be the problem?

I’ve checked the server and there is no httpd error

serial output is like ( I have decreased the reporting Period to 30000UL- for test)

server is at 192.168.2.177
IF client connected 30529
61050
91572
122093
152614
183135
213656

first get arriving on the server and the php is doing insert in mysql

192.168.2.177 - - [04/Oct/2016:23:00:16 +0300] “get /temp1.php?t1=19.60&h1=61.70 HTTP/1.1” 200 216 “-” “-”

Skype.lnk.ino (3.86 KB)

Hi,

Found the problem/mistake

EthernetClient client;
was missing from code

do you see any other mistake or problem?