Avançar para o conteúdo principal

Capacímetro controlado por uC

Como medir a capacidade de um condensador usando um micro-controlador?

Os micro-controladores são verdadeiros canivetes suíços. São muito versáteis e para o provar decidi mostrar-vos como é fácil construir um capacímetro usando um micro controlador. Neste exemplo usei um Arduíno nano, mas pode ser usado qualquer micro controlador com duas ou mais saídas digitais e um conversor A/D.
O princípio de funcionamento é simples e baseado na constante de tempo de um circuito RC. Essa constante de tempo denomina-se tau, e é igual ao produto da resistência em ohms pela capacidade em Farads. É o tempo que decorre entre o estabelecimento do circuito e o momento em que a tensão aos terminais do condensador atinge 63,2% da tensão aplicada ao circuito. 

Resultado de imagem para tau capacitors
Fig.1 Circuito RC - Carga de um condensador
Ora se um micro-controlador consegue medir tensões através do seus portos analógicos e dos seus conversores A/D, se também consegue medir tempos através dos seus temporizadores, ou timers se preferir, então basta construir um circuito de carga muito simples, com uma resistência de valor conhecido, a carregar um condensador de valor desconhecido. Mede-se então o tempo que demora o condensador a atingir 63,2% da tensão aplicada ao circuito. Esse valor de tempo é a constante de tempo do circuito RC, conhecida como tau. O valor desse condensador pode ser determinado facilmente pela fórmula C=tau/R. Necessitamos de ter a certeza que o condensador está descarregado no início da medição, descarga essa que é conseguida com uma segunda resistência ligada entre o condensador e um pino de saída do micro-controlador como mostra a figura 2

Fig.2 Circuito de carga e descarga do condensador
Quando se coloca esse pino a zero, igual ao potencial de massa, o condensador descarrega-se através dessa resistência de descarga, cujo valor deve ser calculado para que não se ultrapasse a corrente máxima permitida nesse pino do uC. O condensador está descarregado quando a tensão aos seus terminais é zero, o que pode ser verificado com a mesma entrada analógica do uC que é usada para verificar a tensão no processo de carga. Vamos então ver quais os passos necessários:

Algoritmo do programa de medição da capacidade de um condensador:
  1. Descarregar o condensador;
  2. Colocar o pino de descarga em modo de entrada, para garantir alta impedância e não influenciar o processo de carga.
  3. Inicia o processo de carga, pondo o pino usado para a carga do condensador no nível lógico 1;
  4. Inicia contagem de tempo;
  5. Usando uma porta analógica (ADC) ligada ao condensador, verifica se a tensão aos seus terminais atingiu 63.2 % da tensão aplicada ao circuito de carga. Continua a fazer leituras até atingir esse valor de 63,2% da tensão aplicada.
  6. Quando o condensador atingir 63,2 % da carga, paramos a contagem de tempo e calculamos a diferença entre o tempo actual e o tempo de inicio da carga. Ficamos com a constante de tempo, conhecida como tau.
  7. Como a constante de tempo tau é igual a R * C, então C= tau/R . Ao dividir o tempo de carga em segundos, pela resistência em ohms, ficamos com a capacidade em Farads.
  8. Como a unidade Farad é muito grande, convertemos para uF ou nF, o que for mais conveniente.
  9. apresentamos o valor
  10. Descarregamos o condensador novamente.
Na minha implementação deste algoritmo, acrescentei dois LEDs, um verde outro vermelho, que sinalizam as etapas de carga e descarga do condensador. Não são verdadeiramente necessários, mas podem ser úteis para depuração do programa. Se o programa "encravar" podemos ter uma ideia do ponto onde se encontra o problema.

Vamos então falar um pouco sobre esta implementação do algoritmo:
Nas linhas abaixo, começamos por definir os pinos usados, e associamos nomes para nos facilitar o trabalho. Usamos o porto analógico A0 para medir a tensão no condensador, O porto digital 13 para carregar o condensador e o porto digital 11 para o descarregar. Os portos digitais 3 e 4 são usados para comandar os dois LEDs que assinalam a carga e a descarga do condensador.

#define analogPin      A0
#define chargePin      13
#define dischargePin   11
#define chargeLed      3
#define dischargeLed   4
#define resistorValue  10000.0F

