tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/thermistor/thermistor.go (about)

     1  // Package thermistor is for temperature sensing using a thermistor
     2  // such as the NTC 3950.
     3  //
     4  // Datasheet: https://www.farnell.com/datasheets/33552.pdf
     5  //
     6  // This code is an interpretation of Adafruit Thermistor module in Python:
     7  // https://github.com/adafruit/Adafruit_CircuitPython_Thermistor
     8  //
     9  // It uses the Steinhart–Hart equation to calculate the temperature
    10  // based on the resistance:
    11  // https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation
    12  //
    13  // To use with other thermistors adjust the BCoefficient and NominalTemperature
    14  // values to match the specific thermistor you wish to use.
    15  //
    16  //	sensor.NominalTemperature = 25
    17  //	sensor.BCoefficient = 3950
    18  //
    19  // Set the SeriesResistor and NominalResistance based on the microcontroller voltage and
    20  // circuit that you have in use. Set HighSide based on if the thermistor is connected from
    21  // the ADC pin to the powered side (true) or to ground (false).
    22  //
    23  //	sensor.SeriesResistor = 10000
    24  //	sensor.NominalResistance = 10000
    25  //	sensor.HighSide = true
    26  package thermistor // import "tinygo.org/x/drivers/thermistor"
    27  
    28  import (
    29  	"machine"
    30  	"math"
    31  )
    32  
    33  // Device holds the ADC pin and the needed settings for calculating the
    34  // temperature based on the resistance.
    35  type Device struct {
    36  	adc                *machine.ADC
    37  	SeriesResistor     uint32
    38  	NominalResistance  uint32
    39  	NominalTemperature uint32
    40  	BCoefficient       uint32
    41  	HighSide           bool
    42  }
    43  
    44  // New returns a new thermistor driver given an ADC pin.
    45  func New(pin machine.Pin) Device {
    46  	adc := machine.ADC{pin}
    47  	return Device{
    48  		adc:                &adc,
    49  		SeriesResistor:     10000,
    50  		NominalResistance:  10000,
    51  		NominalTemperature: 25,
    52  		BCoefficient:       3950,
    53  		HighSide:           true,
    54  	}
    55  }
    56  
    57  // Configure configures the ADC pin used for the thermistor.
    58  func (d *Device) Configure() {
    59  	d.adc.Configure(machine.ADCConfig{})
    60  }
    61  
    62  // ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
    63  func (d *Device) ReadTemperature() (temperature int32, err error) {
    64  	var reading uint32
    65  	if d.HighSide {
    66  		// Thermistor connected from analog input to high logic level.
    67  		val := d.adc.Get()
    68  		reading = uint32(val) / 64
    69  		reading = (1023 * d.SeriesResistor) / reading
    70  		reading -= d.SeriesResistor
    71  	} else {
    72  		// Thermistor connected from analog input to ground.
    73  		reading = d.SeriesResistor / uint32(65535/d.adc.Get()-1)
    74  	}
    75  
    76  	var steinhart float64
    77  	steinhart = float64(reading) / float64(d.NominalResistance) // (R/Ro)
    78  	steinhart = math.Log(steinhart)                             // ln(R/Ro)
    79  	steinhart /= float64(d.BCoefficient)                        // 1/B * ln(R/Ro)
    80  	steinhart += 1.0 / (float64(d.NominalTemperature) + 273.15) // + (1/To)
    81  	steinhart = 1.0 / steinhart                                 // Invert
    82  	steinhart -= 273.15                                         // convert to C
    83  
    84  	return int32(steinhart * 1000), nil
    85  }