Construa um Voltímetro Inteligente com Arduino e Smartphone – Projeto DIY Fácil
Componentes e Materiais
| Arduino UNO | 1 |
| PHPoC WiFi Shield para Arduino | 1 |
| Resistor 100k ohm | 1 |
| Resistor 1M ohm | 1 |
| Jumpers (fios de ligação) | 1 conjunto |
Sobre o Projeto
Demonstração
Se você é novo no Arduino, pode começar com tutoriais para iniciantes.
Como Funciona
Podemos usar uma porta analógica do Arduino para medir tensão. No entanto, a tensão máxima mensurável é 5V.
Para aumentar o intervalo de medição, precisamos usar um divisor de tensão.
Na Teoria
A relação é dada por:
V_medida = (R1 + R2) / R2 × V_entrada
razão = (R1 + R2) / R2
⇒ V_medida = razão × V_entrada
Se escolhermos R1 = 10 × R2, temos:
V_medida = 11 × V_entrada
Como o máximo de V_entrada permitido é 5V ⇒ A tensão máxima mensurável é 55V.
Para limitar a corrente que passa pelo pino do Arduino, o que poderia danificá-lo, devemos escolher valores de resistores o maiores possíveis.
Escolhi R1 = 1 MΩ, R2 = 100 kΩ.
Na Prática
Existem alguns problemas práticos:
- Os valores de R1 e R2 têm tolerâncias. Esses erros causam erro em V_medida.
- A fonte de alimentação do Arduino pode ser instável. Isso torna a V_REF da entrada analógica instável, causando erro no cálculo de V_entrada e, consequentemente, em V_medida.
Esses problemas são resolvidos na etapa de Calibração.
Calibração
1. Medir o valor real de (R1 + R2) / R2
Isso precisa ser feito apenas uma vez para obter a razão.
Ligação conforme imagem abaixo:
razão = (R1 + R2) / R2 = V_medida / V_entrada = leitura_A1 / leitura_A0
razão = leitura_A1 / leitura_A0
Código para esta calibração ⇒ veja ResisterCalibration.ino na seção de código.
2. Instabilidade da fonte de alimentação
A instabilidade da fonte causa instabilidade na referência de tensão do pino analógico, gerando medição incorreta.
Para resolver, precisamos medir a referência de tensão frequentemente.
Como medir a referência de tensão? Conecte 3.3V ao pino A1.
A referência de tensão é medida indiretamente baseada no valor em A1:
V_referência = 1023 × 3.3 / valor_A1
Como calcular V_medida:
V_entrada = mapFloat(valor_A0, 0, 1023, 0, V_referência); V_medida = razão × V_entrada;
Ligação principal:
Como Fazer
- Faça a ligação do circuito de "calibração do resistor"
- Carregue o
ResistorCalibration.ino - Abra o Serial Plotter
- Copie o valor da razão
- Substitua este valor na linha 5 do
Voltmeter.ino - Refaça a ligação conforme "ligação principal"
- Carregue o
Voltmeter.ino - Carregue a Interface Web (voltmeter.php e voltmeter_body.jpg) para o PHPoC Shield
- Acesse a página web
https://ip_do_phpoc_shield/voltmeter.phppara ver a tensão.
Você pode visualizar a tensão no smartphone:
Dicas de Ligação
Código
ResistorCalibration.ino
double ratio;
int analogReadAverage(int pin, int read_time) {
unsigned long read_value = 0;
for(int i = 0; i < read_time; i++) {
read_value += analogRead(pin);
delay(2);
}
read_value /= read_time;
return read_value;
}
double resistorCalibration() {
double _ratio;
double A0_read_value;
double A1_read_value;
A0_read_value = analogReadAverage(A0, 20);
A1_read_value = analogReadAverage(A1, 20);
_ratio = A1_read_value / A0_read_value;
return _ratio;
}
void setup() {
Serial.begin(9600);
}
void loop() {
ratio = resistorCalibration();
Serial.print("ratio:");
Serial.println(ratio);
delay(200);
}
Voltmeter.ino
double V_measure;
double V_in;
double V_reference;
double ratio = 11.59; // Substitua pelo valor calibrado
double mapFloat(double x, double in_min, double in_max, double out_min, double out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
int analogReadAverage(int pin, int read_time) {
unsigned long read_value = 0;
for(int i = 0; i < read_time; i++) {
read_value += analogRead(pin);
delay(2);
}
read_value /= read_time;
return read_value;
}
double getVoltageReference() {
double A1_value = analogReadAverage(A1, 20); // A1 conectado a 3.3V
double V_REF = 1023 * 3.3 / A1_value;
return V_REF;
}
void setup() {
Serial.begin(9600);
}
void loop() {
V_reference = getVoltageReference();
double A0_value = analogReadAverage(A0, 20);
V_in = mapFloat(A0_value, 0, 1023, 0, V_reference);
V_measure = ratio * V_in;
Serial.println(V_measure);
delay(200);
}
voltmeter.php (Interface Web)
<!DOCTYPE html>
<html>
<head>
<title>PHPoC Shield - VOLTÍMETRO</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/segment7" type="text/css"/>
<style>
html {height: 100%;}
body {width: 100%; height: 100%; text-align: center;}
.container {width: 100%; min-height: 99%; max-height: 100%;}
canvas { background: url(voltmeter_body.jpg); background-size:contain; font-family: 'Segment7Standard'; font-weight: bold; font-style: italic; }
</style>
<script>
var COLOR_LCD_TEXT = "#000000";
var COLOR_LCD_BGR = "#00FFFF";
var IMG_WIDTH = 583;
var IMG_HEIGHT = 1235;
var METER_WIDTH, METER_HEIGHT;
var ws;
var canvas;
var ctx;
var buffer = "";
var voltage = 0;
function init() {
canvas = document.getElementById("graph");
ctx = canvas.getContext("2d");
canvas_resize();
update_view(voltage);
var ws_host_addr = "";
if((navigator.platform.indexOf("Win") != -1) && (ws_host_addr.charAt(0) == "[")) {
ws_host_addr = ws_host_addr.replace(/[\[\]]/g, '');
ws_host_addr = ws_host_addr.replace(/:/g, "-");
ws_host_addr += ".ipv6-literal.net";
}
ws = new WebSocket("ws://" + ws_host_addr + "/serial_monitor", "uint8.phpoc");
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
ws.binaryType = "arraybuffer";
}
function ws_onopen() { }
function ws_onclose() {
alert("NÃO CONSEGUE CONECTAR AO ARDUINO!");
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
}
function ws_onmessage(e_msg) {
e_msg = e_msg || window.event;
var u8view = new Uint8Array(e_msg.data);
buffer += String.fromCharCode.apply(null, u8view);
buffer = buffer.replace(/\r\n/g, "\n");
buffer = buffer.replace(/\r/g, "\n");
while(buffer.indexOf("\n") == 0) buffer = buffer.substr(1);
if(buffer.indexOf("\n") <= 0) return;
var pos = buffer.lastIndexOf("\n");
var str = buffer.substr(0, pos);
var arr = str.split("\n");
buffer = buffer.substr(pos + 1);
if(arr.length) {
voltage = parseFloat(arr[arr.length - 1]);
update_view(voltage);
}
}
function update_view(voltage) {
ctx.clearRect(0, 0, METER_WIDTH, METER_HEIGHT);
var top = METER_HEIGHT * 0.125;
var left = METER_WIDTH * 0.2;
var width = METER_WIDTH * 0.6;
var height = METER_HEIGHT * 0.12;
ctx.fillStyle = COLOR_LCD_BGR;
ctx.rect(left, top, width, height);
ctx.fill();
ctx.font = "italic 75px Segment7Standard";
ctx.textBaseline = "middle";
ctx.textAlign = "end";
ctx.fillStyle = COLOR_LCD_TEXT;
ctx.fillText(voltage.toFixed(2), left + width - 50, top + height / 1.8);
ctx.font = "18px Arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.fillText("VDC", left + width - 25, top + height / 2);
ctx.font = "bold 32px Arial";
ctx.shadowBlur = 5;
ctx.shadowColor = "white";
ctx.fillStyle = "#00FFFF";
ctx.fillText("ARDUINO", METER_WIDTH / 2, METER_HEIGHT * 0.5);
ctx.fillText("WEB VOLTMETER", METER_WIDTH / 2, METER_HEIGHT * 0.55);
}
function canvas_resize() {
canvas.width = 0;
canvas.height = 0;
var container = document.getElementById("container");
var height = container.clientHeight;
var ratio = height / IMG_HEIGHT;
var width = ratio * IMG_WIDTH;
METER_WIDTH = width;
METER_HEIGHT = height;
canvas.width = METER_WIDTH;
canvas.height = METER_HEIGHT;
update_view(voltage);
}
window.onload = init;
</script>
</head>
<body onresize="canvas_resize()">
<div class="container" id="container">
<canvas id="graph"></canvas>
</div>
</body>
</html>
Esquemáticos
Processo de manufatura
- Console de Controle DIY para Photoshop com Arduino Nano RP2040
- Sistema de Presença RFID Confiável com Arduino e Python
- Controle Remoto Universal Android com Arduino, 1Sheeld e IR
- Construa um Sensor de Batimento Cardíaco Infravermelho Confiável com Arduino: Guia Passo a Passo
- Medição Precisa de Frequência e Ciclo de Trabalho com Arduino UNO
- Construa um Voltímetro DIY com Arduino e Display Nokia 5110 – Guia Passo a Passo
- Medição de Distância em Tempo Real com Sonar Arduino e Visualização no Processing
- MobBob: Construa Seu Próprio Robô Arduino, Controlado via Smartphone Android
- Controle Suave de Brilho de LED com Bolt IoT e Arduino UNO
- Braço Robótico Inteligente Controlado por Arduino: Tutorial DIY Fácil