Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Arduino Code Problem

Pavi98

Member
Hello there,
I'm a newbie in Arduino, and I tried to make two battery-level indicators to be displayed on an OLED display. Once I uploaded the following Arduino code, it showed two battery level indicators with percentage values. One battery level indicator should only work with the voltage input to the A0 pin, and the other should only work with the A1 pin. the problem is, once I attach either A0 or A1 pin with a voltage level, the expected battery level indicator works fine, but the other battery level indicator also shows some percentage value which should be avoided. What is the reason for this? Is there any issue with the following code? I tried many times to figure out this issue but still no luck.

Thank you for your help.
 

Attachments

  • Dual_battery.ino
    4 KB · Views: 95
Hi, you need to post a listing of the program, please.

Use the "code" option < / > in the three dots menu so it keeps its formatting?
 
Morning

Have a look here .. .. https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

The Arduino ADC will not reference 12vdc .. .. .. .

The warnings at the bottom of the page might help

C:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BATTERY_IN_12V A1
#define BATTERY_IN_3V7 A0
void DrawBattery12V(int y) {
  int value12V = analogRead(BATTERY_IN_12V);
  float voltage12V = (value12V / 1023.0) * 5.0; // Assuming 5.0V as the reference voltage
  int percent12V = 0; // Initialize percentage to 0
 
  // Only calculate the percentage if voltage is detected on A1
  if (voltage12V > 0) {
    percent12V = map(value12V, 0, 1023, 0, 100); // Map the 0-1023 range to 0-100%
  }
 
  int batteryWidth12V = map(percent12V, 0, 100, 2, 20); // Smaller battery size, adjusted
  int batteryOutlineWidth12V = 20;
  int batteryX12V = SCREEN_WIDTH - batteryOutlineWidth12V - 10; // Position from the right
 
  display.drawRect(batteryX12V, y, batteryOutlineWidth12V, 10, SSD1306_WHITE); // Battery outline
 
  // Calculate position for the battery connector icon (close to the battery outline)
  int connectorX12V = batteryX12V - 3; // Adjust for positioning close to the outline
  int connectorY12V = y + 2; // Adjust for positioning close to the outline
 
  display.fillRect(connectorX12V, connectorY12V, 2, 6, SSD1306_WHITE); // Battery connector
  display.fillRect(batteryX12V, y, batteryWidth12V, 10, SSD1306_WHITE); // Fill based on the percentage, within the outline
 
  display.setTextSize(1.4);
  display.setTextColor(SSD1306_WHITE);
 
  // Calculate position for the percentage text (left side of the battery connector, with a gap)
  int percentX12V = batteryX12V - 30; // Adjust for positioning to the left with more gap
  int percentY12V = y + 2; // Adjust for positioning close to the connector
 
  // Only display the percentage value if voltage is detected on A1
  if (voltage12V > 0) {
    display.setCursor(percentX12V, percentY12V);
    display.print(percent12V);
    display.print("%");
  }
}
void DrawBattery3V7(int y) {
  int value3V7 = analogRead(BATTERY_IN_3V7);
  int voltage3V7 = (value3V7 / 1023.0) * 5.0; // Assuming 5.0V as the reference voltage
  int percent3V7 = map(value3V7, 0, 1023, 0, 100); // Map the 0-1023 range to 0-100%
 
  // Check if the voltage is less than 3.7V and set the percentage to 0%
  if (voltage3V7 <= 3.7) {
    percent3V7 = 0;
  }
 
  // Check if the voltage is greater than or equal to 4.2V and set the percentage to 100%
  else if (voltage3V7 >= 4.2) {
    percent3V7 = 100;
  }
 
  int batteryWidth3V7 = map(percent3V7, 0, 100, 2, 20); // Smaller battery size, adjusted
  int batteryOutlineWidth3V7 = 20;
  int batteryX3V7 = SCREEN_WIDTH - batteryOutlineWidth3V7 - 10; // Position from the right
 
  display.drawRect(batteryX3V7, y, batteryOutlineWidth3V7, 10, SSD1306_WHITE); // Battery outline
 
  // Calculate position for the battery connector icon (close to the battery outline)
  int connectorX3V7 = batteryX3V7 - 3; // Adjust for positioning close to the outline
  int connectorY3V7 = y + 2; // Adjust for positioning close to the outline
 
  display.fillRect(connectorX3V7, connectorY3V7, 2, 6, SSD1306_WHITE); // Battery connector
  display.fillRect(batteryX3V7, y, batteryWidth3V7, 10, SSD1306_WHITE); // Fill based on the percentage, within the outline
 
  display.setTextSize(1.4); // Larger text size
  display.setTextColor(SSD1306_WHITE);
 
  // Calculate position for the percentage text (left side of the battery connector, with a gap)
  int percentX3V7 = batteryX3V7 - 30;
  int percentY3V7 = y + 2; // Adjust for positioning close to the connector
 
  display.setCursor(percentX3V7, percentY3V7);
  display.print(percent3V7);
  display.print("%");
}
void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;) ;
  }
}
void loop() {
  display.clearDisplay();
  // Draw the border around the OLED display
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
  DrawBattery12V(5);
  DrawBattery3V7(20);
  display.display();
}


