Library - One Wire / DS18B20 (Multiple devices, async)

[title]One Wire / DS18B20 (Multiple devices, async)[/title]
http://code.tinyclr.com/project/456/one-wire--ds18b20-multiple-devices-async/
[line]
This library allows you to use multiple one-wire devices on the same bus

It allows for devices of different types (Only code for the DS18B20 has been written, but it’s easily extended) to be used both synchronously and asynchronously

It can be used in raw NETMF and Gadgeteer - The test application is set-up for the Spider using socket #8 and pin #6

XML documentation is provided for all methods and all public properties

The source code file shown shows the code required to define a new device - The class is automatically registered as long as it inherits from OneWireDevice and replaces the FamilyCode static property

I have this working, and it’s a far better piece of code than any other comparable library I’ve seen.
I’m going to try to add support for the DS2413 switch and DS2450 quad A/D. I’ll share it if I succeed!

I’m glad you like it. :slight_smile:

Drop a link in here when you’ve made your changes and I’ll add it to the description on the code page.

Any way you can add support to change the resolution on DS18B20s?

While it’s cool to have it Async so it’s not blocking reducing the resolution should reduce conversion time. I want to get 5-6 sensors on one bus and if all 5 are active the round-trip is excrutiating at full resolution.

Most of the code examples from Dallas in CPP have this.

I’ll see what I can do tonight, would probably not make it asynchronous though seems as it’s just a one-time configuration.

I couldn’t get my initial resolution code that I threw together last night working. I’ll mess with it more tonight and if I do I’ll send it over.

I do think that by changing the resolution we’ll also have to change the multiplier on the value retrieved from the scratchpad after a conversion.

so the class would have to track the resolution of each device and apply the multiplier based on that.

Off the top of my head I think the value of the multiplier would still be the same, but the lower bits would need to be masked as they are undefined.

I’m looking at some CPP code I just found that does the temperature conversion based on resolution. This is what I had implemented in .NET last night when I was fooling with it:


float DS18B20::calculateTemperature(BYTE* data)
 {
     bool signBit = false;
     if (data[TEMPERATURE_MSB] & 0x80) signBit = true;
         
     int read_temp = (data[TEMPERATURE_MSB] << 8) + data[TEMPERATURE_LSB];
     if (signBit)
     {
         read_temp = (read_temp ^ 0xFFFF) + 1;    // two's complement
         read_temp *= -1;
     }
     
     int resolution = (data[CONFIG_REG_BYTE] & 0x60) >> 5; // mask off bits 6,5 and move to 1,0
     switch (resolution)
     {
         case nineBit:    // 0.5 deg C increments
             read_temp &= 0xFFF8;                // bits 2,1,0 are undefined
              pc_ds18B20.traceOut("9 bit resolution ...\r\n");
             break;
         case tenBit:     // 0.25 deg C increments
             read_temp &= 0xFFFC;                // bits 1,0 are undefined
             pc_ds18B20.traceOut("10 bit resolution ...\r\n");
             break;
         case elevenBit:  // 0.125 deg C increments
             read_temp &= 0xFFFE;                // bit 0 is undefined
             pc_ds18B20.traceOut("11 bit resolution ...\r\n");
             break;
         case twelveBit:  // 0.0625 deg C increments
             pc_ds18B20.traceOut("12 bit resolution ...\r\n");
             break;
     }
00098     float realTemp = (float)read_temp/16 ;
00099                  
00100     pc_ds18B20.traceOut("TEMP_READ/REAL TEMP: %f \r\n", realTemp); 
00101                
00102     return realTemp;
00103 }



so you’re right, the multiplier is the same, but the other bits are being washed.

In order to write to the scratch pad, you need to read the scratch pad (So you don’t overwrite your alarms) so the entire scratch pad might as well be stored.

Negative values / two’s complement should have been added in the first place, I totally missed that. :-[

It’s a shame that the formula for the mask requires a power as it would have been neater, but it would just be a waste: (And I don’t even know if NETMF supports Math.Pow.)


if (resolution < 12)
{
    temperature &= ~(Math.Pow(2, 11 - resolution) - 1);
}