Go Down

Topic: DS18B20 multiple sensors (Read 9269 times) previous topic - next topic

gasperinn

Hi,

I have connected 9 of DS18B20 sensors on the arduino mega (pin 3) and one DHT22 sensor on pin 2. With 5minutes delay, the arduino board on serial monitor prints all addresses of those DS18B20 with their temperatures and temperature and humidity of that DHT22 sensor. Everything works fine, until i connect the 10th DS18B20 sensor. When i connect the 10th sensor the board prints only the temperature and humidity from DHT22 sensor. Any suggestions what should be wrong?

I wired the DS18B20 sensors like that: http://bildr.org/blog/wp-content/uploads/2011/06/DS18S20-hookup.png

GoForSmoke

How are you powering that many sensors?
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

gasperinn

All to the same 5V pin on arduino board. Arduino is powered by 9V adapter.

el_supremo

If you are using the 4.7k resistor shown in the diagram try changing it to 2.2k or 1k.

Pete

gasperinn

Ok, so it is possible that 5V is not enough power supply for all of them, but i have in mind to connect about 5-10 more sensors, will that 5V be enough you think?

what if i connect 5V cable to data cable without resistor?

GoForSmoke

It's not the 5V, it's the 5V -through- the Arduino. You want to draw 200 mA or less total -through- the Arduino. Think about external power through transistors.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

el_supremo

Quote
Ok, so it is possible that 5V is not enough power supply for all of them

No, that is not why. I assume that you are using them in parasite mode in which case the pullup must not be high enough that it prevents parasite mode from working properly. The spec for the DS18B20 says that it uses 1mA while doing a conversion. The 4.7k resistor you are using may not permit enough current when you have so many devices on the bus. So, reduce the resistor to 2.2k or 1k and see if that fixes the problem.
However, when you have that many devices (and you say you want to add more) I presume you are spreading them around. If you are using parasite mode with that many devices you will have to take note of what the datasheet says about how to power the I2C bus properly.

Pete

gasperinn

#7
Feb 25, 2013, 08:33 pm Last Edit: Feb 25, 2013, 09:05 pm by gasperinn Reason: 1
I don't really know how does the parasite mode looks like :) I have one wire for +5V, one wire for GND and one wire for data going out of the Arduino. Then those wires splits up in 9 different ways and then realy close to the sensors i have resistors (connecting 5V and data) on each of the sensors. Is that ok, or i should better use just one resistor in the begining (near to Arduino board) for all of the sensors?

I would try it with 1k resistor, but i have one problem. The senzors are already in place, with the 4.7k resistors. So if i understand it right, if i connect one more sensor (10th), not with 4.7k resistor but with the 1k resistor, then the Arduino should read at least that sensor. I don't want to happen that i would disassemble all of the sensors and replace the resistors and then it wouldn't work.


el_supremo

You appear to be providing a 5V line to each of the sensors, in which case you don't need to use parasite mode, but I don't think you need a 4k7 resistor on each sensor either.
If you post your code we can tell whether your code is using parasite mode and take it from there.

Pete


gasperinn

#9
Feb 25, 2013, 11:29 pm Last Edit: Feb 25, 2013, 11:37 pm by gasperinn Reason: 1
Ok, here is the code:

Code: [Select]

#include <DHT22.h>
#include <OneWire.h>

#define DHT22_PIN 2 // DHT22 on pin X

OneWire  ds(3);  // DS18B20s on pin X

void setup()
{
  Serial.begin(9600);
}

void loop()
{
byte data[12];
byte addr[8];

DHT22 myDHT22(DHT22_PIN);

delay(2000); //DHT22 can only be read 1-2 s


//while number of DS18B20 sensors are connected
while( ds.search(addr)) {

printAddressDS18B20(addr);

readDataDS18B20(addr, data);

float celsius = getTemperatureDS18B20(data);
               Serial.print(";");
Serial.print(celsius);
Serial.println();

}

resetDS18B20DsSearch();

printTemperatureHumidityDHT22(myDHT22);

       delay(298000);


}

float getTemperatureDS18B20(byte data[12]){

unsigned int raw = (data[1] << 8) | data[0];
 
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time

return (float)raw / 16.0;
}

void readDataDS18B20(byte addr[8], byte data[12]){

 byte present = 0;

 ds.reset();
 ds.select(addr);
 ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
 delay(1000);     // maybe 750ms is enough, maybe not
 // we might do a ds.depower() here, but the reset will take care of it.
 
 present = ds.reset();
 ds.select(addr);    
 ds.write(0xBE);         // Read Scratchpad

 for ( byte i = 0; i < 9; i++) {           // we need 9 bytes
data[i] = ds.read();
 }
}

void resetDS18B20DsSearch(){
ds.reset_search();
delay(250);
}
void printAddressDS18B20(byte addr[8]){
     
 for( byte i = 0; i < 8; i++) {
Serial.print(addr[i], HEX);
 }
}

void printTemperatureHumidityDHT22(DHT22 DHT22){
DHT22_ERROR_t errorCode = DHT22.readData();

switch(errorCode)
 {
case DHT_ERROR_NONE:
 Serial.print("DHT22;");
 Serial.print(DHT22.getTemperatureC());
 Serial.print(";");
 Serial.println(DHT22.getHumidity());
     
 break;
  }
}




Is there any other, simplier way to get temperature from DS18B20?

GoForSmoke

I look at those delays and think "no, I don't have time to rewrite the whole thing".

BlinkWithoutDelay. Finite State Machine.


Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

el_supremo

Code: [Select]
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
Yep, you are using parasite power. Your description of how you have wired up the sensors suggests that you don't need this, so change it to:
Code: [Select]
  ds.write(0x44,0);         // start conversion.
and try again.

Pete

afremont

#12
Feb 26, 2013, 09:53 am Last Edit: Feb 26, 2013, 10:12 am by afremont Reason: 1
The OP wrote: "I have one wire for +5V, one wire for GND and one wire for data going out of the Arduino. Then those wires splits up in 9 different ways and then realy close to the sensors i have resistors (connecting 5V and data) on each of the sensors. Is that ok, or i should better use just one resistor in the begining (near to Arduino board) for all of the sensors?"

I think he has a resistor on each sensor, making for 10 resistors when he has 10 sensors.  If that's the case, then that's the problem.  Only one pullup resistor to +5V on the data line.  With all those resistors in parallel, the devices can't pull the bus low.

EDIT:  I suggest the OP read some Dallas documentation on powering the 1-wire data bus.  He could get rid of a wire (+5V) by using parasitic power mode thru the data line.  Then he'd only have to run the Data(Q) and Gnd wires to the sensors.  Handier sometimes.
Experience, it's what you get when you were expecting something else.

GoForSmoke

Why would you want to pull the power line low?

But then why put a resistor between power and data? Between power and the chip, I could see.
First time I read that I just figured it was some kind of typo.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

afremont

Dallas 1-wire devices are open-collector.  You have to supply a pull-up resistor from the data line to +5V (Vcc) on the data bus.  Only one resistor is needed for the entire bus.
Experience, it's what you get when you were expecting something else.

Go Up