Ir ao conteúdo

Arduino Leitura de Tensão na Bateria


Ir à solução Resolvido por .if,

Posts recomendados

Postado

Oi gente, tudo bom?

 

Seguinte, final do ano passado, eu precisei fazer um comedouro automático para meus gatos em casa e precisei de um pouco de ajuda na parte da bateria (especie de nobreak dc) e o circuito para controle de carga da bateria e a bateria, funcionou muito bem e para o fim de ano, como não precisava de algo muito elaborado, me resolveu o problema e meus bixos não morreram de fome.

 

 

 

Agora eu quero dar uma melhorada, colocar um displayzin, enfeitar o bolo, por assim dizer.
A parte do display, não é problema... Mas estou com um pequeno galho bem chatinho de resolver (ao menos pra mim) que é uma medição de tensão da bateria.

O Problema é que a tensão fica oscilando muito... Mas muito mesmo vai de 4.1v pra 8.0v do nada e no multimetro acusa 6.8v quando carregada, nessa oscilação, fica basicamente impossível fazer uma leitura, próxima ao que meu multímetro acusa.

 

Já fiz o ajuste de referência interna para 1.1v e o negocio fica doido na leitura kkkkk
Não é necessário isso pro projeto mas eu gostaria de mostrar essa frescura de % de carga da bateria.

 

Algum de vocês já teve algum problema desse tipo e precisou fazer algum tipo de coisa pra calibrar essa leitura?

Coloquei o código que estou 'refatorando'.

 

O Divisor de tensão que estou usando vindo da bateria e indo ao pino A3 do Nano

image.png.5cae12345bb2f12aabaaa768822e13df.png

 

/**
 * Includes de bibliotecas
 */
#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <Adafruit_GFX.h> //INCLUSÃO DE BIBLIOTECA
#include <Adafruit_SSD1306.h> //INCLUSÃO DE BIBLIOTECA

// Declarações de tipagem
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned int uint;
typedef Adafruit_SSD1306 ADisplay;

// Verifica qual variavel de referência usar.
// Para usar a referência padrão de 5v, remover comentário abaixo.
// #define ANALOG_USE_DEFAULT
#ifndef ANALOG_USE_DEFAULT
#define ANALOG_USE_INTERNAL
#define ANALOG_VREF 1.1
#else
#define ANALOG_VREF 5.0
#endif

// Definições de vref
#define ANALOG_VOUT(PIN) (float(analogRead(PIN)) * ANALOG_VREF / 1023.0)
#define ANALOG_VIN(PIN, R1, R2) (ANALOG_VOUT(PIN) / (R2 / (R1 + R2)))

// Definições de display
#define DISPLAY_ADDR 0x003c
#define DISPLAY_TYPE 0x0004

// Definições do relógio
#define CLOCK_ADDR 0x0068
#define CLOCK_UPDATE_DELAY 300
boolean CLOCK_ERROR = false;
ulong CLOCK_DELAY, CLOCK_LAST_MIN;


// Definições da bateria
#define BATTERY_PIN A3
#define BATTERY_VR1 100000.0
#define BATTERY_VR2 10000.0
#define BATTERY_VIN() ANALOG_VIN(BATTERY_PIN, BATTERY_VR1, BATTERY_VR2)

// Definições da fonte
#define POWER_SUPPLY_PIN 2
#define POWER_SUPPLY_CHECK 2500
bool POWER_SUPPLY_STATE;
ulong POWER_SUPPLY_DELAY;

// Definições de pinos de erro.
#define ERROR_PIN 3

/**
 * Definições de função
 */
static void display_show_clock(void);
static void power_supply_show(void);

// Display que será exibido as informações
ADisplay* lcd;

// Definições globais
bool setup_error = false;

void setup()
{

#ifdef ANALOG_USE_INTERNAL
    // > Define a vref interna para as comparações analógicas
    // Para Uno e Nano, usando este parametro passa a ser de 1.1v
    // > No caso, o analogRead(<PIN>) vai chegar a 1023 quando atingir 1.1v
    //   Necessário ter uma atenção nos divisores de tensão dos pinos.
    analogReference(INTERNAL);
    delay(100);
#endif

    // Define os pinos de entrada
    pinMode(BATTERY_PIN, INPUT);
    pinMode(POWER_SUPPLY_PIN, INPUT);
    pinMode(ERROR_PIN, OUTPUT);
    delay(100);

    // Desativa o pino em caso de ativado anteriormente
    digitalWrite(ERROR_PIN, LOW);
    delay(100);

    // Inicializa o display
    lcd = new ADisplay(DISPLAY_TYPE);
    lcd->begin(SSD1306_SWITCHCAPVCC, DISPLAY_ADDR);
    lcd->setTextColor(WHITE);
    lcd->setTextSize(1);
    lcd->clearDisplay();
    lcd->display();
    delay(100);

    // Informa no display sobre a inicialização...
    lcd->setCursor(0, 0);
    lcd->print("Inicializando...");
    lcd->display();
    delay(250);

    lcd->setCursor(0, 8);
    lcd->print("Relogio... ");
    lcd->display();

    if (RTC.isRunning()) {
        lcd->print("OK");
    } else {
        setup_error = true;
        lcd->print("ERROR");
    }
    lcd->display();
    delay(1000);

    // Limpa o display e faz a inicialização
    // Somente se nenhum erro aconteceu durante a inicialização.
    if (!setup_error) {
        lcd->clearDisplay();
        lcd->display();
    }

    // Zera o delay para o relógio.
    CLOCK_DELAY = 0;
    CLOCK_LAST_MIN = 0;

    // Informa que o power supply não está
    // conectado como inicialização
    POWER_SUPPLY_STATE = false;
    POWER_SUPPLY_DELAY = 0;

    // Mostra no display a hora atual.
    delay(100);
}

