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 }