For my application I need an acruate voltage measurement up to 36V.

And I also I want to upload those measurements to a server via WIFI. I've bought a RP2040 with a display for this task:  
To achieve acurate measurements I decided to try the INA226, which you can buy already mounted on a small PCB and has a I2C interface: 
 
The hardware setup is fairly straight forward, I power the INA226 from the RP2040 and connect the SCL (pin 13) and SDA (pin 12) and you are done, and end up with something like this:  
Looking at the PSU:  
And comparing the INA226, the measurement does indeed seem to be very acurate:  
Also a double check measurement with my Fluke shows acurate results:

I used the Arduino IDE to program the RP2040 using this code:


#include <TFT_eSPI.h> //tested with v2.4.78 from https://github.com/Xinyuan-LilyGO/LILYGO-T-display-RP2040 
#include <stdio.h>
#include "pico/stdlib.h"
#include <Arduino.h>
#include "hardware/gpio.h"
#include <Wire.h>
#include <INA226_WE.h>

/* 
#define TFT_MISO -1
#define TFT_MOSI 3
#define TFT_SCLK 2
#define TFT_CS 5  // Chip select control pin
#define TFT_DC 1  // Data Command control pin
#define TFT_RST 0 // Reset pin (could connect to RST pin) */
#define TFT_BL 4
#define PWR_ON 22
#define BOTTON1 6
#define BOTTON2 7
#define RedLED 25
#define BatVol 26
#define I2C_SDA 12
#define I2C_SCL 13
#define I2C_INA_ADDRESS 0x40


#define dark()                   \
  for (int i = 0xff; i > 0; i--) \
  {                              \
    delay(5);                    \
    analogWrite(TFT_BL, i);      \
  }                              \
  digitalWrite(RedLED, !digitalRead(RedLED));

#define light()                  \
  for (int i = 0; i < 0xff; i++) \
  {                              \
    delay(5);                    \
    analogWrite(TFT_BL, i);      \
  }                              \
  digitalWrite(RedLED, !digitalRead(RedLED));

TFT_eSPI tft = TFT_eSPI();

INA226_WE ina = INA226_WE(&Wire);

void setup()
{
  pinMode(PWR_ON, OUTPUT);
  digitalWrite(PWR_ON, 1);
  pinMode(BatVol, INPUT);
  pinMode(TFT_BL, OUTPUT);
  pinMode(RedLED, OUTPUT);
  digitalWrite(TFT_BL, 0);
  analogWrite(TFT_BL, 0);

  Serial.begin(115200);
  tft.init();
  tft.setRotation(1);
  tft.setTextSize(2);
  tft.setSwapBytes(true);
  light();
  Serial.println("Hello Pico");

  Serial.println("I2C init: SDA 12 SCL 13");
  Wire.setSDA(I2C_SDA);
  Wire.setSCL(I2C_SCL);
  Wire.begin();
  delay(500);

  Serial.println("Initialize INA226");
  
  // Default INA226 address is 0x40
  bool success = ina.init();

  // Check if the connection was successful, stop if not
  if(!success)
  {
    Serial.println("Connection error");
    while(1);
  }

  // Configure INA226
  ina.setResistorRange(0.002,20.0);

  ina.waitUntilConversionCompleted();
  Serial.println("-----------------------------------------------");
  tft.fillScreen(TFT_BLACK);
}

void loop()
{

  float shuntVoltage_mV = 0.0;
  float busVoltage_V = 0.0;
  float current_mA = 0.0;
  float power_mW = 0.0; 

  ina.readAndClearFlags();
  shuntVoltage_mV = ina.getShuntVoltage_mV();
  busVoltage_V = ina.getBusVoltage_V();
  current_mA = ina.getCurrent_mA();
  power_mW = ina.getBusPower();
  
  Serial.print("Shunt Voltage [mV]: "); Serial.println(shuntVoltage_mV);
  Serial.print("Bus Voltage [V]: "); Serial.println(busVoltage_V);
  Serial.print("Current[mA]: "); Serial.println(current_mA);
  Serial.print("Bus Power [mW]: "); Serial.println(power_mW);
  if(!ina.overflow){
    Serial.println("Values OK - no overflow");
  }
  else{
    Serial.println("Overflow! Choose higher current range");
  }
  Serial.println();

  tft.fillScreen(TFT_BLACK);
  tft.setCursor(0, 0);
  tft.setTextColor(random(TFT_WHITE));
  tft.print("Voltage [V]: ");
  tft.print(busVoltage_V);
  tft.println();

  tft.print("Current [mA]: ");
  tft.print(current_mA);

  delay(1500);
      }

 

Hope this helps.