Pages: [1]   Go Down
Author Topic: DS2482-800 reading DS18b20 temperature sensor  (Read 1434 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi have used the libray from paeae https://github.com/paeaetech/paeae/tree/master/Libraries/ds2482/  files attached.
this with one or more 18b20 devices reports the address and CRC byte as expected. I then want to send convert temperature and read from the values from the sensor scatchpad.

example of what is printed.
ROM = 28 54 8B 83 03 00 00 E2 FFFFFFFFFFFFFFFFFF 0.0
ROM = 28 6F 2B 5F 02 00 00 7C FFFFFFFFFFFFFFFFFF 0.0
No more addresses.

I think I send the correct codes for 18b20  but get 0xFF so can anybody help? I failed to find examples for reading and writing to devices.

Code:
/*
Arduino library for controlling DS2482-100 and DS2482-800 1-wire masters.
Uses Wire library to communicate with DS2482 so be sure to call Wire.begin() before using the library.
Quick example modeled after Onewire example:
*/

#include <Wire.h>
#include <DS2482.h>

DS2482 ds(0);  //channels ds2482-800 is 0 to 7, DS2482-100 is just set 0

byte data[8]; //holding for onewire capture
byte addr[8]; //1wire wire address and CRC

void setup()
{
Wire.begin();
ds.reset();
      

  // start serial port
  Serial.begin(57600);
  
  //below REMed out by author fails test everytime.
  
//configure DS2482 to use active pull-up instead of pull-up resistor
//configure returns 0 if it cannot find DS2482 connected
//if (!ds.configure(DS2482_CONFIG_APU))
//{
// Serial.print("DS2482 not found\n");
//}
}

void loop()
{

       if ( !ds.wireSearch(addr))
{
Serial.print("No more addresses.\n");
ds.wireResetSearch();


return;
}
  Serial.print("ROM =");
  for( int i = 0; i < 8; i++) {
    Serial.write(' ');
    if (addr[i] < 16) Serial.print("0");
    Serial.print(addr[i], HEX);
  }
  if (ds.crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  //test if device code DS18b20
 if (addr[0]==0x28) {
 //force temperature convertion start
  ds.reset();
  ds.selectChannel(0); //necessary on -800
  //ds.wireSelect(addr);
  ds.wireSkip();  //skip address, used all to address all devices
  ds.wireWriteByte(0x44); //convert temperature on all devices
  delay(1000); //wait for conversion could test status.
  
 //read temperature data.
  ds.reset();
  ds.selectChannel(0); //necessary on -800
  ds.wireSelect(addr);
  ds.wireWriteByte(0xbe);         // Read Scratchpad command

//display hex values of scratchpad
  Serial.print(" ");
  for ( int i = 0; i < 9; i++) {           // we need 9 bytes
   //command 0x96 (1wire readbyte)
   //command 0xE1 (command set read pointer)
   //write 0xE1 (read register code)
   //i2c Read
    data[i] = ds.wireReadByte();
    
 if (data[i]<16)Serial.print("0");
 Serial.print(data[i],HEX);
    
  }
Serial.print(" ");

//convert to decimal temperature

  int LowByte = data[0];
  int HighByte = data[1];
  int TReading = (HighByte << 8) + LowByte;
  int SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }

  int Tc_100 = (double)TReading * 0.0625 * 10;

  if (SignBit) // If its negative
  {
     Tc_100=0-Tc_100;
  }
  
  //print temp for each device
    
    Serial.print( Tc_100/10);
    Serial.print(".");
    Serial.println(Tc_100%10);
  
 }
 

}

Thanks in advance
Graham

* DS2482.h (2.99 KB - downloaded 23 times.)
* README (0.67 KB - downloaded 16 times.)
* DS2482.cpp (5.39 KB - downloaded 29 times.)
« Last Edit: February 21, 2014, 12:32:24 pm by Graham_Wise » Logged

Offline Offline
Faraday Member
**
Karma: 61
Posts: 2898
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are succeeding in reading the address of each device,  I guess the communication is probably working.

The code you are using looks a bit strange.

My suggestion would be to find some other examples of code which uses this device and see what differences there are in the program.
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your code looks more than a bit strange, it looks unique.

Perhaps you are trying to do something different, but I assume the objective to use the Arduino to obtain temperature readings from the DS18B20. It seems that you are trying to use the DS2482 to do something the DS18B20 can do by itself. I therefore believe you are on the wrong tram and the solution is to ditch the DS2482 and start over again, using the DS18B20 in the manner in which it is intended

Here is all you need to do that.      http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi have made it work. The big problem was the reset, I used ds.resest(); which is the DS2482 chip reset when I should used ds.wireReset(); instead.  The next problem was with two devices it showed correct tempertures and with more didn't.  The global temperature convert command fails.  I powered the devices with 5V and then it works. I don't understand enough yet to hard power the I/O pin to power all the devices to convert, I think it need an external FET.   The 4k7 resistor in out makes no difference.

ROM = 28 54 8B 83 03 00 00 E2 62014B467FFF0E1003 22.1
ROM = 28 2F 8E 83 03 00 00 50 62014B467FFF0E1003 22.1
ROM = 28 6F 2B 5F 02 00 00 7C 59014B467FFF0710A2 21.5
No more addresses.

I have many temperatures to convert, on the solar heating, heat recovery systems along with my weather station and 3 rain gauges, so I want many channels of Onwire so it a device shorts it doesn't take it all down hence the DS2482-800 chip. I have used 5 pins each a Onwire network but this releases pins and is a better solution. Now that oneWire Read and Write work I can recode the DS2407 and DS2423 routines.

The revised code from before is listed the include files are unchanged.
Graham

Code:
/*
Arduino library for controlling DS2482-100 and DS2482-800 1-wire masters.
Uses Wire library to communicate with DS2482 so be sure to call Wire.begin() before using the library.
Quick example modeled after Onewire example:
*/

#include <Wire.h>
#include <DS2482.h>

DS2482 ds(0);  //channels ds2482-800 is 0 to 7, DS2482-100 is just set 0

byte data[8]; //holding for onewire capture
byte addr[8]; //1wire wire address and CRC

void setup()
{
Wire.begin();
ds.reset();
       

  // start serial port
  Serial.begin(57600);
 
  //below REMed out by author fails test everytime.
 
//configure DS2482 to use active pull-up instead of pull-up resistor
//configure returns 0 if it cannot find DS2482 connected
//if (!ds.configure(DS2482_CONFIG_APU))
//{
// Serial.print("DS2482 not found\n");
//}
   ds.wireReset();
   ds.wireSkip();
   //need to send high power to bus??  Adding 5 volts to devices makes it work.
   ds.wireWriteByte(0x44); //convert temperature on all devices
   delay(1000); //wait for conversion
 
}

void loop()
{
   
  //do search
 
   if ( !ds.wireSearch(addr))
     {
Serial.print("No more addresses.\n");

  ds.wireResetSearch();
   ds.wireReset();
   ds.wireSkip();
   //need to send high power to bus??  Adding 5 volts to devices makes it work.
   ds.wireWriteByte(0x44); //convert temperature on all devices
   delay(1000); //wait for conversion
 

  return;
      }
     
   Serial.print("ROM =");
   for( int i = 0; i < 8; i++) {
    Serial.write(' ');
    if (addr[i] < 16) Serial.print("0");
     Serial.print(addr[i], HEX);
    }
   
   if (ds.crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
   }
 
  //test if device code DS18b20
 if (addr[0]==0x28) {
 
  //read temperature data.
  ds.wireReset(); //ds.reset();
  ds.selectChannel(0); //necessary on -800
  ds.wireSelect(addr);
  ds.wireWriteByte(0xbe);         // Read Scratchpad command

//display hex values of scratchpad
  Serial.print(" ");
  for ( int i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.wireReadByte();
 
   if (data[i]<16)Serial.print("0");
   Serial.print(data[i],HEX);
   
  }
  Serial.print(" ");

//convert to decimal temperature

  int LowByte = data[0];
  int HighByte = data[1];
  int TReading = (HighByte << 8) + LowByte;
  int SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }

  int Tc_100 = (double)TReading * 0.0625 * 10;

  if (SignBit) // If its negative
  {
     Tc_100=0-Tc_100;
  }
 
  //print temp for each device
   
    Serial.print(Tc_100/10);
    Serial.print(".");
    Serial.println(Tc_100%10);
   
 }
 

}

 
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi have made it work.

