Arquivo de tag arduino

Ricardo Jorge porRicardo Jorge

PROGMEM e os microcontroladores AVR

Neste artigo sobre PROGMEM e os microcontroladores AVR, será abordado o uso de PROGMEM, que é um grande aliado quando necessitamos melhor utilizar a memória RAM de nossos microcontroladores usados em diversos projetos recreativos, IoT, Indústria 4.0 e muito mais.

É importante lembrar que arduino é uma das mais conhecidas e utilizadas plataformas de desenvolvimento / prototipagem de hardware, fazendo dele um excelente representante dos microcontroladores AVR.

Existem outros artigos em nosso Blog falando sobre arduino e alguns de seus usos :

O que é PROGMEN?

A palavra-chave PROGMEM é um modificador de variável, que informa ao compilador para “manter esta variável na memória flash”, ao invés de carregá-la na SRAM.

O PROGMEM é útil para placas arduino que têm SRAM limitada, mas muitos usuários do arduino e até mesmo alguns desenvolvedores de bibliotecas não o usam.

Com certeza, se você estiver desenvolvendo algum sistema IoT ou sensores mais complexos com display LCD, mais cedo ou mais tarde, notará o uso da SRAM em seu projeto.

E logo fará a seguinte pergunta: Porque um sketch de 100 linhas usou grande parte dos preciosos 2.048 bytes de SRAM do arduino Uno?

Arquitetura Harvard versus Von Neumann

Antes de falarmos sobre o que é PROGMEM e o que ele faz, precisamos entender duas arquiteturas básicas no projeto de microprocessadores.

Primeiro precisamos entender que para um programa ser executado em seu computador pessoal (Mac, Windows ou Linux), ele precisará estar armazenado em algum tipo de mídia, como o disco rígido por exemplo.

E que antes que este programa entre em execução, ele será copiado do disco rígido para a memória RAM.

Após o programa ser carregado na memória RAM e entrar em execução, poderá declarar variáveis ​​e estruturas de dados que usarão ainda mais RAM.

Quando você termina de usar o programa, alguns dos dados talvez sejam salvos no disco rígido, mas toda a cópia do programa e de suas variáveis que estavam na RAM, serão liberadas e assim a memória ficará livre para o próximo programa a ser usado.

Considerando a arquitetura de um microprocessador de computador, essa abordagem é denominada de arquitetura de Von Neumann, onde o código e os dados existem no mesmo espaço de endereços na RAM.

A maioria das placas Arduíno usa microcontroladores baseados na arquitetura AVR.

Muitos AVRs têm quantidade limitada de RAM estática (SRAM), mas podem ter mais espaço disponível na memória Flash.

Por exemplo, o arduino Uno tem SRAM de apenas 2.048 bytes e 32.728 bytes de memória Flash.

O AVR é ​​um processador de arquitetura Harvard, amplamente utilizado para projetos de microcontroladores (MCU), em que a memória do programa é separada da memória de dados.

Para MCUs com arquitetura Hardvard, o programa é executado diretamente da memória de programa (memória Flash), mas todas as variáveis ​​e dados são carregados na SRAM.

Muitas das variáveis, como as mensagens a serem exibidas, não precisam ser carregadas na SRAM porque embora sejam definidas como uma variável do tipo string, o conteúdo desta string nunca mudará.

O problema é agravado pelo fato de que a maioria das linguagens de programação, C e C++, não foram projetadas para arquiteturas Harvard, mas sim, para arquitetura Von Neumann como seu computador pessoal, onde código e dados existem no mesmo espaço de endereço.

Através do PROGMEM você pode otimizar o uso da memória RAM em seus projetos.

Arquitetura Harvard pode significar coisas diferentes

O termo “arquitetura Harvard” pode significar coisas diferentes para diferentes processadores ou MCUs: tome os chips ARM como exemplo, eles têm arquitetura de “barramento” Harvard, o que significa que os acessos de código e dados podem acontecer ao mesmo tempo.

No entanto, o espaço de memória é unificado, o que significa que tanto a instrução quanto os dados compartilham o mesmo espaço de memória.

Isso é diferente da arquitetura de memória Harvard usada em MCU baseado em AVR ou outros MCUs de 8 bits, como 8051, Pic, etc, que têm espaços de memória separados para código e dados.

A arquitetura Harvard também pode ser usada para especificar designs de cache.