MM
 
Hi, you need to post a listing of the program, please.

Use the "code" option < / > in the three dots menu so it keeps its formatting?
Sorry, I didn't know that. I'll upload the code according to that.
Code:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define BATTERY_IN_12V A1
#define BATTERY_IN_3V7 A0

void DrawBattery12V(int y) {
  int value12V = analogRead(BATTERY_IN_12V);
  float voltage12V = (value12V / 1023.0) * 5.0; // Assuming 5.0V as the reference voltage
  int percent12V = 0; // Initialize percentage to 0
 
  // Only calculate the percentage if voltage is detected on A1
  if (voltage12V > 0) {
    percent12V = map(value12V, 0, 1023, 0, 100); // Map the 0-1023 range to 0-100%
  }
 
  int batteryWidth12V = map(percent12V, 0, 100, 2, 20); // Smaller battery size, adjusted
  int batteryOutlineWidth12V = 20;
  int batteryX12V = SCREEN_WIDTH - batteryOutlineWidth12V - 10; // Position from the right
 
  display.drawRect(batteryX12V, y, batteryOutlineWidth12V, 10, SSD1306_WHITE); // Battery outline
 
  // Calculate position for the battery connector icon (close to the battery outline)
  int connectorX12V = batteryX12V - 3; // Adjust for positioning close to the outline
  int connectorY12V = y + 2; // Adjust for positioning close to the outline
 
  display.fillRect(connectorX12V, connectorY12V, 2, 6, SSD1306_WHITE); // Battery connector
  display.fillRect(batteryX12V, y, batteryWidth12V, 10, SSD1306_WHITE); // Fill based on the percentage, within the outline
 
  display.setTextSize(1.4);
  display.setTextColor(SSD1306_WHITE);
 
  // Calculate position for the percentage text (left side of the battery connector, with a gap)
  int percentX12V = batteryX12V - 30; // Adjust for positioning to the left with more gap
  int percentY12V = y + 2; // Adjust for positioning close to the connector
 
  // Only display the percentage value if voltage is detected on A1
  if (voltage12V > 0) {
    display.setCursor(percentX12V, percentY12V);
    display.print(percent12V);
    display.print("%");
  }
}