OK, but that is no confirmation of a good idea. If you are referring to power for the DS18B20s, you probably won't need a FET but you probably will need a pullup eventually. I only say this because nobody uses a FET but everybody uses a pullup of some sort. This might not be relevant in your case but might be something worth bearing in mind.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Further Notes:
There are two types of pull-up in the DS2482 Active and Strong. The Active APU does away with a pull-up resistor and pulls the bus high actively pulse by pulse. The strong pull-up SPU is enabled after the last bit or a Read or Write and remains until another transaction or is rest or turned off.  So the logical state is APU is on by default and when wanted to convert temperature enable SPU and then wait for the conversion time.

So sequence is for DS18b20 temperature sensors.
ds.wireReset();
ds.selectChannel(0); // after reset need to set channel
ds.configure(0x05); //adding this helps but does make sense.
ds.wireSkip();
ds.configure(0x05); //set bus on strong pull-up after next write, not only LSB nibble is required
ds.wireWriteByte(0x44); //convert temperature on all devices
delay(1000); //wait for conversion   
ds.configure(0x01);

Doing this one device works reliably, two can work some of the time; but more doesn’t. I have tried various combinations and tried different pin on the DS2482-800 without improvement. The only solution remains to DC power the sensors. The other method that is slow is to address each chip convert the temperature and then read it, effectively one chip drawing current.
I have tried decoupling of the DS2482 chip, a higher Current 5V DC supply.
A Decoupling capacitor 100nF on the DS18b20 supply pin makes 2 function reliably hinting the devices are nor holding enough charge and or the SPU is not strong enough. Adding more capacitance doesn’t help even with 10uF 3 devices still don’t work.
Extending the delay time no effect.
Adding a digital output through a diode to the OneWire pin did make 3 work but not 4 again hinting the SPU is weak or the DS820 are too demanding.
There is nothing obvious in the CCP library or the data sheet so I am stuck of how to improve it.
Graham