O cache de nível 1 em processadores ARM são normalmente Harvard, ou seja, cache de código e dados estão separados.

Armazenando dados na área de código

Isso significa que qualquer compilador para um processador de arquitetura Harvard, como o AVR, deve usar outros meios para operar com espaços de endereço separados.

O arduino usa uma variação do compilador GCC para compilar o código em códigos AVR.

O atributo PROGMEM que você vê no arduino veio do avr-libc, que faz parte do conjunto de ferramentas AVR.

A biblioteca avr-libc fornece uma macro simples denominada PROGMEM que é definida como um atributo para dizer ao compilador GCC para fazer algo especial sobre as variáveis ​​que têm o atributo PROGMEM.

A macro PROGMEM é definida no arquivo de cabeçalho do sistema e foi compilada junto com o arduino Core e, portanto, disponível para ser usada por todos os usuários do arduino.

Resumo

Em resumo, as macros e funções usadas para recuperar dados da Área de Código “consomem” código adicional para carregar os dados que estão nesta área.

Isso aumenta um pouco o tamanho do código na memória Flash e usa ciclos adicionais que aumentam um pouco o tempo de execução do programa.

De forma geral, considerando o pouco espaço de SRAM existente no Arduíno Uno (2kB SRAM) ou ATtiny85 (512 bytes SRAM), o benefício de usar PROGMEM freqüentemente supera o aumento no tempo de execução e o uso adicional da memória Flash.


Este artigo foi baseado nesta excelente postagem.


Image by Tiki Shabudin from Pixabay
Ricardo Jorge porRicardo Jorge

Linguagem C dicas sobre programação

No artigo Linguagem C dicas sobre programação será mostrado que algumas opções de programação podem gerar efeitos diferentes do esperado.

Ao longo dos anos de uso e com a experiência adquirida, acabamos definindo nossas formas prediletas de codificação.

Entretanto, em alguns casos é necessário avaliar se o resultado será consistente e principalmente, o que esperamos.

Além disto, algumas formas de codificação melhoram o desempenho do código, permitindo que aquele hardware mais “simples”, possa ser usado em nosso projeto.

A linguagem C é bastante flexível e expressiva; essas são algumas das razões pelas quais ela tem sido bem-sucedida e resiliente à substituição por linguagens “melhores”.

Um exemplo de sua flexibilidade é a possibilidade de escrever uma expressão de várias maneiras que são funcionalmente equivalentes.

Isso permite que o estilo de codificação seja adaptado às necessidades pessoais.

No entanto, há um problema: às vezes, o código aparentemente equivalente tem diferenças sutis.

Isso pode ocorrer no código mais simples e exploraremos algumas possibilidades neste artigo.

É comum para linguagem C, fornecer várias maneiras diferentes de fazer algo, sendo todas equivalentes.

Por exemplo, dado que x é uma variável do tipo integer ( int ), cada uma das seguintes instruções fará exatamente o mesmo trabalho:

x = x + 1;
x += 1;
x++;
++x;

Em todos os casos, 1 será adicionado a x.

A única diferença é que dependendo do compilador, um código ligeiramente melhor poderá ser gerado para as duas últimas opções.

As duas formas de uso do operador ++, produzem o mesmo resultado.

No entanto, se o valor da expressão for usado, o pré-incremento e o pós-incremento são diferentes, assim:

y = x++;   // y terá o valor de x antes do incremento
y = ++x;   // y terá o valor de x após o incremento

Curiosamente, o pós-incremento é um pouco mais “pesado”, pois o armazenamento precisa ser alocado para manter o valor antigo de x.

No entanto, um compilador provavelmente otimizaria isso.

Se o armazenamento for alocado quando o valor da expressão não for usado, siginifica que o compilador usado não é o mais indicado !

Se, em vez de ser um int, x fosse um ponteiro para int, adicionar 1 teria o efeito de adicionar 4 (em uma máquina de 32 bits).

No entanto, às vezes, construções que parecem ser equivalentes têm diferenças muito sutis.

Provavelmente, a coisa mais simples que você pode fazer em qualquer linguagem de programação é atribuir um valor a uma variável.

Neste caso, poderíamos escrever o seguinte em C :

alpha = 99;
beta = 99;
gamma = 99;

Claro, uma forma mais compacta ficaria assim:

alpha = beta = gamma = 99;