void DrawBattery3V7(int y) {
  int value3V7 = analogRead(BATTERY_IN_3V7);
  int voltage3V7 = (value3V7 / 1023.0) * 5.0; // Assuming 5.0V as the reference voltage
  int percent3V7 = map(value3V7, 0, 1023, 0, 100); // Map the 0-1023 range to 0-100%
 
  // Check if the voltage is less than 3.7V and set the percentage to 0%
  if (voltage3V7 <= 3.7) {
    percent3V7 = 0;
  }
 
  // Check if the voltage is greater than or equal to 4.2V and set the percentage to 100%
  else if (voltage3V7 >= 4.2) {
    percent3V7 = 100;
  }
 
  int batteryWidth3V7 = map(percent3V7, 0, 100, 2, 20); // Smaller battery size, adjusted
  int batteryOutlineWidth3V7 = 20;
  int batteryX3V7 = SCREEN_WIDTH - batteryOutlineWidth3V7 - 10; // Position from the right
 
  display.drawRect(batteryX3V7, y, batteryOutlineWidth3V7, 10, SSD1306_WHITE); // Battery outline
 
  // Calculate position for the battery connector icon (close to the battery outline)
  int connectorX3V7 = batteryX3V7 - 3; // Adjust for positioning close to the outline
  int connectorY3V7 = y + 2; // Adjust for positioning close to the outline
 
  display.fillRect(connectorX3V7, connectorY3V7, 2, 6, SSD1306_WHITE); // Battery connector
  display.fillRect(batteryX3V7, y, batteryWidth3V7, 10, SSD1306_WHITE); // Fill based on the percentage, within the outline
 
  display.setTextSize(1.4); // Larger text size
  display.setTextColor(SSD1306_WHITE);
 
  // Calculate position for the percentage text (left side of the battery connector, with a gap)
  int percentX3V7 = batteryX3V7 - 30;
  int percentY3V7 = y + 2; // Adjust for positioning close to the connector
 
  display.setCursor(percentX3V7, percentY3V7);
  display.print(percent3V7);
  display.print("%");
}

void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;) ;
  }
}

void loop() {
  display.clearDisplay();
  // Draw the border around the OLED display
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
  DrawBattery12V(5);
  DrawBattery3V7(20);
  display.display();
}
 
Morning

Have a look here .. .. https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

The Arduino ADC will not reference 12vdc .. .. .. .

The warnings at the bottom of the page might help

C:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BATTERY_IN_12V A1
#define BATTERY_IN_3V7 A0
void DrawBattery12V(int y) {
  int value12V = analogRead(BATTERY_IN_12V);
  float voltage12V = (value12V / 1023.0) * 5.0; // Assuming 5.0V as the reference voltage
  int percent12V = 0; // Initialize percentage to 0
 
  // Only calculate the percentage if voltage is detected on A1
  if (voltage12V > 0) {
    percent12V = map(value12V, 0, 1023, 0, 100); // Map the 0-1023 range to 0-100%
  }
 
  int batteryWidth12V = map(percent12V, 0, 100, 2, 20); // Smaller battery size, adjusted
  int batteryOutlineWidth12V = 20;
  int batteryX12V = SCREEN_WIDTH - batteryOutlineWidth12V - 10; // Position from the right
 
  display.drawRect(batteryX12V, y, batteryOutlineWidth12V, 10, SSD1306_WHITE); // Battery outline
 
  // Calculate position for the battery connector icon (close to the battery outline)
  int connectorX12V = batteryX12V - 3; // Adjust for positioning close to the outline
  int connectorY12V = y + 2; // Adjust for positioning close to the outline
 
  display.fillRect(connectorX12V, connectorY12V, 2, 6, SSD1306_WHITE); // Battery connector
  display.fillRect(batteryX12V, y, batteryWidth12V, 10, SSD1306_WHITE); // Fill based on the percentage, within the outline
 
  display.setTextSize(1.4);
  display.setTextColor(SSD1306_WHITE);
 
  // Calculate position for the percentage text (left side of the battery connector, with a gap)
  int percentX12V = batteryX12V - 30; // Adjust for positioning to the left with more gap
  int percentY12V = y + 2; // Adjust for positioning close to the connector
 
  // Only display the percentage value if voltage is detected on A1
  if (voltage12V > 0) {
    display.setCursor(percentX12V, percentY12V);
    display.print(percent12V);
    display.print("%");
  }
}
void DrawBattery3V7(int y) {
  int value3V7 = analogRead(BATTERY_IN_3V7);
  int voltage3V7 = (value3V7 / 1023.0) * 5.0; // Assuming 5.0V as the reference voltage
  int percent3V7 = map(value3V7, 0, 1023, 0, 100); // Map the 0-1023 range to 0-100%
 
  // Check if the voltage is less than 3.7V and set the percentage to 0%
  if (voltage3V7 <= 3.7) {
    percent3V7 = 0;
  }
 
  // Check if the voltage is greater than or equal to 4.2V and set the percentage to 100%
  else if (voltage3V7 >= 4.2) {
    percent3V7 = 100;
  }
 
  int batteryWidth3V7 = map(percent3V7, 0, 100, 2, 20); // Smaller battery size, adjusted
  int batteryOutlineWidth3V7 = 20;
  int batteryX3V7 = SCREEN_WIDTH - batteryOutlineWidth3V7 - 10; // Position from the right
 
  display.drawRect(batteryX3V7, y, batteryOutlineWidth3V7, 10, SSD1306_WHITE); // Battery outline
 
  // Calculate position for the battery connector icon (close to the battery outline)
  int connectorX3V7 = batteryX3V7 - 3; // Adjust for positioning close to the outline
  int connectorY3V7 = y + 2; // Adjust for positioning close to the outline
 
  display.fillRect(connectorX3V7, connectorY3V7, 2, 6, SSD1306_WHITE); // Battery connector
  display.fillRect(batteryX3V7, y, batteryWidth3V7, 10, SSD1306_WHITE); // Fill based on the percentage, within the outline
 
  display.setTextSize(1.4); // Larger text size
  display.setTextColor(SSD1306_WHITE);
 
  // Calculate position for the percentage text (left side of the battery connector, with a gap)
  int percentX3V7 = batteryX3V7 - 30;
  int percentY3V7 = y + 2; // Adjust for positioning close to the connector
 
  display.setCursor(percentX3V7, percentY3V7);
  display.print(percent3V7);
  display.print("%");
}
void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;) ;
  }
}
void loop() {
  display.clearDisplay();
  // Draw the border around the OLED display
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
  DrawBattery12V(5);
  DrawBattery3V7(20);
  display.display();
}