* DS2482-800.pdf (431.05 KB - downloaded 20 times.)
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I understood it worked - apparently not. It might be time to take stock of the situation and the first thing to review is why you are doing it differently to everybody else. There may be a good reason, but there certainly isn't a clear one.

The next item to consider is the power supply. All that gets mentioned is lots of peripherals, lots of current, but only 5 volts, and your problem could simply be a shortage of the latter. It might also pay to read the DS18B20 data sheet and check the active power requirement. I believe it is 1 mA.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If the 18b20 are powered by DC then it does work.  I just can make it work on paracitic power.

ROM = 28 78 6A 5F 02 00 00 86 5C014B467FFF0410A1 21.7
ROM = 28 54 8B 83 03 00 00 E2 5B014B467FFF0510B5 21.6
ROM = 28 2C 4D 83 03 00 00 65 5B014B467FFF0510B5 21.6
ROM = 28 42 37 CE 02 00 00 B3 5C014B467FFF0410A1 21.7
ROM = 28 D6 80 83 03 00 00 16 5C014B467FFF0410A1 21.7
ROM = 28 6E 1B CE 02 00 00 A1 5B014B467FFF0510B5 21.6
ROM = 28 91 34 5F 02 00 00 0E 5B014B467FFF0510B5 21.6
ROM = 28 89 47 CE 02 00 00 B9 5A014B467FFF0610A3 21.6
ROM = 28 E3 14 CE 02 00 00 6E 5A014B467FFF0610A3 21.6
ROM = 28 2F 8E 83 03 00 00 50 5C014B467FFF0410A1 21.7
ROM = 28 6F 2B 5F 02 00 00 7C 54014B467FFF0C10FD 21.2
No more addresses.

Graham
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If the 18b20 are powered by DC then it does work.  I just can make it work on paracitic power.

The second sentence is unintelligible but the whole might hint at a misunderstanding. The normal practice is to power the DS18B20 from the Arduino 5v pin, not an external supply.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A slow version that works on parasite power.
From DS18b20 data sheet.
“the DS18B20’s parasite power control circuitry, which “steals” power from the 1-Wire bus via the DQ pin when the bus is high.”
The current during the temperature conversion is typically 1.0 max 1.5mA

From the DS2482 data sheet.
Strong Pullup Voltage Drop VCC >= 3.2V, 1.5mA load  0.3V
                                  VCC >=5.2 V,   3mA load  0.5V
So the DS2482 can on power 2 devices at 5v and only 1 at 3.2v. I know that the voltage can be down to 2.5V so there is a little more current available, for the temperature conversion.  This means it will never power many devices at once.  So my wish to convert all DS18b20 devices at once that does work on an Android pin as it has 40mA current, perhaps 25 devices.
The only way to make it work is to individually access device by device, request the temperature conversion then read the value, about 900ms each. Not one convert command to all and many shorter read times.

I did a load test on the DS2482 I/O and loading with resistors to vary the current indicated it is about 1k4 ohms, which seems wrong for the SPU dropping only 0.5V at 3 mA. I have tried all the possible numbers in the configuration resister using ds.configure and direct Wire.Write command for the 0xD2 configuration register without improvement. It is like the APU setting is timed and the SPU is just on, perhaps the chip is subtly broken. APU is 800 to 1650 ohm range.

