mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
1bb1b621c6
Signed-off-by: deadprogram <ron@hybridgroup.com>
86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
// 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 Steinhart–Hart 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"
|
||
)
|
||
|
||
// 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 int32, 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 int32(steinhart * 1000), nil
|
||
}
|