Será que estas duas formas descritas são 100% equivalentes ?

Na maioria das vezes, essas duas construções são inteiramente equivalentes, mas existem (pelo menos) quatro situações em que escolher uma ou outra pode fazer a diferença:

Em primeiro lugar, e de forma mais comum, cada variável é separada e talvez um comentário indicando por que ela está definida com esse valor seja apropriado.

Em segundo lugar, é sempre bom escrever código sustentável.

Talvez, em algum momento no futuro, o código precise ser alterado para que todas as três variáveis ​​não sejam definidas com o mesmo valor.

O primeiro formato se presta mais facilmente a modificações.

O terceiro motivo está relacionado a compiladores abaixo do padrão, que podem gerar código como este para a primeira construção:

mov r0, #99
mov alpha, r0
mov r0, #99
mov beta, r0
mov r0, #99
mov gamma, r0

A segunda construção dá a dica de que r0 só precisa ser carregado uma vez.

Novamente, um compilador melhor não precisaria da dica.

Por último, há a questão da ordem de execução.

Na primeira construção, é totalmente claro que alfa será atribuído primeiro e gama por último.

Um compilador interpretará a segunda construção assim:

alpha = (beta = (gamma = 99));

Isso significa que a ordem de atribuição foi invertida.

Será que isso importa?

Na maioria das vezes, não.

Mas se fossem registradores de dispositivos, não variáveis ​​comuns, isso poderia fazer uma grande diferença.

É muito comum que o hardware precise que os valores de configuração sejam carregados em uma sequência precisa.

Portanto, eu diria que as atribuições múltiplas em uma construção de instrução devem ser evitadas.

No geral, embora C seja uma linguagem pequena, pode-se argumentar que ela poderia ser ainda menor, fornecendo menos maneiras de fazer as coisas.

O resultado pode ser um código mais claro e sustentável.

Artigo baseado nesta publicação.

Artigos relacionados

Função switch e a máquina de estado – state machine

arduino – como melhorar a precisão da entrada analógica



Photo by Niclas Illg on Unsplash
Ricardo Jorge porRicardo Jorge

Função switch e a máquina de estado – state machine

A função switch, associada a máquina de estado ( state machine ), simplifica o código e facilita a manutenção, substituindo os vários “IF” aninhados, também conhecido como cascata de “IF”.

Não raro durante o desenvolvimento de um código, é necessário tomar decisões sobre vários eventos para que o fluxo prossiga na direção correta.

A máquina de estado também é conhecida como :

  • finite-state machine (FSM)
  • finite-state automaton (FSA)
  • autômato finito

Porque utilizar a máquina de estado?

Implementar código usando uma máquina de estado é uma técnica de design extremamente útil para resolver problemas complexos de engenharia.

As máquinas de estado dividem o projeto em uma série de etapas, ou o que é chamado de estados no jargão da máquina de estado.

Cada estado executa alguma tarefa estritamente definida.

Os eventos, por outro lado, são os estímulos que fazem com que a máquina de estado se mova, ou transite, entre estados.

Como a máquina de estado opera?

Cada máquina de estado tem o conceito de “estado atual”.

Este é o estado que a máquina de estado ocupa naquele momento.

Em qualquer momento, a máquina de estado pode estar em apenas um único estado.

Cada instância de um estado particular da máquina de estado, pode redefinir o estado inicial, ou o próximo estado.

Entretanto, o estado inicial não é executado imediatamente pela máquina de estado, quando o programa for iniciado.

Somente após receber um evento, a máquina de estado executa uma função que estava associada ao evento.

Desta forma, as várias etapas, ou estados, são executados quando cada evento é recebido e avaliado pela máquina de estado.

Devido a forma de operar da função switch, ela é perfeita para navegação entre os estados de uma máquina de estado.

Imagine criar uma máquina de estado, utilizando “IF” !

Em relação ao uso de “IF”, as principais vantagens da função switch são :

  • Código legível
  • Facilidade de manutenção
  • Facilidade de alteração : inclusão / remoção de opções ( estados )
  • Rapidez na seleção do trecho de código a ser executado

Função switch e a máquina de estado

Abaixo temos um exemplo real da aplicação da função switch usada para determinar a frequência da rede AC.

Posteriormente este código será comentado com mais detalhes, no artigo referente ao Monitor AC.

