Monday, January 10, 2011

Volt-Amperímetro com Arduino - Parte 1: Protoboard

Estava procurando algum projeto de um dispositivo real para sair das "blinking leds" dos tutoriais de Arduino e montar um dispositivo que fosse útil de alguma forma. Sempre achei confuso ter que colocar dois voltímetros, além do excesso de fios espalhados, inclusive ja queimei a maioria das escalas de corrente dos meus voltímetros, ao medir corrente e voltagem simultâneamente. Por isso me interessei por um projeto de voltímetro e amperímetro digital, além de ser o companheiro ideal para fontes reguláveis caseiras de testes em bancada.

English version of this article: Arduino Volt-Ammeter - Part 1 - Breadboard.

Esse projeto é baseado no modelo descrito em PIC Volt Ampere Meter. Eu achei o projeto totalmente viável, porém eu precisaria de um gravador PIC e fazer todo código fonte na mão, já que eles optam por não divulgar muitos detalhes do projeto a fim de criar o interesse nas pessoas em adquirir o kit pronto para montagem. Como eu já tinha um Arduino aqui, resolvi aproveitar ele como plataforma de prototipação e de gravação do microcontrolador e escrever eu mesmo o código. Por fim, o que foi realmente aproveitado desse modelo citado foi o uso do resistor shunt para medir a corrente e a idéia de criar um modo de calibração, visto que as resistencias totais do circuito não são totalmente previsíveis mesmo utilizando os resistores de precisão 1%.

A lista de componentes necessários para montar esse projeto na protoboard são:

  • 1 Arduino;
  • 1 Protoboard (não esquecer o jogo de fios para as conexões);
  • 1 Display 1602A (16x2 com luz de fundo);
  • 1 Barra de pinos 1x16 para fixar o dispay;
  • 1 Buzzer;
  • 2 Bornes de 2 pólos cada;
  • 3 Chaves tácteis (botões);
  • 1 Potenciômetro de 10k;
  • 6 Resistores de 10k;
  • 2 Resistores de 100k;
  • 1 Resistor de 100R;
  • 1 Resistor de 10R;
  • 1 Resistor de 0.47R com 5W de potência.

Os componentes deverão ser montados na protoboard da seguinte forma:


Para quem ainda não sabe, o aplicativo utilizado para montar esses esquemas de protoboard é o Fritzing. Ele é gratuito e bastante fácil de usar. Clique aqui para baixar o arquivo do Fritzing de fonte dessa imagem.

A seguir o código fonte para ser gravado no Arduino:

//version
#define NAME "Arduino Ammeter"
#define VERSION "0.9"

//debug flag (avoid enabling. it makes your device slower)
//#define DEBUG

//pins
const int PIN_BACKLIGHT = 7;
const int PIN_BUZZER = 3;
const int PIN_VOLTAGE = 0;
const int PIN_CURRENT = 1;
const int PIN_BUTTON_UP = 6;
const int PIN_BUTTON_SETUP = 5;
const int PIN_BUTTON_DOWN = 4;

// includes
#include <LiquidCrystal.h>
#include <EEPROM.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

//variables
//voltage
int VOLTAGE_CURRENT;
int VOLTAGE_LAST=99999;
unsigned long VOLTAGE_MILLIS;
float VOLTAGE_CALCULATED;
float VOLTAGE_MAP = 50; //default voltage map... calibration needed
//current
int CURRENT_CURRENT;
int CURRENT_LAST=99999;
unsigned long CURRENT_MILLIS;
float CURRENT_CALCULATED;
float CURRENT_MAP = 10; //default current map... calibration needed 
//buttons
boolean BUTTON_PRESSED = false;
unsigned long BUTTON_MILLIS = false;
byte BUTTON_LAST;
boolean SETUP_MODE = false;
byte SETUP_ITEM;
boolean SETUP_DELAYBEEP;
//...
unsigned long MILLIS;
unsigned long SETUP_BLINKMILLIS;
boolean SETUP_BLINKSTATE;

//parameters
const int SENSOR_INTERVAL = 500;
const int BUTTON_HOLDTIME = 2000;
const int SETUP_MAXITEMS = 2;
const int SETUP_BLINKINTERVAL = 300;
const byte EEPROM_VALIDATOR = 73; //random number
const float VOLTAGE_STEP = 0.1;
const float CURRENT_STEP = 0.1;

//configuration
const byte EEPROM_CONFIGADDRESS = 0;
struct config_t
{
  byte Validator;
  /////////////////////
  float VOLTAGE_MAP;
  float CURRENT_MAP;
  /////////////////////
  byte ValidatorX2;
} EEPROM_DATA;

void setup() {
  //configure pins
  pinMode(PIN_BACKLIGHT, OUTPUT);
  pinMode(PIN_BUZZER, OUTPUT);
  pinMode(PIN_VOLTAGE, INPUT);
  pinMode(PIN_CURRENT, INPUT);
  pinMode(PIN_BUTTON_UP, INPUT);
  pinMode(PIN_BUTTON_SETUP, INPUT);
  pinMode(PIN_BUTTON_DOWN, INPUT);

  //set up LCD
  lcd.begin(16, 2);

  //initial message  
  lcd.setCursor(0, 0);
  lcd.print(NAME);
  lcd.setCursor(0, 1);
  lcd.print("Version ");
  lcd.print(VERSION);
  
  //lights up
  digitalWrite(PIN_BACKLIGHT, HIGH);
  
#ifdef DEBUG
  delay(2000);
  lcd.setCursor(0, 1);
  lcd.print("Debug enabled!  ");
  lcd.print(VERSION);

  Serial.begin(9600);
  Serial.println("============================");
  Serial.println(NAME);
  Serial.println("Version ");
  Serial.println(VERSION);
  Serial.println("============================");
  Serial.println("Debug messages:");
  Serial.println("----------------------------");
#endif
  
  //try to load the configuration
  loadConfiguration();

  //show initial message for a while then clear and beep
  delay(2000);
  lcd.clear();
  showLabels();
  
  //beep
  beepStart();
}