MM
Both the voltage measurements are based on measuring up to maximum of 5V DC. I don't know why either A0 or A1 inputs shows percentage values for both battery level indicators.
 
As MM says, if the voltage you are trying to measure is higher than the Arduino internal supply or its set ADC reference voltage, you must use resistive dividers to keep the voltage to the device pins win a safe range.

Any voltage above its internal supply can cause permanent damage.

For 12V I'd use a divider around 4:1, eg. 3K9 from 12V and 1K to 0V.
If its a 12V lead acid the voltage may be 15V on charge, so a higher division may be needed.

Likewise 3.7V is too high for a 3.3V core device, that also needs a divider; one that allows up to 4.2V if that is a rechargeable lithium cell? eg. 2:1, 2 x 1K resistors to give a max of 2.1V to the MCU.

If it's eg. a coin cell or primary cell, you would need a rather more complex circuit to measure it without flattening it!
 
As MM says, if the voltage you are trying to measure is higher than the Arduino internal supply or its set ADC reference voltage, you must use resistive dividers to keep the voltage to the device pins win a safe range.

Any voltage above its internal supply can cause permanent damage.

For 12V I'd use a divider around 4:1, eg. 3K9 from 12V and 1K to 0V.
If its a 12V lead acid the voltage may be 15V on charge, so a higher division may be needed.

Likewise 3.7V is too high for a 3.3V core device, that also needs a divider; one that allows up to 4.2V if that is a rechargeable lithium cell? eg. 2:1, 2 x 1K resistors to give a max of 2.1V to the MCU.

If it's eg. a coin cell or primary cell, you would need a rather more complex circuit to measure it without flattening it!
but it is said that the the Analog input pins can read voltage levels between 0V to 5V
 
OK, that is a pure 5V device; not all are - many of the more powerful ones have a 3.3V core voltage.

The other possible problem is the ADC sample & hold being upset by noise??

You should ideally have all unused pins set to output low level so nothing "floats" - can you try that?
 
Just to reinforce what [B]rjenkinsgb[/B] said, when testing no floating pins. Either C coupling or internal S/H at input to A/D is not reset or board/package leakage, when going from one pin to
another with , can cause non sensical readings on a floating pin.

Regards, Dana.
 
Last edited:
Do you have a delay between switching channels to allow the sample and hold capacitor to charge? I would assume analogueRead() would take care of that but it may be worth calling it twice with a 1mS delay between. What are you using value wise in your resistive divider? If the total is too high it can cause problems.
A schematic of what's on either Analogue pin would help.

Mike.
 
The issue can be in your circuit arrangement too. You have not attached any circuit diagram. So, we can't say what is exactly happening. Following are some write-ups that you may find helpful.
 

Latest threads

New Articles From Microcontroller Tips

Back
Top