//
// Calculate frequency
//

  if(freqEnabled)
  {
    freqSampleVAC = sampleVAC - 512;
    switch(freqSM) {
      case 1:
        if(freqSampleVAC < 0) {              // wait for zero to start counting cycles
          freqSM = 2;
        }
      break;
      case 2:
        if(freqSampleVAC >= 0)               // wait for positive cycle
        {
          freqStartTime = micros(); 
          freqSM = 3;
        }
      break;
      case 3:
        if(freqSampleVAC < 0 )               // wait for zero crossing
        {
          freqSM = 4;
        }  
      break;
      case 4:
        if(freqSampleVAC >=0 )                // one cycle is completed
        {
          freqSample++;                   // count number of cycles and wait for another one
          freqSM = 3;
        }
      break;
    }
  
        if(freqSample == ACFreq)          
        {
            acFrequency = 1000000 / ((float)(micros() - freqStartTime) / freqSample);
            freqSample = 0;
            freqSM = 1;
            freqEnabled = false;           // now frequency info can be used
            freq_activity = !freq_activity;
        }
    }


Referência :

Finite-state machine

State Machine Design in C

Artigos relacionados :

arduino – como melhorar a precisão da entrada analógica

Linguagem C dicas sobre programação

IoT – protocolo MQTT – introdução



Image by Arek Socha from Pixabay

Ricardo Jorge porRicardo Jorge

Introdução aos filtros EMI e filtros de linha

Neste artigo introdutório sobre filtros EMI e filtros de linha, também conhecidos como réguas de AC, falaremos um pouco sobre os componentes básicos de cada um deles.

Antes de prosseguirmos é importante mencionar que EMI ( Electromagnetic interference ), também denominada de RFI ( radio-frequency interference ), quando o ruído está na faixa de radio frequencia, é um distúrbio gerado por uma fonte externa que afeta um circuito elétrico por indução eletromagnética, acoplamento eletrostático ou condução.

Electromagnetic interference

Nota : Um dos objetivos deste artigo, é proporcionar um melhor entendimento do projeto do monitor solar e eólico, que possui uma etapa de monitoração AC.

No mercado brasileiro costumamos chamar as réguas de tomadas de filtro de linha.

Alguns produtos até possuem um filtro de linha, ou filtro EMI, enquanto a maioria tem foco em proteção contra algum tipo de surto de tensão e talvez um estágio simples de supressão de ruído.

Os filtros EMI tem por objetivo diminuir as interferências externas, como também evitar que o equipamento eletrônico insira interferências na rede.

Os filtros EMI normalmente são compostos por capacitores e um indutor.

Os capacitores utilizados nos filtros, são classificados como :

  • Capacitor Cx – para filtragem no modo diferencial
  • Capacitor Cy – para filtragem no modo comum

O nível e o tipo de ruído, depende diretamente do tipo de equipamento ( carga ) conectada na rede de energia elétrica.

Em nossas casas, as principais fontes de ruído são os motores dos vários eletrodomésticos, como :

  • geladeira, freezer e frigobar
  • filtros de água / bebedouros com refrigeração
  • liquidificador
  • batedeira
  • aspirador de pó
  • secador de cabelo
  • lava roupa
  • lava louça
  • secadora de roupa

E alguns outros equipamentos, como :

  • computador pessoal
  • adaptadores “power line”
  • televisor
  • no break e estabilizador
  • reatores de alguns tipos de lâmpadas
  • bomba d’água e elevadores em prédios
  • portão da garagem

Infelizmente, muitos dos filtros de linha existentes no mercado, tem um circuito elétrico muito simples, que pouco ajuda com relação aos ruídos.

Em grande parte dos casos, os conhecidos filtros de linha são compostos por apenas um varistor que serve para proteção contra alguns tipos de surtos de tensão.

Um varistor é um componente eletrônico que modifica o valor da sua resistência em função da tensão aplicada sobre seus terminais.

Ou seja, quanto maior a tensão aplicada, menor a resistência do varistor.

Varistor
Ilustração – Varistor

Por vezes encontramos modelos que além do varistor tem também um capacitor Cx, mas é raro que as réguas de tomada tenham indutores e capacitores Cy.

O capacitor Cx ficará ligado entre fase e o neutro ou entre as duas fases, dependendo se você mora em uma região onde a tensão é 127V ou 240V bifásica ou monofásica.