void loop() {
  processButtons();
  
  MILLIS = millis();

  if ( (MILLIS - VOLTAGE_MILLIS) >= SENSOR_INTERVAL )
  {
    readVoltage();
    
    if (!SETUP_MODE || SETUP_ITEM!=1) {
      showVoltage();
    }

    VOLTAGE_MILLIS = MILLIS;
  }

  if ( (MILLIS - CURRENT_MILLIS) >= SENSOR_INTERVAL )
  {
    readCurrent();
    
    if (!SETUP_MODE || SETUP_ITEM!=2) {
      showCURRENT();
    }

    CURRENT_MILLIS = MILLIS;
  }

  if (SETUP_MODE)
  {
    if ( (MILLIS - SETUP_BLINKMILLIS) >= SETUP_BLINKINTERVAL )
    {
      if (SETUP_BLINKSTATE)
      {
        if (SETUP_ITEM==1)
          showVoltage();
        else if (SETUP_ITEM==2)
          showCURRENT();
        
        SETUP_BLINKSTATE = false;
      } else {
        if (SETUP_ITEM==1)
          hideVoltage();
        else if (SETUP_ITEM==2)
          hideCURRENT();        
        
        SETUP_BLINKSTATE = true;
      }
      
      SETUP_BLINKMILLIS = MILLIS;
    }
  }
}

void processButtons()
{
  if (digitalRead(PIN_BUTTON_UP) == HIGH)
  {
    if (!BUTTON_PRESSED)
    {
#ifdef DEBUG  
      showDebug("Pressed UP");
#endif

      BUTTON_LAST = PIN_BUTTON_UP;
      BUTTON_PRESSED = true;
    }
  }
  else if (digitalRead(PIN_BUTTON_SETUP) == HIGH)
  {
    if (!BUTTON_PRESSED)
    {
#ifdef DEBUG  
      showDebug("Pressed SETUP");
#endif
      
      beepButton();
      BUTTON_LAST = PIN_BUTTON_SETUP;
      BUTTON_MILLIS = millis();
      BUTTON_PRESSED = true;
      SETUP_DELAYBEEP = false;
    } else {
      if ((millis() - BUTTON_MILLIS) > BUTTON_HOLDTIME)
        if (!SETUP_DELAYBEEP)
        {
          beepButton();
          SETUP_DELAYBEEP = true;
        }
      
    }
  }
  else if (digitalRead(PIN_BUTTON_DOWN) == HIGH)
  {
    if (!BUTTON_PRESSED)
    {
#ifdef DEBUG  
      showDebug("Pressed DOWN");
#endif 
      
      BUTTON_LAST = PIN_BUTTON_DOWN;
      BUTTON_PRESSED = true;

    }
  }
  else 
  {
    if (BUTTON_PRESSED) {
      if (BUTTON_LAST == PIN_BUTTON_SETUP)
      {
#ifdef DEBUG  
        showDebug("Released SETUP");
#endif
        
        if (!SETUP_MODE && (millis() - BUTTON_MILLIS) > BUTTON_HOLDTIME) {
#ifdef DEBUG  
          showDebug("Entered setup mode!");
#endif
          
          lcd.setCursor(0, 1);
          lcd.print("   Setup Mode   ");
          SETUP_MODE = true;
          SETUP_ITEM = 1;
        } 
        else {
          if (SETUP_ITEM == SETUP_MAXITEMS) {
#ifdef DEBUG  
          showDebug("Exited setup mode!");
#endif
            
            showLabels();
            SETUP_MODE = false;
            SETUP_ITEM = 0;
            saveConfiguration();
          } 
          else {
            SETUP_ITEM++;
          }
          
          showVoltage();
          showCURRENT();
        }
      } 
      else if (BUTTON_LAST == PIN_BUTTON_UP) {
#ifdef DEBUG  
        showDebug("Released UP");
#endif
        
        if (SETUP_MODE) {
          beepButton();
          
          if (SETUP_ITEM==1) { //voltage
            VOLTAGE_MAP+=VOLTAGE_STEP;
            readVoltage();
            
#ifdef DEBUG  
            startDebug("New VOLTAGE_MAP: ");
            Serial.println(VOLTAGE_MAP,6);
#endif
          } else if (SETUP_ITEM==2) { //current
            CURRENT_MAP+=CURRENT_STEP;
            readCurrent();
            
#ifdef DEBUG  
            startDebug("New CURRENT_MAP: ");
            Serial.println(CURRENT_MAP,6);
#endif
          }
        }
      } 
      else if (BUTTON_LAST == PIN_BUTTON_DOWN) {
#ifdef DEBUG  
        showDebug("Released DOWN");
#endif
        
        if (SETUP_MODE) {
          beepButton();
          
          if (SETUP_ITEM==1) { //voltage
            VOLTAGE_MAP-=VOLTAGE_STEP;
            readVoltage();
            
#ifdef DEBUG  
            startDebug("New VOLTAGE_MAP: ");
            Serial.println(VOLTAGE_MAP,6);
#endif
          } else if (SETUP_ITEM==2) { //current
            CURRENT_MAP-=CURRENT_STEP;
            readCurrent();
            
#ifdef DEBUG  
            startDebug("New CURRENT_MAP: ");
            Serial.println(CURRENT_MAP,6);
#endif
          }
        }
      }

      BUTTON_PRESSED = false;
    }
  }
}

