obbo-pl / mcp3x6x-c-lib

C library for MCP3461/2/4(R) and MCP3561/2/4(R) delta-sigma ADC
MIT License
9 stars 0 forks source link

SetGainCalibration causes all values to return 0. #3

Open AbsentBen opened 1 week ago

AbsentBen commented 1 week ago

Hi, obbo thanks for the great library. i have been using it with an ESP32S3 together with an Mikroe ADC click 9 (MCP3564), the MCP3564 is using an reference voltage of 2.048V coming from an MCP1501 which i have included in the spi_mcp3x6x_def.h. I am trying to use the set gain calibration and offset calibration to calibrate the MCP3564. However, whenever i enable the calibration for the SetGainCalibration the readings returns 0V (For AVDD) | -269.13C (For internal temperature).

Would appreciate if you could provide some guidance on this issue.

Screenshot based on the Arduino example provided below.

Wrong reading

The example code and changes i made: /*

include

include "spi_bus_hal.h"

include "spi_mcp3x6x.h"

spi_mcp3x6x_t* adc;

void setup() { Serial.begin(115200); // Init SPI spi_bus_hal_Init(); // Init chip adc = spi_mcp3x6x_Create(); spi_mcp3x6x_Init(adc, SPI_MCP3X6X_VARIANT_MCP3564R, SPI_MCP3X6X_DEVICE_ADDRESS_DEFAULT, spi_bus_hal_ReadReg, spi_bus_hal_WriteReg, true, SPI_BUS_HAL_OK); // Connectivity check if (spi_mcp3x6x_IsConnected(adc)) { printf("MCP3564R is connected. \n"); } else { printf("The MCP3564R is not responding or the chip ID is not correct. \n"); } // Basic setup spi_mcp3x6x_SetClock(adc, SPI_MCP3X6X_CLK_INT); spi_mcp3x6x_SetPrescaler(adc, SPI_MCP3X6X_PRESCALER_DIV2); spi_mcp3x6x_SetVref(adc, SPI_MCP3X6X_VREF_EXT); // Set the Offset Calibrations spi_mcp3x6x_EnableCalibration(adc, true, true); // Enable offset and gain calibration spi_mcp3x6x_SetOffsetCalibration(adc, -0.0308); // Enables Error offset, refer to PG 57 | 5.13 spi_mcp3x6x_SetGainCalibration(adc, 1); // Enable calibration spi_mcp3x6x_EnableAutoZeroingMUX(adc, true); spi_mcp3x6x_EnableAutoZeroingVref(adc, true); // Data conversion setting spi_mcp3x6x_SetOversampling(adc, SPI_MCP3X6X_OSR_49152); spi_mcp3x6x_SetDataFormat(adc, SPI_MCP3X6X_DATA_RIGHT_CHID); spi_mcp3x6x_SetIRQMode(adc, SPI_MCP3X6X_MODE_IRQ_INACTIVE_LH); spi_mcp3x6x_SetConversionMode(adc, SPI_MCP3X6X_CONV_CONTINUOUS); spi_mcp3x6x_SetADCMode(adc, SPI_MCP3X6X_MODE_CONVERSION); // Scan settings spi_mcp3x6x_SetScanDelay(adc, SPI_MCP3X6X_SCAN_DELAY_512); spi_mcp3x6x_SetTimerDelay(adc, 0xFFFFF); spi_mcp3x6x_SetScanSelection(adc, SPI_MCP3X6X_SCAN_AVDD | SPI_MCP3X6X_SCAN_TEMP); }

void loop() { const float vref = (float)SPI_MCP3X6X_EXTERNAL_VREF_MV / 1000; vTaskDelay(50 / portTICK_PERIOD_MS); uint8_t status; spi_mcp3x6x_ReadStatus(adc, &status); if ((status & SPI_MCP3X6X_STATUS_DR_MASK) == 0) { int32_t adc_data = 0; uint8_t ch_id = 0; spi_mcp3x6x_ReadADCData(adc, &adc_data, &ch_id); float value; switch (0x0001 << ch_id) { case SPI_MCP3X6X_SCAN_AVDD: // AVDD transfer function value = 3.0 adc_data vref / (1L << 23); printf("AVDD: %0.4f [V] \n", value); break; case SPI_MCP3X6X_SCAN_TEMP: // Temperature sensor transfer function for MCP3564R value = 0.00040096 adc_data vref - 269.13; printf("Temperature: %0.2f [C] \n", value); break; } } }

obbo-pl commented 6 days ago

Hi AbsentBen, Look at gain calibration and EQUATION 5-8 PG50 (datasheet revision C). The Gain Error Calibration register is an unsigned 24-bit wide. To make the gain calibration equal to 1, enter the value 8388608 (0x800000).