Ir ao conteúdo
  • Cadastre-se

Arduino Leitura de Tensão na Bateria


Ir à solução Resolvido por .if,

Posts recomendados

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
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
  • Solução
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
Link para o comentário
Compartilhar em outros sites

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!