O coração do programa está no cálculo do tau, a constante de tempo. Na função abaixo está o código que nos permite fazer esse cálculo. 

unsigned long chargetime() {  //Carrega o condensador e mede o tempo de carga
  unsigned long elapsedTime, startTime;
  digitalWrite(chargeLed, HIGH);  // sinaliza a carga do condensador
  digitalWrite(chargePin, HIGH);  // Inicia a carga
  startTime = millis();           // Começa a contar o tempo
  while (analogRead(analogPin) < 647) {  // 647 = 63.2% de 1023 
  }
  elapsedTime = millis() - startTime; //calcula o tempo que passou desde o inicio da carga
  digitalWrite(chargeLed, LOW);    // desliga o LED de Carga
  return (elapsedTime); // devolve valor de tau
}

Apresento seguidamente a listagem completa do programa. É uma adaptação do código original que pode ser consultada aqui:

// Baseado no programa original RCTiming_capacitance_meter de Paul Badger 2008
// Adaptado por Luís Sousa 2020

#define analogPin      A0         // analog pin for measuring capacitor voltage
#define chargePin      13         // pin to charge the capacitor - connected to one end of the charging resistor
#define dischargePin   11         // pin to discharge the capacitor
#define chargeLed      3          // pin conected to charge LED
#define dischargeLed   4          // pin conected to charge LED
#define resistorValue  10000.0F   // change this to whatever resistor value you are using
// F formatter tells compliler it's a floating point value

unsigned long ct;
float uF;                // floating point variable to preserve precision, make calculations
float nF;
float pF;

void testLED(int led) {
  digitalWrite(led, HIGH);//lamp test
  delay(500);
  digitalWrite(led, LOW);
  return (0);
}

unsigned long chargetime() {  //Carrega o condensador e mede o tempo de carga
  unsigned long elapsedTime, startTime;
  digitalWrite(chargeLed, HIGH);  // sinaliza a carga do condensador
  digitalWrite(chargePin, HIGH);  // Inicia a carga
  startTime = millis();           // Começa a contar o tempo
  while (analogRead(analogPin) < 647) {     // 647 is 63.2% of 1023, which corresponds to full-scale voltage
  }
  elapsedTime = millis() - startTime;
  digitalWrite(chargeLed, LOW);    // desliga o Led de Carga
  return (elapsedTime);
}

void discharge() {
  /* dicharge the capacitor  */
  digitalWrite(dischargeLed, HIGH);         // sinaliza a descarga
  digitalWrite(chargePin, LOW);             // desliga o pin de carga do condensador
  pinMode(dischargePin, OUTPUT);            //
  digitalWrite(dischargePin, LOW);          // põe pino de descarga a 0V (descarrega)
  while (analogRead(analogPin) > 0) {       // espera ate o condensador estar descarregado (0V)
  }
  digitalWrite(dischargeLed, LOW);         // desliga LED de Descarga
  pinMode(dischargePin, INPUT);            // Poe pino de descarga em alta impedancia
  return 0;
}

void setup() {
  pinMode(chargePin, OUTPUT);     // set chargePin to output
  pinMode(chargeLed, OUTPUT);     // set chargeLed to output
  pinMode(dischargePin, INPUT);   // Poe pino de descarga em alta impedancia
  pinMode(dischargeLed, OUTPUT);  // set dischargeLed to output
  digitalWrite(chargePin, LOW);
  testLED(chargeLed);
  testLED(dischargeLed);
  //testLED(LED_BUILTIN);
  Serial.begin(9600);             
}

void loop() {
  discharge(); //Começa por descarregar o condensador
  ct = chargetime();
  uF = ((float) ct / resistorValue) * 1000; //carrega e mede o tempo de carga
  Serial.print(ct);       // mostra tempo de carga no serial port
  Serial.print(" mS    ");
  if (uF > 1) {
    Serial.print((long)uF);       // mostra o valor no serial port
    Serial.println(" uF");
  }
  else
  {
    // para valores inferiores a 1 microFarad, convertemos para nF (10^-9 Farad).
    // This is  a workaround because Serial.print will not print floats
    nF = uF * 1000.0;      // multiply by 1000 to convert to nF (10^-9 Farads)
    Serial.print((long)nF);         // print the value to serial port
    Serial.println(" nF");          // print units and carriage return
  }
}

