/*
Hoje vamos usar o STM32 Maple Mini para fazer uma leitura de AC, ou seja, pegar o valor RMS da
rede elétrica. Isso é bastante útil para aqueles que querem monitorar a rede elétrica para a
Internet das Coisas. Vamos, então, criar uma aplicação aproveitando a poder computacional do
Maple Mini, aplicar um circuito eletrônico capaz de permitir a aquisição de um sinal 127Vac,
bem como aplicar o cálculo da raiz do valor quadrático médio (RMS) sobre as amostras.
Demonstração
Na nossa montagem de hoje, nós temos o STM32, além do nosso circuito analógico para fazer a
entrada do 110. Para evitar choques, isolamos o resistor que está entrando por 110.
O circuito é bastante sensível. Estou entrando com 110, mas reduzo 168 vezes usando o divisor de
tensão e jogo para dentro do amplificador operacional, o qual tem várias funções.
Temos ainda alguns capacitores opcionais para filtragem da fonte. Caso sua fonte seja de boa
qualidade, não precisa utilizá-los.
A entrada do AD é calculada através do osciloscópio, no qual você vê uma senóide, que não é a
110, mas é bem formada. Outra coisa é que a tensão na nossa rede elétrica não é 110, mas 127
volts. Mas, como estamos passando por um estabilizador, ele ajustará para 115V.
O valor exibido no monitor serial é o calculado em RMS, ou seja, o identificado pelo multímetro
Fluke.
Recursos usados
· jumpers
· Um Maple Mini
· Protoboard
· Um amplificador LM386
· Uma fonte simétrica (+5V e -5V)
· Um trimpot multivoltas 10k (ou potenciômetro)
· Quatro capacitores de 100nF poliester
· 3 resistores 10k
· 4 resistores470k
· 1 resistor 5k6
· 1 Diodo zener 1n4728A
Diagrama de blocos
Este é um circuito que desenvolvi baseado nas especificações que acredito serem mais
interessantes para esta medida, mas há vários outros exemplos na internet.
LM386 – Pinagem
O LM386 possui dois amplificadores para condicionamento ou amplificação de sinal.
AmpOp – Diferencial (subtrator)
AmpOp – Somador Inversor
Maple Mini – Pinagem
Pinos marcados em:
Vermelho >> Tolerantes a 3V3
Verde >> Tolerantes a 5V
Maple Mini – Pinagem – A/D utilizado na captura
Destaco aqui que o pino que eu utilizei é o D11 que, na nomenclatura da STMicroelectronics é o
PA0.
Montagem
Para o nosso circuito, você precisará de uma fonte simétrica, como a que criamos para este
projeto, ou, então, de duas fontes.
Gráfico com os dados obtidos
Cálculo do valor rms
*/
#define leituraTensao D11 //AD CH0 no pino PA0
//valor teórico divisor de tensão = 168.85714285714285714286
const float fatorDivisor = 168.40166345742404792461;
//valor teórico do ganho de amplificação = 1.0
const float fatorAmplificador = 1.0;
//Valor usado na multiplicação da leitura
const float fatorMultiplicacao = fatorDivisor * fatorAmplificador;
//Valor teórico da Tensão de alimentação Vcc = 3.3V
const float Vcc = 3.3;
//valor teórico do offset do amplificador = Vcc / 2.0;
const float offSet = 1.66;
//fator teórico da conversão do AD = 3.3 / 4095.0
const float fatorAD = Vcc / 4095.0;
const int amostras = 71429; //resulta em 1,027 segundos para cada atualização
//const int amostras = 35715; //resulta em 0,514 segundos para cada atualização
float Vrms = 0.0; //armazena o valor rms da tensão
float Vmax = 0.0; //armazena o valor máximo detectado
float Vmin = 10000.0; //armazena o valor mínimo detectado
float Vmed = 0.0; //armazena o valor médio entre Vmáx e Vmín
void setup() {
Serial.begin(1000000); //inicia a porta serial em 1Mbps
pinMode(leituraTensao, INPUT); //ajusta a porta do AD como entrada
delay(500); //aguarda 5s antes de iniciar a coleta. (opcional)
}
void loop() {
int i = 0; //variável para iteração
float leitura = 0.0; //armazena as leituras do AD
Vrms = 0.0; //reinicia a variável Vrms
while (i < amostras) { //inicia um ciclo de amostragem até que i alcance o número de amostras
leitura = analogRead(leituraTensao); //lê a porta analógica
//Serial.println(leitura); //Descomente se quiser ver o sinal bruto do AD
Vrms = Vrms + pow(((leitura * fatorAD) - offSet), 2.0); //calcula a soma dos quadrados das
//tensões lidas
i++; //incrementa o iterador
}
//Aplicando fator de multiplicação para determinar o valor real das tensões
Vrms = (sqrt(Vrms / amostras)) * fatorMultiplicacao;
//detecta se é um valor é máximo
if (Vrms > Vmax) {
Vmax = Vrms;
}
//detecta se é um valor mínimo
if (Vrms < Vmin) {
Vmin = Vrms;
}
//calcula a média dos valores máximo e mínimo atuais
Vmed = (Vmax + Vmin) / 2.0;
//saída formatada para plotter serial IDE Arduino
Serial.print(Vrms, 3);
Serial.print(",");
Serial.print(Vmax, 3);
Serial.print(",");
Serial.print(Vmin, 3);
Serial.print(",");
Serial.println(Vmed, 3);
Serial.println(leitura);
/*
//saída formatada como json
Serial.print("{\"instante(ms)\":");
Serial.print(millis());
Serial.print(",");
Serial.print("\"Vrms(V)\":");
Serial.print(Vrms, 3);
Serial.print(",");
Serial.print("\"Vmax(V)\":");
Serial.print(Vmax, 3);
Serial.print(",");
Serial.print("\"Vmin(V)\":");
Serial.print(Vmin, 3);
Serial.print(",");
Serial.print("\"Vmed(V)\":");
Serial.print(Vmed, 3);
Serial.println("}");
*/
/*
//saída formatada como CSV
Serial.print(millis());
Serial.print(",");
Serial.print(Vrms, 3);
Serial.print(",");
Serial.print(Vmax, 3);
Serial.print(",");
Serial.print(Vmin, 3);
Serial.print(",");
Serial.println(Vmed, 3);
*/
}Loading
st-nucleo-l031k6
st-nucleo-l031k6