void loop()
{
    if (setup_error)
        return;

    display_show_clock();
    power_supply_show();
}

/**
 * Exibe dados da fonte conectada
 */
static void power_supply_show(void)
{
    // Se o delay para uma nova verificação ainda
    // não foi atingido, então, retorna o último estado.
    if (POWER_SUPPLY_DELAY > 0 && (ulong)(millis() - POWER_SUPPLY_DELAY) < POWER_SUPPLY_CHECK)
        return;

    // Limpa o local onde será exibido as informações
    // da fonte/bateria
    lcd->fillRect(96, 0, 31, 8, BLACK);

    // Armazena as informações do delay para a próxima verificação
    POWER_SUPPLY_STATE = digitalRead(POWER_SUPPLY_PIN) == HIGH;
    POWER_SUPPLY_DELAY = millis();

    // Se a fonte estiver presente, então irá exibir um 'icone'
    // de tomada na fonte
    if (POWER_SUPPLY_STATE) {
        lcd->fillRect(104, 3, 8, 2, WHITE);
        lcd->fillRect(112, 1, 6, 6, WHITE);
        lcd->fillRect(118, 2, 4, 1, WHITE);
        lcd->fillRect(118, 5, 4, 1, WHITE);
    } else {
        float batteryVin = BATTERY_VIN();
        lcd->setCursor(96, 0);
        lcd->print(batteryVin);
    }

    // Finaliza as edições na região do display e envia
    // o buffer de saída ao lcd
    lcd->display();
}

/**
 * Faz a verificação do relógio para exibição da hora.
 */
static void display_show_clock(void)
{
    tmElements_t nowTime;

    // Verifica o delay para leitura do relógio
    if (CLOCK_DELAY > 0 && (ulong)(millis() - CLOCK_DELAY) < CLOCK_UPDATE_DELAY)
        return;

    // Leitura realizada com sucesso!
    if (RTC.read(nowTime)) {
        // Verifica se é necessário atualizar o minuto atual
        if (nowTime.Minute != CLOCK_LAST_MIN) {
            char timeClock[16] = "";

            // Atualiza a variavel de horario para exibição
            sprintf(timeClock, "%02d/%02d/%04d %02d:%02d",
                nowTime.Day,
                nowTime.Month,
                1970 + nowTime.Year,
                nowTime.Hour,
                nowTime.Minute);

            // Atualiza o último minuto em memória
            CLOCK_LAST_MIN = nowTime.Minute;

            // Limpa a posição do relógio para escrever na tela a informação
            // do relógio
            lcd->fillRect(0, 0, 96, 8, BLACK);
            lcd->setCursor(0, 0);
            lcd->print(timeClock);
            lcd->display();
        }

        // Atualiza o delay do relógio
        CLOCK_DELAY = millis();
    }
}


 

Desde já agradeço a ajuda =]

  • Curtir 1
  • Membro VIP
  • Solução
Postado
6 horas atrás, Carlos Zanon disse:

O Problema é que a tensão fica oscilando muito... Mas muito mesmo vai de 4.1v pra 8.0v do nada e no multimetro acusa 6.8v quando carregada, nessa oscilação, fica basicamente impossível fazer uma leitura, próxima ao que meu multímetro acusa.

Você deve analisar e resolver este problema primeiro. Nenhum hw ou sw vai conviver com isso com satisfação e segurança. Pode ser mau contato, bateria ruim, fonte ruim, cagadinhas básicas e etc

 

Off - 1/2 on

De curiosidade faça um "osciloscópio" algo como

loop
{
a=analog_read(3);
serial.print (a);
serial.print(";");
}

Depois faça um ctrl-c ctrl-v na tela do terminal, cole num arquivo texto, importe no excel e faça um gráfico qualquer...

Com um pouco de criatividade, talvez dê pra ver ao vivo no terminal. Algo como usar a variável a pra posicionar em y o cursor e imprimindo "H" p.ex. Certa feita fiz isso em C pra um equipamento de pulsação cardíaca...

 

  • Curtir 1
Postado
20 minutos atrás, Isadora Ferraz disse:

Pode ser mau contato, bateria ruim, fonte ruim, cagadinhas básicas e etc

 

Né por nada não, mas estou achando que pode ser minha protoboard.

Vou fazer os testes aqui e volto com um feedback.

 

Obrigado pela ajuda =]

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...