#ifdef DEBUG  
void showDebug(char* Message)
{
  Serial.print(millis());
  Serial.print(": ");
  Serial.println(Message);
}

void startDebug(char* Message)
{
  Serial.print(millis());
  Serial.print(": ");
  Serial.print(Message);
}
#endif

void showLabels()
{
  lcd.setCursor(0, 1);
  lcd.print("Volts       Amps");
}

void showVoltage()
{
    lcd.setCursor(0, 0);
    lcd.print(VOLTAGE_CALCULATED, 2);
    lcd.print(" V");

    if (VOLTAGE_CALCULATED<10)
      lcd.print(" ");
}

void hideVoltage()
{
    lcd.setCursor(0, 0);
    lcd.print("       ");
}

void showCURRENT()
{
    lcd.setCursor(9, 0);

    if (CURRENT_CALCULATED<10)
      lcd.print(" ");

    lcd.print(CURRENT_CALCULATED, 2);
    lcd.print(" A");
}

void hideCURRENT()
{
    lcd.setCursor(9, 0);
    lcd.print("       ");
}

void beepStart()
{
  for (int i=0; i<300; i++) {
    digitalWrite(PIN_BUZZER, HIGH);
    delayMicroseconds(200);
    digitalWrite(PIN_BUZZER, LOW);
    delayMicroseconds(200);
  } 
}

void beepButton()
{
  for (int i=0; i<20; i++) {
    digitalWrite(PIN_BUZZER, HIGH);
    delayMicroseconds(700);
    digitalWrite(PIN_BUZZER, LOW);
    delayMicroseconds(700);
  } 
}

void readVoltage()
{
  VOLTAGE_CURRENT = analogRead(PIN_VOLTAGE);
  if ( VOLTAGE_CURRENT != VOLTAGE_LAST || SETUP_MODE ) {
    VOLTAGE_LAST = VOLTAGE_CURRENT;
    VOLTAGE_CALCULATED = fmap(VOLTAGE_CURRENT, 0, 1023, 0.0, VOLTAGE_MAP);
    
#ifdef DEBUG  
    if (!SETUP_MODE)
    {
      startDebug("New voltage: ");
      Serial.print(VOLTAGE_CALCULATED);
      Serial.println("V");
    }
#endif
  }
}

void readCurrent()
{
  CURRENT_CURRENT = analogRead(PIN_CURRENT);
  if ( CURRENT_CURRENT != CURRENT_LAST || SETUP_MODE ) {
    CURRENT_LAST = CURRENT_CURRENT;
    CURRENT_CALCULATED = fmap(CURRENT_CURRENT, 0, 1023, 0.0, CURRENT_MAP);
    
#ifdef DEBUG
    if (!SETUP_MODE)
    {
      startDebug("New current: ");
      Serial.print(CURRENT_CALCULATED);
      Serial.println("A");
    }
#endif
  }
}


float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

int EEPROM_writeConf()
{
    byte Address = EEPROM_CONFIGADDRESS;
  
    const byte* p = (const byte*)(const void*)&EEPROM_DATA;
    int i;
    for (i = 0; i < sizeof(EEPROM_DATA); i++)
      EEPROM.write(Address++, *p++);
    return i;
}

int EEPROM_readConf()
{
    byte Address = EEPROM_CONFIGADDRESS;
  
    byte* p = (byte*)(void*)&EEPROM_DATA;
    int i;
    for (i = 0; i < sizeof(EEPROM_DATA); i++)
      *p++ = EEPROM.read(Address++);
    return i;
}

void loadConfiguration()
{
  //read data from eeprom
  EEPROM_readConf();
  
  //verify validators
  if (EEPROM_DATA.Validator == EEPROM_VALIDATOR && EEPROM_DATA.ValidatorX2 == EEPROM_VALIDATOR*2)
  {
    //copy data
    VOLTAGE_MAP = EEPROM_DATA.VOLTAGE_MAP;
    CURRENT_MAP = EEPROM_DATA.CURRENT_MAP;

#ifdef DEBUG
    showDebug("Configuration loaded from EEPROM!");
    startDebug("   VOLTAGE_MAP: ");
    Serial.println(VOLTAGE_MAP,6);
    startDebug("   CURRENT_MAP: ");
    Serial.println(CURRENT_MAP,6);
#endif
  } else {
#ifdef DEBUG
    showDebug("Configuration NOT loaded from EEPROM!");
#endif    
  }
}

void saveConfiguration()
{
  if ( EEPROM_DATA.VOLTAGE_MAP != VOLTAGE_MAP ||
       EEPROM_DATA.CURRENT_MAP != CURRENT_MAP
  ) {
    //copy validators
    EEPROM_DATA.Validator = EEPROM_VALIDATOR;
    EEPROM_DATA.ValidatorX2 = EEPROM_VALIDATOR*2;
  
    //copy data
    EEPROM_DATA.VOLTAGE_MAP = VOLTAGE_MAP;
    EEPROM_DATA.CURRENT_MAP = CURRENT_MAP;
  
    //save data to eeprom
    EEPROM_writeConf();
    
#ifdef DEBUG
    showDebug("Configuration saved!");
#endif
  } else {
#ifdef DEBUG
    showDebug("Configuration not changed!");
#endif 
  }
}

