Nano every as a volt meter calibration issue

Hi, im using the internal 1.1v as reference. I only need that much headroom. Ill be monitoring voltages from .400 to 1v. A battery of mine which tests at .440v shows on the nano every display as .880 so double. When i try and put in scalingFactor 0.5, it halves the 1.1v headroom to .550, therefore any voltage over .550 shows as .550. How can i half the analog but have the 1.1 headroom? Thanks.

The obvious reply is to show your code.

Plz standby. I will share soon. Sorry.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);



const int voltagePins[] = {A0, A1, A2, A3};
float scalingFactor = 0.5;


void setup() {
  // Initialize OLED displays
  display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);

  // Set internal reference voltage to 1.1V
  analogReference(INTERNAL);
}

void loop() {
  displayVoltageReadings();
  delay(500); // Update interval for the readings
}

void displayImage(const uint8_t *imageData, int width, int height) {
  display1.clearDisplay();
  display1.drawBitmap((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2, imageData, width, height, SSD1306_WHITE);
  display1.display();

  display2.clearDisplay();
  display2.drawBitmap((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2, imageData, width, height, SSD1306_WHITE);
  display2.display();
}
void displayVoltageReadings() {
  // Read voltage values from analog pins
  float voltages[4];
  for (int i = 0; i < 4; i++) {
    voltages[i] = analogRead(voltagePins[i]) * 1.1 / 1023.0;
  }

  // Clear displays and set text properties
  display1.clearDisplay();
  display1.setTextSize(4);
  display1.setTextColor(SSD1306_WHITE);

  display2.clearDisplay();
  display2.setTextSize(4);
  display2.setTextColor(SSD1306_WHITE);

  // Calculate vertical positions for centering
  int lineHeight = 8;
  int totalHeight = 2 * lineHeight; // Total height for two lines
  int startY = (SCREEN_HEIGHT - totalHeight) / 2;

  // Display voltage readings on screen 1
  display1.setCursor(0,0);
  display1.print("");
  display1.println(voltages[0], 3);

  display1.setCursor(0,35);
  display1.print("");
  display1.println(voltages[1], 3);
  display1.display();

  // Calculate vertical positions for centering on screen 2
  int startY2 = (SCREEN_HEIGHT - totalHeight) / 2;

  // Display voltage readings on screen 2
  display2.setCursor(0,0);
  display2.print("");
  display2.println(voltages[2], 3);

  display2.setCursor(0,35);
  display2.print("");
  display2.println(voltages[3], 3);
  display2.display();
}

There maybe some hints here…

LINK

LINK

1 Like

Thank you, but i dont understand. Ill have to read it over and over again. I cant comprehend too easily.

At first glance, your code looks ok… it could be tuned up, but the logic looks sound.

Forget the scaling factor.

I’m more interested in how everything is wired together.
Maybe a pen & paper drawing showing everything from left to right.?

1 Like

The ADC output is 10 bits, running from 0 to the reference voltage.
I do not think there is a way to have the low value of the reference voltage be any thing else than 0v. There are no register settings relating to the reference voltage which can do that.

It seems trivial, but can you post the raw readings from the ADC?
Also - check the data sheet - but when you switch from one adc input to another its a good idea to do a dummy read; just read the adc, discard the value and read it again.
As the every is so much faster you may even need a short delay.

I dont see why this should happen, which is why I'd like to see the raw reading

Try changing to analogReference(INTERNAL1V1); in setup().
analogReference(INTERNAL); is the (default) 0.55volt reference on an Every.
Leo..

2 Likes

From analogReference() - Arduino Reference

Arduino megaAVR Boards (Uno WiFi Rev2)

  • DEFAULT: a built-in 0.55V reference
  • INTERNAL: a built-in 0.55V reference <<<<<<<<<<
  • VDD: Vdd of the ATmega4809. 5V on the Uno WiFi Rev2
  • INTERNAL0V55: a built-in 0.55V reference
  • INTERNAL1V1: a built-in 1.1V reference
  • INTERNAL1V5: a built-in 1.5V reference
  • INTERNAL2V5: a built-in 2.5V reference
  • INTERNAL4V3: a built-in 4.3V reference
  • EXTERNAL: the voltage applied to the AREF pin (0 to 5V only) is used as the reference

Versus:

and

1 Like

Batt1----------A0
Batt2----------A1
Batt3----------A2
Batt4----------A3

Oled1 0x3c-------vin/3.3v----gnd/gnd----sdl/A4----scl/A5
Oled 0x3d. Same as above

Im not clear on these directions. Sorry.

Can i change the internal to 2.5? Thatd be awesome.

The Nano Every Sales page Tech Specs points to this datasheet:

...which in turn says it's possible:

Thank you. I canged it. To 1v5 to gain more headroom. I thought 1v1 was the highest. Looks like i can go up more even. Thats why i was getting double the voltage reading. The internal was .55. Thank you very much.

1 Like

Batteries usually have two or more terminals.

A schematic sketch showing ALL your connections would be helpful. ( Not a Fritzy please )

1 Like

Problem solved. Changed default internal .55v to 1v5. I thought the internal was 1v1 .
All batt neg
Go to nano ground.

What is the battery's new or full charged voltage?

1 Like
float vRef = 1.1 //  or whichever you chose
for (int i = 0; i < 4; i++) {
    voltages[i] = analogRead(voltagePins[i]);  //dummy read to allow ADC to settle
    delay(1);  // or more if there is no rush
    voltages[i] = analogRead(voltagePins[i]) * vRef / 1023.0;
  }
1 Like