Para que um filtro possa ter um mínimo de eficiência, um capacitor Cx e um indutor deveriam estar presentes em sua construção.

Já os capacitores Cy ficam ligados entre uma das fases e o terra e entre o neutro e o terra, também dependendo se sua instalação é monofásica ou bifásica.

O diagrama elétrico básico para um filtro é similar ao da figura abaixo :

Exemplo de filtro EMI simples
Figura 1 – Filtro AC simples

Existem também, filtros com duplo estágio :

Exemplo de filtro EMI duplo
Figura 2 – Filtro AC duplo

A finalidade destes filtros, é eliminar alguns tipos de ruído na linha AC.

Exemplo de ruído antes e depois do filtro
Figura 3 – Exemplo de ruído e da eficácia do filtro AC

Na figura 3 temos um exemplo de ruído à esquerda, e do sinal após o filtro à direita.

Nem todo tipo de ruído pode ser eliminado através dos filtros mostrados.

Isto ocorre porque os filtros atuam em determinadas faixas de frequência e os ruídos podem ocorrer em diversas frequências diferentes.

Durante o projeto do filtro e portanto do cálculo dos valores dos componentes para Cx, Cy e L1, no caso do filtro simples mostrado na figura 1, precisamos definir a faixa desejada para atuação do filtro.

No caso de filtros duplos, ou de dois ou mais estágios, é possível atuar em mais de uma faixa de frequência e assim ter melhores resultados na eliminação do(s) ruído(s).

Contudo, precisamos ficar atentos para os custos e também para o tamanho final destes filtros.

Dependendo da potência a ser utilizada após o filtro, os indutores poderão ter um tamanho considerável, devido a bitola do fio necessária para passagem da corrente elétrica.

Analisando um caso real

Durante o desenvolvimento e testes do protótipo do monitor para energia solar e eólica, notei uma interferência gerada por um Power Line que tenho.

Para fazer interface do arduino com a rede elétrica, utilizei o módulo ZMPT101B que possui isolação galvânica através de um transformador rebaixador de tensão.

Desta forma, as tensões de 127 V ou 240 V, ficam em níveis tolerados pela entrada analógica.

O módulo ZMPT101B possui também um circuito que faz com o que o zero da rede elétrica, fique no centro da escala da entrada analógica do arduino.

O resultado pode ser visto na figura 4 abaixo.

Sinal AC na porta analógica
Figura 4 – sinal AC sem interferência

Quando o Power Line é ligado, e está em atividade, podemos observar um ruído na entrada analógica. Veja figura 5 abaixo.

Sinal AC na porta analógica - Sem filtro
Figura 5 – ruído existente na linha AC

Na figura 6 podemos ver o sinal, após o filtro ser aplicado.

Sinal AC na porta analógica - Com filtro
Figura 6 – condição após aplicar filtro

O filtro utilizado, é similar ao da figura 7 abaixo.

Exemplo Filtro EMI
figura 7 – Filtro AC proposto

Através deste exemplo prático, podemos comprovar a necessidade e a importância dos filtros EMI, e porque a maioria dos chamados filtros de linha existentes no mercado, não seria capaz de eliminar os ruídos.

Referências :

Line filter

Artigos relacionados :

Multímetro com LoZ e a tensão fantasma

arduino – Monitor para energia solar e eólica – Parte 1

arduino – Monitor para energia solar e eólica – Parte 2

IoT – como aplicar em sua casa?


Ricardo Jorge porRicardo Jorge

arduino – como melhorar a precisão da entrada analógica

Monitorar Diagnosticar e Projetar

Melhorar a precisão da entrada analógica para o arduino e ESP8266 é um tema tratado com certa frequência na Internet.

Neste artigo, abordaremos alguns pontos importantes que farão a diferença em seu projeto.

Será que apenas 10 bits são suficientes ?

Para responder melhor, primeiro é necessário entender o objetivo de nosso projeto.

O que desejamos construir com nosso arduino e / ou ESP8266?

Responder claramente a esta pergunta tem relação direta com o custo e a complexidade do projeto.

Na maioria dos casos, buscamos monitorar algo e não estamos preocupados em desenvolver um sistema de medição de alta precisão.

Monitorar é entender o comportamento de um sistema através de suas métricas básicas “baseline”.

A precisão é mais importante para diagnosticar e projetar.

Todos sabemos que bons instrumentos de medição são caros.

