From d683d03fe802d65a419654451af8945b37949383 Mon Sep 17 00:00:00 2001 From: Leonardo Celente Date: Thu, 17 Mar 2022 20:00:27 -0300 Subject: [PATCH] First release candidate of MAX6682 driver for #8 --- MAX6682/README.md | 39 ++++++++++++++++++++++++++++ MAX6682/max6682.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ MAX6682/max6682.h | 30 +++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 MAX6682/README.md create mode 100644 MAX6682/max6682.c create mode 100644 MAX6682/max6682.h diff --git a/MAX6682/README.md b/MAX6682/README.md new file mode 100644 index 0000000..29a5058 --- /dev/null +++ b/MAX6682/README.md @@ -0,0 +1,39 @@ +# MAX6682 + +## Propósito +Interface externa de termistores. O MAX6682 permite o controle da região de +linearidade da relação entre resistência e temperatura de um termistor. + + +## Exemplo +```c +spi_device_t spi = { .spi = &hspi1, // SPI Handle + .pin = { .port = MAX6682_CS_GPIO_Port, // CS GPIO Port + .pin = MAX6682_CS_Pin }, // CS GPIO Pin + }; + +max6682_t max = { .dev = spi, // + .Rext = 7680 // External Resistance (Rext) + }; + +max6682_init(&max); +result_float result = max6682_measure(&max); +if(result.hasError){ + printf("Invalid Resistance\r\n"); +} +float R = result.value; +printf("Thermistor Resistance: %.f\r\n", R); +``` + +## Documentação + +Para determinar a resistência externa $$R_ext$$ utilize a formula do datasheet + +![relação datasheet](https://i.imgur.com/9JAlXYt.png) + +Por último o parãmetro da resistência de calibração é a resistência +anunciada pelo termistor, isto é, a sua resistência esperada para temperatura +de 25°C. + +## Notas +Não esqueça de ativar printf com floats antes de rodar o exemplo. diff --git a/MAX6682/max6682.c b/MAX6682/max6682.c new file mode 100644 index 0000000..1806e51 --- /dev/null +++ b/MAX6682/max6682.c @@ -0,0 +1,66 @@ +/* + * thermistor.c + * + * Created on: Mar 17, 2022 + * Author: leocelente + */ + +#include "max6682.h" +#include + +// Vr+, voltage the sensor sets at pin R+, aka Rref +#define V_Rp (1.220f) +// Conversion constants: datasheet Page 4, Temperature Conversion +#define C_1 (0.010404f) +#define C_2 (0.174387f) + +/** + * Read from MAX6682 via SPI + */ +static result_uint16_t read(max6682_t const *max) { + uint8_t raw[2] = { 0 }; + buffer_view_t view_raw = { .data = raw, .size = sizeof(raw) }; + gpio_low(max->dev.pin); + error_t e = spi_receive(max->dev, view_raw); + gpio_high(max->dev.pin); + uint16_t value = (raw[0]) | (raw[1] << 8); + result_uint16_t out = { .hasError = e, .value = value }; + return out; +} + +error_t max6682_init(max6682_t *max) { + if (max->Rext <= 0.f) { + return ERROR; + } +// ... + return SUCCESS; +} + +// Convert raw data from SPI to resistance in Ohms +static result_float convert(max6682_t const *max, uint16_t Dout) { + // voltage drop on Rext + float Vext = V_Rp * ((Dout * C_1)/8 + C_2); + // current passing through both resistors + float Iload = Vext / max->Rext; + // voltage drop in thermistor + float Vth = V_Rp - Vext; + // thermistor resistance + float R = Vth / Iload; + + result_float result = { .value = R, .hasError = 0 }; + if (R <= 0.f || isnan(R) || !isfinite(R)) { + result.hasError = ERROR; + } + return result; +} + +result_float max6682_measure(max6682_t const *max) { + // output is 11 bits long + result_uint16_t result = read(max); + if (result.hasError) { + result_float failed = { .value = 0.f, .hasError = result.hasError }; + return failed; + } + return convert(max, result.value); +} + diff --git a/MAX6682/max6682.h b/MAX6682/max6682.h new file mode 100644 index 0000000..c35d73d --- /dev/null +++ b/MAX6682/max6682.h @@ -0,0 +1,30 @@ +/* + * thermistor.h + * + * Created on: Mar 17, 2022 + * Author: leocelente + */ + +#ifndef INC_MAX6682_H_ +#define INC_MAX6682_H_ +#include "platform/platform.h" + + +typedef struct { + spi_device_t dev; + // Linearizing external resistance + float Rext; +} max6682_t; + +/** + * Validates Rext and device connection + */ +error_t max6682_init(max6682_t * max); + +/** + * Reads SPI output and returns the thermistor resistance + */ +result_float max6682_measure(max6682_t const* max); + + +#endif /* INC_MAX6682_H_ */