@ -31,15 +31,16 @@ import (
"periph.io/x/periph/devices"
)
// New returns an object that communicates over 1-wire to the DS18B20 sensor with the
// specified 64-bit address.
// New returns an object that communicates over 1-wire to the DS18B20 sensor
// with the specified 64-bit address.
//
// resolutionBits must be in the range 9..12 and determines how many bits of precision
// the readings have. The resolution affects the conversion time: 9bits:94ms, 10bits:188ms,
// 11bits:375ms, 12bits:750ms.
// resolutionBits must be in the range 9..12 and determines how many bits of
// precision the readings have. The resolution affects the conversion time:
// 9bits:94ms, 10bits:188ms, 11bits:375ms, 12bits:750ms.
//
// A resolution of 10 bits corresponds to 0.25C and tends to be a good compromise between
// conversion time and the device's inherent accuracy of +/-0.5C.
// A resolution of 10 bits corresponds to 0.25C and tends to be a good
// compromise between conversion time and the device's inherent accuracy of
// +/-0.5C.
func New ( o onewire . Bus , addr onewire . Address , resolutionBits int ) ( * Dev , error ) {
if resolutionBits < 9 || resolutionBits > 12 {
return nil , errors . New ( "ds18b20: invalid resolutionBits" )
@ -47,8 +48,8 @@ func New(o onewire.Bus, addr onewire.Address, resolutionBits int) (*Dev, error)
d := & Dev { onewire : onewire . Dev { Bus : o , Addr : addr } , resolution : resolutionBits }
// Start by reading the scratchpad memory, this will tell us whether we can talk to the
// device correctly and also how it's configured.
// Start by reading the scratchpad memory, this will tell us whether we can
// talk to the device correctly and also how it's configured.
spad , err := d . readScratchpad ( )
if err != nil {
return nil , err
@ -57,10 +58,14 @@ func New(o onewire.Bus, addr onewire.Address, resolutionBits int) (*Dev, error)
// Change the resolution, if necessary (datasheet p.6).
if int ( spad [ 4 ] >> 5 ) != resolutionBits - 9 {
// Set the value in the configuration register.
d . onewire . Tx ( [ ] byte { 0x4e , 0 , 0 , byte ( ( resolutionBits - 9 ) << 5 ) | 0x1f } , nil )
if err := d . onewire . Tx ( [ ] byte { 0x4e , 0 , 0 , byte ( ( resolutionBits - 9 ) << 5 ) | 0x1f } , nil ) ; err != nil {
return nil , err
}
// Copy the scratchpad to EEPROM to save the values.
d . onewire . TxPower ( [ ] byte { 0x48 } , nil )
// Wait for the write to complete
if err := d . onewire . TxPower ( [ ] byte { 0x48 } , nil ) ; err != nil {
return nil , err
}
// Wait for the write to complete.
time . Sleep ( 10 * time . Millisecond )
}
@ -69,13 +74,13 @@ func New(o onewire.Bus, addr onewire.Address, resolutionBits int) (*Dev, error)
// ConvertAll performs a conversion on all DS18B20 devices on the bus.
//
// During the conversion it places the bus in strong pull-up mode to
// p ower p arasitic devices and returns when the conversions have
// completed. This time period is determined by the maximum
// resolution of all devices on the bus and must be provided.
// During the conversion it places the bus in strong pull-up mode to power
// p arasitic devices and returns when the conversions have completed. This tim e
// period is determined by the maximum resolution of all devices on the bus and
// must be provided.
//
// ConvertAll uses time.Sleep to wait for the conversion to finish,
// which takes from 94ms to 752ms.
// ConvertAll uses time.Sleep to wait for the conversion to finish, which takes
// from 94ms to 752ms.
func ConvertAll ( o onewire . Bus , maxResolutionBits int ) error {
if maxResolutionBits < 9 || maxResolutionBits > 12 {
return errors . New ( "ds18b20: invalid maxResolutionBits" )
@ -89,7 +94,8 @@ func ConvertAll(o onewire.Bus, maxResolutionBits int) error {
//===== Dev
// Dev is a handle to a Dallas Semi / Maxim DS18B20 temperature sensor on a 1-wire bus.
// Dev is a handle to a Dallas Semi / Maxim DS18B20 temperature sensor on a
// 1-wire bus.
type Dev struct {
onewire onewire . Dev // device on 1-wire bus
resolution int // resolution in bits (9..12)
@ -113,7 +119,9 @@ func (d *Dev) Temperature() (devices.Celsius, error) {
return d . LastTemp ( )
}
// LastTemp reads the temperature resulting from the last conversion from the device.
// LastTemp reads the temperature resulting from the last conversion from the
// device.
//
// It is useful in combination with ConvertAll.
func ( d * Dev ) LastTemp ( ) ( devices . Celsius , error ) {
// Read the scratchpad memory.
@ -122,15 +130,15 @@ func (d *Dev) LastTemp() (devices.Celsius, error) {
return 0 , err
}
// spad[1] is MSB, spad[0] is LSB and has 4 fractional bits. Need to do sign extension
// multiply by 1000 to get devices.Millis, divide by 16 due to 4 fractional bits.
// Datasheet p.4.
// spad[1] is MSB, spad[0] is LSB and has 4 fractional bits. Need to do sign
// extension multiply by 1000 to get devices.Millis, divide by 16 due to 4
// fractional bits. Datasheet p.4.
c := ( devices . Celsius ( int8 ( spad [ 1 ] ) ) << 8 + devices . Celsius ( spad [ 0 ] ) ) * 1000 / 16
// The device powers up with a value of 85°C, so if we read that odds are very high
// that either no conversion was performed or that the conversion failed due to lack of
// power. This prevents reading a temp of exactly 85°C, but that seems like the right
// tradeoff.
// The device powers up with a value of 85°C, so if we read that odds are
// very high that either no conversion was performed or that the conversion
// failed due to lack of power. This prevents reading a temp of exactly 85°C,
// but that seems like the right tradeoff.
if c == 85000 {
return 0 , busError ( "ds18b20: has not performed a temperature conversion (insufficient pull-up?)" )
}