Estes instrumentos compartilham algumas das características listadas abaixo :

  • Fonte de alimentação de qualidade – precisa e estável
  • Componentes discretos com boa qualidade e precisão : capacitores, resitores e indutores
  • Circuitos para compensão da temperatura
  • Planejamento da disposição dos componentes e contorno das trilhas da placa de circuito impresso.
  • Filtros de faixa, conforme a frequência a ser medida
  • Conectores de baixa resistência
  • Cabos e pontas de prova com resistência, capacitância e indutância adequadas para medição a ser feita.
  • Chaves comutadoras de qualidade
  • Isolação quanto a ruídos externos que possam afetar a medição

Como pode ser visto, não é só o ADC ( Analog to Digital Converter – Conversor Analógico Digital ), que torna nosso sistema preciso.

Como melhorar a precisão analógica?

Pouco adianta utilizamos um ADC de 16 bits, se nossa fonte de alimentação tem ruído, ou não entrega uma tensão estável para nosso circuito.

Existe ainda o condicionamento do sinal a ser medido e não podemos esquecer da relação Sinal Ruído, que pode comprometer nossa medição.

O condicionamento é quando conseguimos que o sinal em medição tenha uma amplitude equivalente a entrada analógica e o mais livre possível de ruídos.

Outra forma de condicionar o sinal, é quando utilizamos apenas a faixa de nosso interesse, desprezando a amplititude total possível para a entrada analógica.

Este caso de condionamento por faixa é conhecido como Modo Diferencial.

Vejamos alguns tipos mais comuns de módulos :

MóduloFaixa da Tensão analógica
arduino – UNO ( 5V )0 – 5V
arduino – Pró Mini ( 5V )0 – 5V
arduino – Pró Mini ( 3V3 )0 – 3.3V
ESP82660 – 1V
NodeMCU0 – 3.3V
Tabela 1 – Faixa de operação da entrada analógica de alguns MCU

De fato, para um ADC de 10 bits, a entrada analógica mostra valores inteiros entre 0 e 1023.

Duas observações são fundamentais para entrada analógica :

  • Não suporta valores negativos, podendo danificar o controlador
  • Só pode ser usada para medir tensão

Exemplo : para medir corrente, é necessário transformar os níveis de corrente em níveis de tensão.

Atenção : alguns MCU utilizam a tensão de alimentação como tensão de referência analógica, enquanto outros podem ter tensão de referẽncia externa.

A família arduino baseada em ATmega328 pode utilizar tensão de referência externa, que pode ser diferente da tensão de alimentação, mas nunca maior.

O ESP8266 sempre utiliza a tensão de alimentação para referência analógica.

Em qualquer dos caso, uma fonte de alimentação de qualidade é fundamental para precisão de medição analógica.

Observação : não será raro, percebermos que nosso projeto apresenta comportamento diferente quando alimentado pela USB de um computador e posteriormente por uma fonte externa.

Como a tensão de referência e o ADC interferem na precisão

Faixa analógica ( Volts )Fator de divisão para ADC de 10 bitsPrecisão em mV
0 – 510244,9
0 – 3V310243,2
0 – 110240,1
Tabela 2 – Relação da precisão com a faixa de tensão analógica – ADC de 10 bits

Através da tabela 2, podemos verificar que a tensão de referência tem influência direta na precisão medida pela entrada analógica.

Isto precisa ser levado em consideração em nosso sketch.

Utilizando a tablea 2, podemos verificar que um sistema que opere entre 0 a 5V na entrada analógica, terá 1024 passos de 4,9 mV cada e para 3V3, 1024 passos de 3,2 mV.

Enquanto a quantidade de passos é definida pelo precisão do ADC, o valor de cada passo, depende da tensão de referência usada.

Faixa analógica ( Volts )Fator de divisão para ADC de 12 bitsPrecisão em mVolts
0 – 540961,2
0 – 3V340960,8
0 – 140960,02
Tabela 3 – Relação da precisão com a faixa de tensão analógica – ADC de 12 bits

Supondo que desejamos medir uma tensão que vai de 0 a 100 V, teríamos :

Tensão de entradaValor na entrada analógica para ADC de 10 bits
0 Volts0
10 Volts102 ~103
20 Volts204 ~ 205
25 Volts256
50512
75768
1001023
Tablea 4 – Relação aproximada da tensão de entrada e valor lido – ADC de 10 bits