Fig. 4 - Apresentação de resultados

As ligações elétricas são muito simples:
  • Liga-se o condensador em teste, entre o Pino A0(+) e a massa(-) ;
  • Liga-se a resistência de carga (10K) entre o pino D13 e A0;
  • Liga-se a resistência de descarga entre o pino D11 e A0;
  • Liga-se o pino D3 ao ânodo do LED Verde;
  • Liga-se o pino D4 ao ânodo do LED Vermelho;
  • Os cátodos dos LEDs ligam à massa através de resistência de 330 ohm
Fig. 3 Circuito montado numa pequena breadboard
Gama de utilização: Com uma resistência de carga de 10K ohm, não devemos confiar nas leituras abaixo de 1uF. Como o tempo mínimo que conseguimos medir com a instrução millis() é 1ms, para medir condensadores mais pequenos, deverá ser usada uma resistência de carga de valor superior (não esquecer de alterar no programa o valor de R). Podemos ainda se for necessário, alterar o programa para fazer as contas em microsegundos usando a instrução micros() e ajustando os cálculos. 
A partir daqui é convosco. Divirtam-se

Comentários

Mensagens populares deste blogue

Apresentação da Placa Freedom FRDM-KL25Z

Olá a todos! O artigo de hoje é dedicado aos adeptos dos micro-controladores e suas plataformas de avaliação e desenvolvimento. Estas placas são úteis para prototipagem rápida de aplicações baseadas em micro-controladores.  Vamos hoje falar da placa Freedom FRDM-KL25Z. Com um custo na ordem dos 20€, esta placa usa um micro-controlador Kinetics da série L, de 32 bits, mais propriamente o KL25Z128VLK, baseado no ARM® Cortex™-M0+. Com uma frequência de relógio que chega aos 48MHz, 128K de flash e muitos portos analógicos, digitais, e PWM. é sem duvida promissora a nível de possibilidades e desempenho.     Fig. 1 - ARM® Cortex®-M0+ MCU 32-Bit Embedded Evaluation Board A forma da placa e do seu pinout, permite usar placas de expansão desenhadas para o Arduino R3, tendo no entanto em atenção que esta placa FRDM-KL25Z trabalha com 3.3V. Devemo-nos portanto assegurar da compatibilidade dos "shields" Arduino com os 3.3V. ...

Assistentes Virtuais

Olá a todos, Hoje vamos falar sobre as assistentes virtuais e a sua real utilidade. Um(a) assistente  virtual é um dispositivo composto por software e hardware, capaz de realizar tarefas para si, ou para qualquer individuo, baseado num comando dado pelo utilizador. Esse comando pode ser dado por texto ou por voz, dependendo do assistente, sendo que alguns aceitam ambos. Os assistentes virtuais têm ganho espaço na vida das pessoas, em vários campos, nomeadamente no auxílio doméstico. Agilizam a obtenção de informações, como a informação meteorológica, aprendem com as interações com o utilizador, melhorando gradualmente a sua performance. Se tiver o equipamento adequado em casa, podem mesmo ligar a TV, controlar a iluminação, subir os estores etc… Os mais interessantes são os/as assistentes virtuais que aceitam comandos de voz e respondem da mesma forma, pois representa uma maior aproximação da máquina ao ser humano, minimizando a necessidade de o homem aprender a li...

Apresentação do Arduino nano

Olá a todos, Hoje vou apresentar-vos o Arduino nano. O Arduino é uma plataforma muito conhecida e uma forma muito interessante de entrar no mundo dos micro-controladores.  Como a sua base de utilizadores é muito grande, existe muito código disponível que é partilhado em sites temáticos como o  https://create.arduino.cc/ Existem também muitas bibliotecas disponíveis o que facilita muito a utilização dos mais variados tipos de sensores, displays, RTC, cartões de memoria etc...  Os fabricantes de hardware fornecem normalmente as bibliotecas que tornam a utilização do seu hardware fácil e acessível ao principiante.  Existem várias placas arduino disponíveis, com preços muito acessíveis, cada uma virada para um tipo de utilização especifica. Para iniciação, o arduino Uno é normalmente a escolha da maioria, pelo que talvez seja o mais conhecido.  Pessoalmente também usei o Uno da primeira vez que contactei com o universo do arduino...