Observe que no início do código existe a definição da constante DEBUG. Descomentando essa linha ativa-se os avisos de eventos que podem ser acompanhados através do Serial Monitor do Arduino. Esse recurso pode ajudar na montagem da protoboard e no debug do código, porém, além de gravar uma imagem bem maior no microcontrolador, também deixará o software considerávelmente mais lento pelo fato da porta serial possuir uma velocidade fixa e consideravelmente baixa. Assim não é recomendado deixar esse recurso ativado desnecessariamente.

Os 3 botões servem para fazer a calibração. O botão central é o de configuração e ativa a calibração se for pressionado durante 2 segundos confirmado por um segundo bip. Durante a codificação eu tive a impressão que ele não calcula direito o tempo, porisso julguei interessante ter um segundo beep para confirmar que se passaram os 2 segundos leve o tempo que levar. Os outros botões da esquerda e da direita são para diminuir e aumentar a calibração respectivamente acompanhado por um bip. A calibração começa pela voltagem, pressionando o botão de configuração novamente alterna para corrente e, acionando-o mais uma vez, salva a configuração na EEPROM voltando para o modo normal.

Veja a continuação desse artigo em: Parte Final: Circuito impresso

75 comments:

  1. You state : debug flag (avoid enabling. it makes your device slower)
    But looking at the code I see you have a low baudrate.
    Change Serial.begin(9600) to Serial.begin(115200) and the debugf statements will be much faster so the decrease in speed is far less.

    Rob Tillaart
    ------------------
    Você afirma: debug (para evitar que lhe torna o dispositivo mais lento.)
    Mas olhando para o código que eu vejo que você tem uma taxa de transmissão baixa.
    Alterar Serial.begin (9600) para Serial.begin (115.200) e as declarações debugf será muito mais rápido para que a diminuição da velocidade é muito menor.
    (Tradução pelo Google)

    ReplyDelete
  2. Thanks for posting, Rob!

    You could try faster speeds in breadboard, but at next part of this article you can see that this device sketch was built to work in your own PCB without any serial or FTDI support. So, don't care about serial line speed, leaving it enabled will be only a waste of resource.

    Use it as you like!

    ReplyDelete
  3. Isso mede Corrente Alternada e Continua?
    Qual é o maximo de tensão que posso medir, com garantia de não danificar meu arduino?

    ReplyDelete
  4. Bruno, tudo bem?! Só mede contínua. A divisão aplicada é de 1/10 e, como o arduino lê de 0v a 5v, o resultado máximo dá 50v com uma precisão de cerca de 0,07v, porém esse resultado pode variar um pouco dependendo da calibração. Eu notei que a calibração também depende um pouco da voltagem que alimenta o circuito, se ela mudar convém recalibrar. A real é que o principal objetivo dele é de trabalhar em conjunto com uma fonte regulável e em um circuito apropriado, ao invés de diretamente no Arduino. Já deu uma olhada no circuito na segunda parte desse artigo?

    ReplyDelete
  5. Não vi onde colocarei as ponteiras para medição.??

    ReplyDelete
  6. A idéia não é usar isso como se fosse um voltímetro comum. A idéia é utilizar como um voltímetro de fonte regulável de bancada onde a energia vai passar por ele. Porisso ele possui dois bornes de dois pólos cada.

    Veja uma foto do dispositivo pronto para ter uma idéia: http://lh6.ggpht.com/_SlXk_jAXNLY/TS5PUAtL76I/AAAAAAAAAI0/LliMkQUB2v8/placa3.JPG

    O restante da construção do projeto está bem descrito em: http://rexpirando.blogspot.com/2011/01/volt-amperimetro-com-arduino-parte.html

    ReplyDelete
    Replies
    1. renato poderia me ajudar a montar, sou novo nesse tipo de circuito...
      me adicione no face luis augusto castro
      ou no gmail
      luisaugustocastro@hotmail.com
      luisaugustocastro@gmail.com

      Delete
  7. Amigo, queria saber apenas como calcular a CORRENTE. Qual o circuito eu usaria pra medir apenas a corrente? Seria algo bem simples nem precisaria de display nem nada. Apenas ler a corrente e imprimir ela no serial monitor do software arduino mesmo. Vlw. eduardo.cprado@gmail.com

    ReplyDelete
  8. Eduardo, você precisa somente da parte do resistor de 0.47 no GROUND do circuito e o de 100 conectado na porta do controlador. Em cima da leitura você pode calcular normalmente usando fmap da mesmo forma que no código acima. Lembrando que se você também retirar a calibração pode não ficar bom.

    ReplyDelete
  9. Vlw Renato. Olha só eu queria particularmente medir apenas a corrente numa maquina de lavar que usa em media 800W de potencia e ligada a 220v. Isso me dara no maximo 3,6 a 4A de corrente. Como que eu faria? Poderia usar a resistencia de 0,47ohm?
    Esse circuito ai ta me confundido ne uma coisa: tem ENTRADA e SAIDA com o borne de 2 terminais, e no video vc apenas conecta a entrada e ele mostra a voltagem. E para saber a corrente eu vi que tem um jack onde ligaria isso?
    E no meu caso que vou usar 220v da tomada que e alternada como faria? Desculpa milhoes de perguntas e o modo de me expressar que tenho certeza que nao fica muito claro.rsrsrs...mais valeu mesmo por tentar ajudar!

    ReplyDelete
  10. Então, ele tem entrada e saída porque para tirar a corrente você precisa de componentes entre a fonte e a carga do circuito, no caso o shunt resistor de 0,47R. A voltagem de fato não precisa disso, porisso ele mostra direto quando você conecta algo na entrada. Isso faz todo sentido, pois ele é um sensor para usar com fonte regulável, a idéia é que voce possa regular a voltagem da fonte antes de ligar qualquer coisa na saída dela.

    Esse resistor é de 5W, você precisará calcular a dissipação total para ver se ele não vai queimar, além de reforçar as trilhas do circuito. De qualquer forma não creio que isso vá funcionar para tensões AC do jeito que está aí. Eu, no seu lugar, procuraria aqueles sensores de corrente não invasivos (ex.: http://www.seeedstudio.com/depot/noninvasive-ac-current-sensor-30a-max-p-519.html?cPath=144_154). Pelo que eu li sobre eles não são difíceis de usar.

    ReplyDelete
  11. Esse voltímetro/amperímetro funciona em tempo real?

    ReplyDelete
  12. Como assim em tempo real? Ele nao é um osciloscópio, se é isso que você quis saber. :P

    ReplyDelete
  13. Excelente post. Gostaria de tirar a mesma duvida acima. Ele consegue mostrar no display a tensão e a corrente ao mesmo tempo? Ex: 24v e 3A. Ou seja ele fazer a leitura da corrente e da tensão?

    ReplyDelete
  14. Diego, mostra sim. Na segunda parte do artigo tem um vídeo que mostra ele funcionando. Olha o link no final do texto: http://rexpirando.blogspot.com/2011/01/volt-amperimetro-com-arduino-parte.html

    Quanto a dúvida acima eu imaginei que ele estava se referindo a um instrumento mais sensível capaz de medir variações em curtíssimos intervalos amostrais, por isso citei o osciloscópio. Sei lá o que o colega quis dizer com "tempo real". :D

    ReplyDelete
  15. Olá Renato, tudo bem?

    Parabéns pelo post, EXCELENTE! Não faz muito tempo que estava cogitando comprar esse circuito direto do Eletronics DIY, mas devido a inflexibilidade deles acabei desistindo.

    Eu tenho duas dúvidas:
    - Qual a amperagem máxima que esse projeto suporta? Estou pensando em usar no meu projeto para medir a corrente consumida, mas ele chega a correntes de picos altas (talvez até 140A em 24v)
    - Qual a real funcionalidade dessa calibração? Não vi o porquê de não ser feita automaticamente.

    Grande abraço e sucesso!

    ReplyDelete
  16. Valeu, Marcos... :D

    Do jeito que está não vai servir para você não. Você provavelmente terá reforçar as trilhas e o resistor shunt. Sem falar que terá que recalcular o resistor que leva o sinal para a porta analógica 2, pois ele só le até 10A como está aí. 140A é uma porrada.

    Quanto a calibração é o seguinte. Não da pra prever as resistências totais do circuito até terminá-lo, mesmo eu tendo utilizado resistores de precisão 1%. Sem falar que um voltímetro daqueles que a gente usa com ponteiras tem várias escalas de normalmente só uma casa decimal no máximo, oferecendo um pequeno range por escala, e ainda assim nota-se alguma diferença nas leituras entre eles. Já esse projeto aí só tem uma escala para calcular um grande range de valores. De qualquer forma se você tiver alguma idéia de como calcular isso sozinho mostra par gente aí.

    Abração ae! :P

    ReplyDelete
  17. Fala Renato!

    Entendi, mas agora eu tenho mais dúvidas! =)

    1 - Dá para limitar essa escala de maneira fácil?
    2 - No meu caso, para usar só como voltímetro não tem problemas a questão da amperagem nem da calibragem, certo?
    - O que eu precisaria apenas para fazer o voltímetro?

    Grande abraço,
    Marcos

    ReplyDelete
  18. Então.., a calibragem vale tanto para o voltímetro como pro amperímetro, pois você tem o divisor que é usado para baixar a voltagem até os limites da porta analógica do controlador. No caso ela mede de 0~5 e o divisor é 1/10, sendo assim ela só lê até 50v. Mudando esses resistores você obtem outras escalas (quanto menor a escala, maior a precisão). Evite resistores de valores muito baixos no divisor, pois vão requerer maior potência, convém calcular (procure no youtube videos de resistores queimando :P).

    Se você conectar a alimentação do seu circuito nos bornes de entrada ele ja lê a tensão e se não tiver nada na saída ele não vai consumir corrente pelo amperímetro e, consequentemente, vai medir zero amperes e não incendiar a 140A. Enfim, dá pra usar.

    ReplyDelete
  19. Olá Renato!
    EXCELENTE post!
    Renato, gostaria de tirar algumas dúvidas com vc. Não entendi direito como foi utilizada as resistências na entrada analógica do Arduino. Eles são utilizadas para aplicar um divisor de tensão e corrente e tornar os valores utilizáveis no Arduino? Vc poderia me explicar essa conexão, pois não ficou muito claro pra mim na figura.
    Outra pergunta, o Arduino tem um conversor AD de resolução de 10 Bits, que varia de 0-1023, por que esses valores não foram utilizados no cálculo da tensão e corrente?

    Grande abraço

    ReplyDelete
  20. Isso, um divisor de voltagem, pois o conversor AD só lê até 5v (ou 0~1023). Esse divisor divide por 10, o que oferece uma escala capaz de medir até 50v.

    A escala 0~1023 foi usada no cálculo sim. Tem um trecho do código, por exemplo, que diz 'VOLTAGE_CALCULATED = fmap(VOLTAGE_CURRENT, 0, 1023, 0.0, VOLTAGE_MAP);'. Olha o "0, 1023" aí! :P

    ReplyDelete
  21. Meu caro primeiro parabéns pelo projeto e desculpe se estou falando alguma besteira , uma pequena dúvida , pelo que entendo vc está fazendo a medição da corrente em função da perda de tensão no resistor shunt , ou seja , vc mede a tensão antes e depois do resistor , faz uma menos a outra e divide pelo valor da resistência , é isso ??
    O arduino da precisão e estabilidade para uma variação tão pequena de tensão ?

    ReplyDelete
  22. Caro, Anonymous. Desculpe a demora, mas o Arduino é sensível a variação de cada 0,005v. :P

    ReplyDelete
  23. sr Renato montei o seu circuito que esta muito bom mas estou com uma duvida em relacao à corrente minina que ele consegue ler , e tambem se possivel alterar a resistencia de 0.47 para 0.1ohm,e tambem uma explicacao ali na entrada e saida porque que montou assim e principalmente a resistencia de 0.47ohm naquele lugar

    muito obrigado

    ReplyDelete
  24. hello, megaupload is closed, can you upload source code other provider

    thanks
    F4AII Jean Charles

    ReplyDelete
  25. Olá Ricado!

    Seguinte o megauplod fechou e eu gostaria muito de baixar o arquivo para fazer o seu projeto aqui em casa, tem como colocar em outro lugar?

    Obrigado!

    ReplyDelete
  26. Proceed on download! The download host is now Google Drive.

    ReplyDelete
  27. Amigo Renato este multimetro vai de 0 ate quantos Volts

    ReplyDelete
  28. Bom dia Renato, gostaria de saber até quantos amperes consigo medi com ele? pq tenho uma fonte que tem uma resistencia bem baixa na saida, pois era shunt para medição analogica do amperimetro, tem como eu adaptar esse medidor nessa fonte?obrigado
    João Luís

    ReplyDelete
    Replies
    1. Pelo software ele mede até 10A com o resistor de 0.47R. Mas lembre-se que isso não tem nada a ver com quanta potência e por quanto tempo o circuito inteiro aguenta transportar. Olha, se você ligar as entradas dos sensores do microcontrolador nos lugares certos da sua fonte, sua ideia deve funcionar. A diferença do shunt você acerta na calibração, sem problemas. De qualquer forma, mesmo usando o resistor de mesmo valor, a calibração também seria necessária, pois, por não ter seleção de escalas, esse dispositivo trabalha com um intervalo de valores muito maior que os voltímetros comuns.

      Delete
  29. ok Renato vlw,
    é uma fonte meio parruda e antiga deve da mais de 30A. vou fazer os teste e ver o quanto ele vai marca.
    vou montar e depois posto resultado.

    obrigado

    ReplyDelete
  30. Boa tarde Renato,
    Com esse seu circuito eu conseguiria ler um sensor que fornece uma corrente de 4 a 20mA? É um sensor de nível de 5metros. Onde 4mA corresponde a zero metros e 20mA a 5metros. O que você pode me ajudar? Obrigado

    ReplyDelete
    Replies
    1. Não tenho experiência em sensores com indicador por corrente. Talvez se você explicar melhor como ele é eu consiga te ajudar.

      Delete
    2. Boa noite,
      Este sensor que estou trabalhando é de profundidade possui dois fios e fornece uma corrente que varia de 4mA até 20mA. Cada sensor é calibrado para uma faixa de leitura, este é de 0m a 5metros. Com uma fonte de 12v e um amperímetro e um balde d'água consigo medir quantos centímetros o sensor está submergindo na água. Fora da água o sensor marca 4mA. A medida vou submergindo o sensor no balde verifico que a corrente vai aumentando pelo amperímetro. Por uma regra de 3 composta faço uma relação e descubro quantos centímetros a sonda foi submersa no balde. Neste caso, 4mA corresponde a 0 metros e 20mA a 5 metros.
      Logo, se pelo seu circuito eu consigo medir a corrente, eu coloco a fórmula e tenho o valor que sonda submergio. O que vc acha?

      Delete
    3. Bom dia, qualquer contato: ernany03@gmail.com.
      Obrigado

      Delete
    4. Ernany, no sensor você tem entrada e saída, ele usa o canal positivo para medir voltagem e o negativo para corrente. Diferente do voltímetro que usa o positivo para tudo, porém não mede as duas coisas ao mesmo tempo.

      Sinceramente eu não creio que vá funcionar como está, entende? A corrente não é fornecida, ela é consumida, e é isso que confunde mais. Creio que se você ligar o polo de "origem" seu sensor no positivo da entrada do volt-amperímetro e o outro no negativo da saída ele possa medir. Ou talvez uma variação disso que você terá que tentar até conseguir. De qualquer forma, mesmo se funcionar, acho que a precisão do volt-amperímetro não seja aceitável para a escala de 1mA para cada 25cm que você está utilizando. A precisão final serial na casa dos 2 metros.

      Corrija minha matemática se eu estiver errado, pois fiz por cima essas contas e de cabeça.

      Delete
    5. Olá Renato, eu tenho um desenho de um esquema de ligação do sensor que eu gostaria de passar para você para que você possa me ajudar mais. Responda no meu e-mail. Obrigado.
      e-mail: ernany03@gmail.com

      Delete
    6. Você pode postar aqui o esquema de ligação do sensor. Derepente alguém já trabalhou com sensores de 4 a 20mA ou tem mais esperiência. Preciso ler a corrente.

      Delete
  31. Boa tarde Renato,
    Não consegui abrir o seu arquivo do Fritzing.
    Obrigado.

    ReplyDelete
    Replies
    1. Tá usando a versão mais nova? Se não me engano até a extensão do arquivo mudou.

      Delete
    2. Sim, a versão mais nova. A extensão parece que é a mesma.

      Delete
    3. Ernany, eu consegui abrir através de uma versão mais velha do Fritzing e converti para uma versão mais atual, porém ele perde o resistor shunt. Acho que terei que refazer esse negócio todo. =/

      Delete
    4. Mandei para vc o circuito na versão nova para vc postar. Precisa revisar e ajustar.

      Delete
  32. Boa tarde, sou novo com o arduino e tentei montar este circuito. O voltímetro funcionou, porém estou tendo problemas com o amperímetro. Gostaria de saber se o shunt resistor é um resistor normal de baixa resistencia, no caso 0,47R ou tem que ser um resistor especial?

    ReplyDelete
    Replies
    1. Esse resistor, por oferecer pouca resistência, acaba por transmitir muita potência, logo ele precisa ter uma capacidade alta, e por isso os 5W. Não é taaaannnnta potência, mas é bem maior que os demais, e você vai notar que ele é bem mais grosso que os "convencionais".

      Delete
  33. Fala Renatão, é o Anderson da Robocore. Áh quanto tempo heim? E aí? Comprou a FastPcb? Tem tecnologia nova na área, DryFilm, mais pratico...rsrsrs... Renato seguinte, cara to com algumas dúvidas no Arduíno. A primeira é a esse comando que vc usou #if def e #endif. Pra que serve? Eu já ví muitos códigos com esse comando, sei que é um if? Mas qual a diferença de um if comum? A outra é não estou conseguindo dividir o programa do Arduíno em .h. Até consegui, mas quando tenho variáveis globais declaradas dentro do programa principal e os arquivos .h precisam usar, dá pau. Será que vc pode me dar um help? Abraços. Anderson

    ReplyDelete
    Replies
    1. Opa! Blz?! Então... Não tenho feito placas mais... Ando sem tempo, a desculpa de sempre... kkkkk

      Esses controles são macros de pré-compilação que determinam o formato do arquivo a ser compilado e não tem efeito em tempo de execução. Eles não vão para o código compilado, por isso você não pode usá-los para testar um valor que vai ser obtido somente quando o programa já estiver rodando. Você também vai ver muito disso em aplicativos opensource que testam qual sistema operacional está rodando ou quais bibliotecas estão disponíveis a fim de determinar quais funções estarão disponíveis para o compilador.

      Essa macro que eu coloquei para ativar o debug foi de propósito porque eu só utilizo isso durante testes em protoboard e não queria que a imagem final de produção tivesse instruções inúteis, o que afetaria a performance e o tamanho do binário, já que eu nem sequer conecto os tx/rx do controlador na placa. Por isso eu só mudo aquele parâmetro e o compilador compila o executável com ou sem as funções de debug.

      Delete
  34. Bom dia! Renato, sou novo no arduino, estou fazendo esse projeto de volt-amper, mas não estou conseguindo baixar no seu google drive o esquema da protoboard, já baixei o fritzing, mas o seu google não consigo acesso, como posso fazer. Grato.

    ReplyDelete
  35. Renato, consegui baixar. Muito obrigado.

    ReplyDelete
  36. montei igualzinho você fez e ao ligar a tensão fica oscilando muito..estou ligando uma fonte 24 v e fica oscilando entre 23,4 até 25.
    Fiz um teste com um multimetro digital e a fonte nao oscila...
    Troquei os resistores por resistores de precisão e mesmo assim oscila...

    ReplyDelete
    Replies
    1. Você não tem curto entre as trilhas? Como você confeccionou a placa?

      Delete
  37. No momento está na protoboard Renato, e todas fontes que ligo na entrada pra fazer o teste fica oscilando muito! não tem nada em curto e está tudo conforme você fez aí em cima..

    Será que quando passar pra placa pare de oscilar? Tudo que tenho aqui é novo e funcionando..ja testei em 3 protoboards e em 2 arduinos...comprei resistores de 1% e mesmo assim continua oscilando

    ReplyDelete
  38. Replies
    1. Não sei o que fazer, Jorge. Eu já tive esse tipo de problema também, mas normalmente era problema nas conexões ou curtos, como eu disse. Desmonta e faz tudo de novo, liga somente o que precisa (sem o som, botões e liga o sensor de corrente somente depois de ter certeza que o de voltagem estiver funcionando) e vai testando gradualmente. Desculpe, mas não existe resposta pronta pra isso.

      Delete
  39. Renato, preciso montar um volt-amperimetro para medir as respectivas corrente e tensão alternadas, tem como adaptar o seu projeto para minha necessidade; como posso fazer isso?. Obrigado.

    ReplyDelete
    Replies
    1. Claro que dá! Você tem que colocar os respectivos sensores nas entradas analógicas conectadas aos fios amarelos e depois ajustar a escala no código fonte levando em consideração os máximos e mínimos e a resolução do conversor A/D do controlador ATMega do Arduino. Assim, tudo que está ligado nos fios amarelos à esquerda saem e você insere seu novo circuito nesses conectores.

      Assim... o novo circuito fica bem diferente desse aí e eu não tenho uma receita de bolo para você sobre isso não. Você terá que pesquisar.

      Delete
  40. Montei aqui na protoboard, funcionou e ficou bem legal, agora montar em uma placa para monitorar o sistema solar aqui.

    ReplyDelete
  41. Hola Renato excelente post, voy a poner en práctica sus ideas para un proyecto escolar . Soy de Ecuador.
    Yo construí el circuito en la protoboard, el problema es que sólo mide el voltaje y la corriente no se mide, la corriente se mantiene en cero. El código de Arduino si funciona para corriente?. Es sensible a pequeñas corrientes?. ¿Cuál es la función del terminal de salida?Por favor, necesito tu ayuda. Quiero hacer el PCB utilizando Arduino .
    -------------------------------------------------------------------------------------------

    Olá Renato excelente post, vou implementar suas idéias para um projeto da escola . Eu sou do Equador .
    Eu construí o circuito na protoboard, o problema é que mede apenas a tensão ea corrente não é medida , a corrente permanece em zero . Código Arduino se ele funciona para corrente???. É sensível a pequenas correntes?. O que é a função do terminal de saída?. Por favor, eu preciso de sua ajuda . Eu quero fazer o PCB usando Arduino.
    (Tradução pelo Google)

    ReplyDelete
    Replies
    1. Maria, para fazer a leitura de corrente você precisa colocar o medidor em série entre o circuito e a fonte de energia, ou seja, precisará conectar algum dispositivo que consuma energia nos terminais de saída. Lembre-se que a corrente é a medida de consumo da energia, sem consumo não há o que medir e ele sempre vai apresentar o valor zero para corrente junto da voltagem da fonte de energia.

      Delete
  42. não é voltagem e sim tensão

    ReplyDelete
    Replies
    1. Colega, confesso que não sou muito fã das traduções que os livros de engenharia faziam quando começaram a vir para o Brasil, mas obrigado de qualquer forma!

      Delete
  43. Eae cara!?!? Eu montei uma fonte de bancada com um display baseado neste seu projeto ai, olha como ficou: https://youtu.be/ait4dEDYu7s muito obrigado!!

    ReplyDelete
    Replies
    1. Ficou bem legal, cara! Na verdade você foi o único que enviou um projeto final pra gente ver com a finalidade real para qual o circuito foi pensado. Show de bola.... :P

      Delete
  44. Una pregunta para que mida intensidad es necesario conectar algún módulo arduino de corriente, porque lo he armado y me da valores inciertos.

    ReplyDelete
    Replies
    1. Você ligou o dispositivo a ser medido em série com o medidor?

      Delete
  45. Parabéns pelo post e paciência para responder a tantas perguntas. Gostaria de deixar algumas considerações.

    1 - A relação de resistência na verdade é 1/11 e não 1/10. A máxima tensão que o dispositivo consegue medir é 55V. Vard= 55/(100+10)*10=5V.

    2- A máxima corrente útil medida no dispositivo se vc levar em consideração a potência dissipada pelo resistor de 0,47R é de 3,2A que vai dar P0,47R= 4,8W. em 10A a potência dissipada seria de 47W o que torraria o resistor.

    3 - Por ultima a posição do divisor de tensão para medir a tensão. Em correntes um pouco mais altas a diferença de tensão medida e aplicada na carga é significativa. Imagina uma carga com 12V e 3,2A, a queda de tensão no shunt será de 1,5V VShunt=3,2A*0,47R=1,5V o dispositivo vai mostrar 12V, mas na carga mesmo terá apenas 10,5V.

    Uma vez mais parabéns pelo projeto e empenho.

    ReplyDelete
    Replies
    1. Excelentes considerações, colega. Muito obrigado!

      Delete
  46. Boa tarde.
    Estou tendo dificuldades em calibrar a corrente a ser medida. Poderia por favor me ajudar.
    preciso de mais informações sobre os resistores.

    Obrigado!

    ReplyDelete
  47. Qual a frequência que ele faz as leituras? Teria como fazer algo na ordem de 100hz e gravar no computador, tanto para V quanto para A no mesmo exato momenti?

    ReplyDelete
  48. Muito bom seus projeto da para usar um arduino nano?

    ReplyDelete
  49. Parabéns pelo projeto Renato, vai ser muito útil pra mim. Abs..

    ReplyDelete
  50. Parabéns Renato seu projeto é muito bem elaborado, vai ser muito útil para mim. Abs..

    ReplyDelete
  51. parabens cara, quero montar ele para minha assistencia, gostaria de saber melhor, ele mede a tensão de entrada ou pelos botoes posso controlar a voltaguem de saida e tambem amps.

    ReplyDelete
  52. Parabéns, projeto muito legal, quero usar ele em uma fonte que vou montar. Eu não manjo programar microcontroladores, mas tenho um arduino uno, alguns atmega8 e pic18f2550 (e gravador para ambos), será que algum desses dois daria pra adaptar no lugar do atmega328 e ficar bom?

    ReplyDelete