Tensão de entradaValor na entrada analógica para ADC de 12 bits
0 Volts0
10 Volts409 ~410
20 Volts819 ~ 820
25 Volts1024
502048
753072
1004096
Tablea 5 – Relação aproximada da tensão de entrada e valor lido – ADC de 12 bits

Divisor Resistivo de Tensão

Quando medimos tensão utilizando a entrada analógica, precisamos ter cuidado para :

  • A tensão não ultrapassar o nível máximo da entrada analógica
  • A tensão não pode ser negativa

A tabela 1 mostra os níveis máximos para alguns controladores.

Para evitar que o sinal fique negativo, existem técnicas para posicionar a leitura em zero, no centro da faixa de tensão da entrada analógica.

Isto já foi abrodado em :

arduino – Monitor para energia solar e eólica – Parte 2

Quando a tensão a ser medida é maior do que a permitida pela entrada analógica. utilizamos um divisor resisitivo de tensão.

Figura 1 – Diagrama básico de um divisor resistivo de tensão

Existem sistemas para cálculo online dos resistores e das tensões.

Rapidamente você notará que os valores dos resistores nem sempre estão dentro dos valores encontrados no mercado, ou que você tenha para usar.

Uma opção são os resistores variáveis “trimpots”, de preferência multivoltas, para facilitar o ajuste.

Algumas dicas importantes :

  • No divisor resistivo, sempre use uma combinação de valores que resulte em um Vout abaixo da tensão máxima da entrada analógica.
  • Não utilize valores nem muito baixos nem muito altos para os resistores.
  • Tente utilizar valores entre dezenas de Ohm e abaixo de milhões de Ohm.
  • Utilize resistores de precisão, sempre que possível.

O divisor resistivo de tensão, também influencia na precisão das medidas.

Quando 10 bits não bastam

Caso seja necessário utilizar mais do que 10 bits, temos algums opções.

MóduloBits do DAC
arduino Zero12
arduino DUE12
arduino MKR family12
Tabela 6 – placas arduino com ADC de 12 bits

Temos ainda o ESP32 que também conta com ADC de 12 bits.

Necessita de mais precisão ?

Uma opção é o módulo ADS1115 com ADC de 16 bits, visto abaixo

ADS1115
Figura 2 – Módulo ADS1115

Este módulo possui 4 entradas analógicas, sendo acessado via protocolo I2C.

Utilizar I2C permite que até 4 módulos ADS1115 sejam instalados ou que o barramento I2C seja compartilhado com outros dispositivos, como um display LCD, OLED ou outros sensores.

É sempre bom lembrar que o protocolo I2C tem uma temporização própria para estabelecer o endereçamento, a leitura e a escrita no barramento.

Isto deve ser levado em consideração para calcular a máxima taxa de aquisição analógica de seu projeto.

Entrada analógica usando modo diferencial

ATTiny85
Figura 3 – ATTiny85

Observação : Embora o ATTiny85 tenha um ADC de 10 bits, ele é bastante popular, tem bom custo benefício e seu modo diferencial pode ser uma excelente opção para vários usos.

Assim como o ATTiny85, o ADS1115 permite utilizar o modo diferencial.

Um ADC normalmente mede a tensão do sinal com referência ao terra do circuito.

Já no modo diferencial, uma das entradas é usada como referência e desta maneira temos o valor medido como a diferença entre as duas entradas.

Usando o modo diferencial, temos apenas metade das entradas analógicas disponíveis.

Modo diferencial
Figura 4 – Exemplo do Modo diferencial

Mais detalhes sobre o modo diferencial podem ser vistos neste link da Microchip

O ADS115 e o ATTiny85 tem controle de ganho nas entradas analógicas

  • ADS115 tem PGA com os seguintes valores : 2/3, 1, 2, 4, 8, 16
  • ATTiny85 tem ganho de 1 ou 20, somente no modo diferencial

Artigos relacionados :

arduino – Monitor para energia solar e eólica – Parte 1

Sistemas Off-Grid – Monitorando resultados

Divisor de tensão

Calculadora online para divisor de tensão resisitivo

Atenção : O material usado para referência e as fotos para ilustração, não representam associação com as marcas, patrocíonio, indicação e nem endosso para uso.


Ricardo Jorge porRicardo Jorge

arduino – Monitor para energia solar e eólica – Parte 1

Porque um monitor de energia solar ou eólica?

A resposta é muito simples : desenvolver um monitor para energia solar ou gerador eólico, utilizando arduino, é algo viável e com excelentes resultados práticos.

Após a fase do protótipo, podemos evoluir criando uma placa de circuito impresso, integrando os módulos que serão descritos nesta série de artigos.

Embora o título mencione “arduino”, é possível utilizar ESP8266, NodeMCU, ESP32 e similares.

O interesse no desenvolvimento de um monitor, surgiu pouco após iniciar minhas pesquisas com energia solar, quando percebi que não existiam boas opções para monitorar o sistema que eu havia montado.

Pesquisei na Internet e encontrei os famosos wattímetros AC e os amperímetros DC.

E nenhum deles consegue comunicar com o outro !

Também fica difícil ou talvez até impossível, registar as medições ao longo dos dias, semanas, meses e estações do ano.

Ou seja, ou você fica olhando para o painel, ou nunca saberá o que está acontecendo, ou o que aconteceu.

Decidi criar um monitor mais ambicioso, onde seria possível integrar as medições da etapa AC com as medições da etapa DC.

Como este projeto tem vários detalhes, não seria possível apresentar tudo em um único artigo.

Criarei uma série, onde poderemos avaliar e debater melhor, o que foi feito, e o que poderá ser melhorado.

Iniciaremos pelo módulo DC, que é menos comum de ser encontrado no mercado.

Até mesmo projetos com arduino, são mais comuns para a etapa AC.

Antes de iniciarmos, é necessário entender um pouco mais sobre o próprio arduino e porque algumas opções foram escolhidas, ao longo do desenvovlimento deste projeto.

Vamos aos principais tópicos :

  • Precisão da entrada analógica
  • Medição de corrente – Low-side
  • Medição de corrente – High-side

Precisão da entrada analógica

Tratarei este assunto com mais detalhes em outro artigo, mas farei uma rápida introdução agora.

Já vi inúmeros debates na Internet, sobre a “pouca” precisão que “apenas” 10 bits proporcionam.

Não direi que é a melhor precisão possível, mas na maioria das vezes, e no nosso caso também, é suficiente para atender nossas necessidades.

O grande ponto é que, na maioria das vezes, a faixa sendo medida é menor do que a entrada analógica espera.

Vejamos alguns tipos mais comuns de módulos :

MóduloFaixa da Tensão analógica
arduino – UNO ( 5V )0 – 5V
arduino – Pró Mini ( 5V )0 – 5V
arduino – Pró Mini ( 3V3 )0 – 3.3V
ESP82660 – 1V
NodeMCU0 – 3.3V

Sem entender esta relação, muitas vezes um ADC externo é instalado, ao invés de fazermos o condicionamento do sinal analógico a ser medido.

Medição de corrente – Low-side

Nesta opção, a amostra de corrente é obtida através da ligação de um resistor shunt entre a carga e o ponto negativo ( terra ) do circuito.

Como principal desvantagem podemos citar a interferência da conexão da carga ao terra da alimentação

Como principal vantagem, temos a baixa tensão no modo comum do amplificador de corrente.

Medição de corrente – High-side

Como principal vantagem, temos que a carga sempre estará conectada ao terra da fonte.

Contudo, nesta opção, a tensão no modo comum do amplificador é elevada, podendo dificultar e encarecer a criação do circuito sensor de corrente.

Definições para este projeto :

  • Medição de corrente Low-side através de “shunt”
  • Utilização de amplificador para o sinal de tensão proveniente do “shunt”
  • Sistema de “bias” DC, pois desejamos medições bidirecionais de corrente
    • Usando o “bias” o sinal ficará no centro da faixa analógica
  • Voltímetro DC usando divisor resistivo

Através do modelo proposto, conseguimos medir a corrente entrante e sainte no banco de baterias e saberemos, por exemplo :

  • Tensão de carga
  • Corrente de carga
  • Tempo em flutuação
  • Corrente de descarga

Artigos relacionados :

arduino – Monitor para energia solar e eólica – Parte 2

Introdução aos filtros EMI e filtros de linha

IoT – protocolo MQTT – introdução

Sistemas Off-Grid – Monitorando resultados

Matriz Energética e Elétrica

Medição de corrente Low Side e High Side