ROM = 28 78 6A 5F 02 00 00 86 5B014B467FFF0510B5 21.6 899 ms
ROM = 28 54 8B 83 03 00 00 E2 5C014B467FFF0410A1 21.7 1799 ms
ROM = 28 2C 4D 83 03 00 00 65 59014B467FFF0710A2 21.5 2699 ms
ROM = 28 42 37 CE 02 00 00 B3 5A014B467FFF0610A3 21.6 3599 ms
ROM = 28 D6 80 83 03 00 00 16 5A014B467FFF0610A3 21.6 4499 ms
ROM = 28 6E 1B CE 02 00 00 A1 59014B467FFF0710A2 21.5 5399 ms
ROM = 28 91 34 5F 02 00 00 0E 58014B467FFF0810F9 21.5 6299 ms
ROM = 28 89 47 CE 02 00 00 B9 57014B467FFF0910C7 21.4 7199 ms
ROM = 28 E3 14 CE 02 00 00 6E 59014B467FFF0710A2 21.5 8098 ms
ROM = 28 2F 8E 83 03 00 00 50 5D014B467FFF03108C 21.8 8998 ms
ROM = 28 6F 2B 5F 02 00 00 7C 58014B467FFF0810F9 21.5 9899 ms
No more addresses.

Code:
#include <Wire.h>
#include <DS2482.h>

DS2482 ds(0);  //channels ds2482-800 is 0 to 7, DS2482-100 is just set 0

byte data[8]; //holding for onewire capture
byte addr[8]; //1wire wire address and CRC
long time_temp;

void setup()
{
Wire.begin();
ds.reset();
        pinMode(13, OUTPUT);

  // start serial port
  Serial.begin(57600);
  time_temp=millis();}

void loop()
{
   
  //do search
 
   if ( !ds.wireSearch(addr))
     {
Serial.print("No more addresses.\n");
        ds.wireResetSearch();

  return;
      }
     
   Serial.print("ROM =");
   for( int i = 0; i < 8; i++) {
    Serial.write(' ');
    if (addr[i] < 16) Serial.print("0");
     Serial.print(addr[i], HEX);
    }
   
   if (ds.crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
   }
 
  //test if device code DS18b20
 if (addr[0]==0x28) {
 
  //read temperature data.
  ds.wireReset();
  ds.selectChannel(0);
  ds.wireSelect(addr);
  ds.configure(0x05); //set bus on strong pull-up after next write until next command
  ds.wireWriteByte(0x44); //convert temperature on this device
  delay(770); //wait for conversion 750ms Plus margin
  ds.wireReset();
  ds.selectChannel(0);
  ds.wireSelect(addr);
  ds.wireWriteByte(0xbe);         // Read Scratchpad command

//display hex values of scratchpad
  Serial.print(" ");
  for ( int i = 0; i < 9; i++) {           // we need 9 bytes to capture CRC
    data[i] = ds.wireReadByte();
 
   if (data[i]<16)Serial.print("0");
   Serial.print(data[i],HEX);
   
  }
  Serial.print(" ");

//convert to decimal temperature

  int LowByte = data[0];
  int HighByte = data[1];
  int TReading = (HighByte << 8) + LowByte;
  int SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }

  int Tc_100 = (double)TReading * 0.0625 * 10;

  if (SignBit) // If its negative
  {
     Tc_100=0-Tc_100;
  }
 
  //print temp for each device
   
    Serial.print(Tc_100/10);
    Serial.print(".");
    Serial.print(Tc_100%10);
    Serial.print(" ");
    Serial.print(millis() - time_temp);
    Serial.println(" ms");
 }
 

}
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm afraid I can't comment on this any further, and I don't suppose there is any point in suggesting that you re-read reply #2. Your objective is far from clear and it seems that you are just bashing your head against the brickwork while you try to re-invent the wheel.  In the meantime the rest of us get along just fine by using their DS18B20s in the way that God and Dallas intended.

I have never yet heard of a good reason for using parasite power, and I bet you don't have one either.  Using normal power and a low resolution will enable you to use a shorter loop cycle. Failing that, you are probably better off abandoning the DS18B20 and using PT100s, or the like, which I guess can be read as fast as your programme can run. I understand the PT can return better accuracy than the DS18B20 too, but most people round here don't find that a good enough reason to use them.
« Last Edit: February 25, 2014, 05:46:05 pm by Nick_Pyner » Logged

Pages: [1]   Go Up
Jump to: