Files
drivers/thermistor/thermistor.go
Ayke van Laethem 6763521eff all: introduce a temperature type
This type should be used whenever a sensor (or actuator?) works with a
temperature. For example, this commit changes the signature:

    ReadTemperature() (int32, error)

to the following:

    ReadTemperature() (drivers.Temperature, error)

I believe this is much clearer in intent. It also makes it trivial to
introduce common conversions. For example, there are already Celsius()
and Fahrenheit() methods to convert to the given units, as a floating
point. More units could be added as needed, for example a CelsiusInt().
2021-10-21 23:25:42 +02:00

89 lines
2.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package thermistor is for temperature sensing using a thermistor
// such as the NTC 3950.
//
// Datasheet: https://www.farnell.com/datasheets/33552.pdf
//
// This code is an interpretation of Adafruit Thermistor module in Python:
// https://github.com/adafruit/Adafruit_CircuitPython_Thermistor
//
// It uses the SteinhartHart equation to calculate the temperature
// based on the resistance:
// https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation
//
// To use with other thermistors adjust the BCoefficient and NominalTemperature
// values to match the specific thermistor you wish to use.
//
// sensor.NominalTemperature = 25
// sensor.BCoefficient = 3950
//
// Set the SeriesResistor and NominalResistance based on the microcontroller voltage and
// circuit that you have in use. Set HighSide based on if the thermistor is connected from
// the ADC pin to the powered side (true) or to ground (false).
//
// sensor.SeriesResistor = 10000
// sensor.NominalResistance = 10000
// sensor.HighSide = true
//
package thermistor // import "tinygo.org/x/drivers/thermistor"
import (
"machine"
"math"
"tinygo.org/x/drivers"
)
// Device holds the ADC pin and the needed settings for calculating the
// temperature based on the resistance.
type Device struct {
adc *machine.ADC
SeriesResistor uint32
NominalResistance uint32
NominalTemperature uint32
BCoefficient uint32
HighSide bool
}
// New returns a new thermistor driver given an ADC pin.
func New(pin machine.Pin) Device {
adc := machine.ADC{pin}
return Device{
adc: &adc,
SeriesResistor: 10000,
NominalResistance: 10000,
NominalTemperature: 25,
BCoefficient: 3950,
HighSide: true,
}
}
// Configure configures the ADC pin used for the thermistor.
func (d *Device) Configure() {
d.adc.Configure(machine.ADCConfig{})
}
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
func (d *Device) ReadTemperature() (temperature drivers.Temperature, err error) {
var reading uint32
if d.HighSide {
// Thermistor connected from analog input to high logic level.
val := d.adc.Get()
reading = uint32(val) / 64
reading = (1023 * d.SeriesResistor) / reading
reading -= d.SeriesResistor
} else {
// Thermistor connected from analog input to ground.
reading = d.SeriesResistor / uint32(65535/d.adc.Get()-1)
}
var steinhart float64
steinhart = float64(reading) / float64(d.NominalResistance) // (R/Ro)
steinhart = math.Log(steinhart) // ln(R/Ro)
steinhart /= float64(d.BCoefficient) // 1/B * ln(R/Ro)
steinhart += 1.0 / (float64(d.NominalTemperature) + 273.15) // + (1/To)
steinhart = 1.0 / steinhart // Invert
steinhart -= 273.15 // convert to C
return drivers.Temperature(steinhart * 1000), nil
}