Resistivímetro DC de Baixo Custo — Tutorial DIY
Disciplinas: Ciências Ambientais · Hidrogeologia · Geofísica Aplicada
Plataforma: Arduino Mega 2560 · Interface Android via Bluetooth
Baseado em: OhmPi (INRAE, 2020) · Clark & Page (2011) · Vega et al. (2021)
Sumário
- Introdução e Viabilidade
- Princípio Físico
- Arquitetura do Sistema
- Lista de Componentes
- Diagrama de Circuito
- Firmware Arduino
- Interface Android via Bluetooth
- Caixa em Impressão 3D
- Procedimento de Campo
- Calibração e Validação
- Processamento dos Dados
- Referências e Recursos
1. Introdução e Viabilidade
Contexto
A sondagem elétrica por resistividade (DC resistivity) é uma técnica geofísica não-invasiva fundamental em hidrogeologia, ciências ambientais e engenharia geotécnica. Equipamentos comerciais (ABEM Terrameter, Iris Syscal, AGI SuperSting) custam entre R$ 25.000 e R$ 120.000, tornando o acesso inviável para a maioria dos grupos de pesquisa e ensino em universidades brasileiras.
O avanço dos microcontroladores de baixo custo (Arduino, Raspberry Pi) e a disponibilidade de componentes eletrônicos via AliExpress e Mercado Livre criaram condições reais para construção de instrumentos DIY funcionais com base científica sólida.
Conclusão de Viabilidade
✅ Sim, é plenamente viável. Projetos validados em periódicos como Geophysics (SEG), Earth and Space Science (AGU) e SoftwareX (Elsevier) demonstram erros relativos de 0,6% a 5,5% em relação a equipamentos comerciais — suficiente para pesquisa acadêmica e aplicações ambientais.
Comparação com projetos científicos publicados
| Projeto | Custo aprox. | Microcontrolador | Profundidade máx. | Publicação |
|---|---|---|---|---|
| Clark & Page (2011) | ~US$ 250 | Sem MCU | ~35 m | Hydrogeology Journal |
| OhmPi v2023 | ~US$ 500 | Raspberry Pi 4 | Variável | SoftwareX (2020) |
| Vega et al. (2021) | ~US$ 300 | Arduino DUE | ~20 m | Earth and Space Science |
| Sirota & Roth (2022) | ~US$ 400 | Arduino + RPi | ~40 m | Geophysics (SEG) |
| Este tutorial | ~R$ 600 | Arduino Mega | ~30–50 m | DIY / educacional |
Limitações importantes
⚠️ Este instrumento NÃO substitui equipamentos profissionais para prospecção comercial. As principais restrições são: - Profundidade investigada menor (< 50 m em solos típicos) - Maior susceptibilidade a ruído elétrico ambiental - Sem tomografia automática multieletrodo (versão básica) - Para publicações científicas, recomenda-se validação cruzada com equipamento de referência em pelo menos uma campanha de campo
2. Princípio Físico
O método de resistividade elétrica DC
O método baseia-se na Lei de Ohm generalizada aplicada ao meio geológico. Uma corrente contínua I é injetada no solo através de dois eletrodos de corrente A e B. Dois eletrodos de potencial M e N medem a diferença de potencial ΔV resultante. A resistividade aparente ρ é calculada como:
ρ (Ω·m) = K · (ΔV / I)
onde K é o fator geométrico, que depende exclusivamente do arranjo e do espaçamento dos eletrodos.
Arranjo Wenner (recomendado para educação)
O arranjo mais simples: os quatro eletrodos são igualmente espaçados de a metros.
A ———————— M ———————— N ———————— B
|←—— a ——→|←—— a ——→|←—— a ——→|
Fator geométrico: K = 2π · a
Resistividade: ρ = 2π · a · (ΔV / I)
Vantagens: simples de implementar, boa sensibilidade lateral, amplamente documentado.
Desvantagem: AB precisa ser movido a cada leitura — mais trabalhoso para SEV.
Arranjo Schlumberger (recomendado para SEV)
Os eletrodos MN permanecem fixos no centro enquanto AB é afastado progressivamente para investigar maiores profundidades.
A ——————————————— M — N ——————————————— B
|←——————————————— L ————————————————→|
|←a→|
Fator geométrico: K = π · (L²/2a − a/2)
Resistividade: ρ = π · (L²/2a − a/2) · (ΔV / I)
onde: L = AB/2 (metade do espaçamento AB)
a = MN/2 (metade do espaçamento MN)
Regra prática: manter MN ≤ AB/5. Quando AB/2 ≥ 5 × MN/2, reposicionar MN para MN = AB/5.
Vantagens: MN fixo reduz o trabalho de campo; ideal para Sondagem Elétrica Vertical (SEV).
O que o microcontrolador realmente mede
O Arduino não mede resistividade diretamente. Ele mede grandezas elétricas brutas:
| Grandeza | Componente medidor | Precisão típica |
|---|---|---|
Corrente I (A) |
ACS712 — sensor efeito Hall | ±1,5% FS |
Tensão ΔV (V) |
ADS1115 16-bit + INA128 | ~7,8 µV/bit |
Fator K |
Calculado por software | Exato (geométrico) |
A resistividade é então calculada no firmware por: ρ = K × (ΔV / I).
Por que a inversão de polaridade é necessária
Ao injetar corrente DC diretamente no solo, ocorre polarização eletrolítica nos eletrodos: íons acumulam-se na interface metal-solo, criando um potencial parasita que soma ao sinal real. Para mitigar isso:
- Realiza-se uma medição com polaridade direta → obtém-se
V₁eI₁ - Inverte-se a polaridade da injeção → obtém-se
V₂eI₂ - Calcula-se a média:
ΔV = (|V₁| + |V₂|) / 2eI = (I₁ + I₂) / 2
Isso cancela o potencial de polarização, que tem sinal oposto nas duas medições.
3. Arquitetura do Sistema
┌─────────────────────────────────────────────────────────────────┐
│ BATERIA 12V 7Ah │
└──────────────────┬──────────────────────────┬───────────────────┘
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ Boost Converter│ │ Regulador 5V │
│ MT3608 │ │ LM7805 / LM317 │
│ 12V → 60–120V │ │ 5V para MCU │
└────────┬────────┘ └────────┬────────┘
│ │
┌────────▼────────┐ ┌────────▼──────────────────┐
│ H-Bridge │ │ Arduino Mega 2560 │
│ 2× IRF540N │◄───────│ │
│ Inversão polar.│ ctrl │ ADS1115 (I2C, ADC 16-bit) │
└──┬──────────┬───┘ │ INA128 (amp. instrumentação)│
│ │ │ ACS712 (sensor de corrente) │
┌──────▼──┐ ┌────▼───────┐ │ HC-05 (Bluetooth serial) │
│ Shunt │ │ Relés SSR │ │ LCD 20×4 I2C │
│ 0,33Ω │ │ A B M N │ │ Micro SD Card │
└──┬──────┘ └────┬───────┘ │ RTC DS3231 │
│ │ └────────────────────────────┘
┌─────▼───────────────▼───────────────┐
│ ELETRODOS NO SOLO │
│ A M N B │
│ ●────────●──────●────────● │
└──────────────────────────────────────┘
ACS712 mede corrente I no circuito AB
INA128 + ADS1115 mede diferença de potencial ΔV em MN
Fluxo de dados
Campo Eletrodos → Amplificação → ADC → Arduino
↓
Firmware Média de N amostras → Cálculo ρ = K·ΔV/I
↓
Saída LCD (tempo real) + SD Card (CSV) + Bluetooth (Android)
↓
Pós-campo Exportar CSV → IPI2WIN / ResIPy → Inversão → Perfil
4. Lista de Componentes
💡 Todos os componentes podem ser encontrados no Mercado Livre, AliExpress (10–20 dias) ou lojas como FilipeFlop, Baú da Eletrônica e Casa da Robótica.
4.1 Núcleo de controle e aquisição
| Componente | Qtd. | Preço est. (R$) | Função |
|---|---|---|---|
| Arduino Mega 2560 (ou clone) | 1 | 90 | MCU principal — I/O e processamento |
| ADS1115 (módulo I2C breakout) | 1 | 25 | ADC 16-bit para medição de ΔV com alta precisão |
| INA128 ou INA126 (DIP-8) | 1 | 18 | Amplificador de instrumentação para sinal MN |
| ACS712 módulo 30A | 1 | 15 | Sensor de corrente por efeito Hall |
| Módulo Bluetooth HC-05 | 1 | 35 | Comunicação serial wireless com Android |
| Display LCD 20×4 com módulo I2C | 1 | 30 | Interface de campo |
| Módulo RTC DS3231 | 1 | 20 | Timestamp automático nos dados |
| Módulo Micro SD Card | 1 | 15 | Log de dados em campo (formato CSV) |
| Subtotal | ~248 |
4.2 Circuito de injeção de corrente
| Componente | Qtd. | Preço est. (R$) | Função |
|---|---|---|---|
| Boost Converter MT3608 (módulo ajustável) | 1 | 12 | Eleva 12V → 60–120V DC para injeção |
| MOSFET IRF540N (TO-220) | 2 | 6 | H-bridge para inversão de polaridade |
| Relé de estado sólido 5A DC (SSR) | 4 | 60 | Chaveamento ABMN sem bounce mecânico |
| Resistor shunt 0,33 Ω 5W (cimento) | 1 | 8 | Referência de corrente para ACS712 |
| Diodo 1N4007 | 4 | 3 | Proteção contra picos de tensão reversa |
| Capacitor eletrolítico 100 µF 200V | 2 | 12 | Filtro de ripple na saída do boost |
| Resistor 100 kΩ 1% (par casado) | 2 | 4 | Divisor de tensão — proteção entrada MN |
| Resistor 10 kΩ 1% (par casado) | 2 | 4 | Divisor de tensão — proteção entrada MN |
| Diodo TVS SMAJ5.0A | 2 | 6 | Proteção ESD nas entradas M e N |
| Regulador LM7805 (TO-220) | 1 | 5 | 5V estabilizado para Arduino e sensores |
| Bateria selada 12V 7Ah (VRLA) | 1 | 120 | Fonte de campo — ~4h de operação |
| Subtotal | ~240 |
4.3 Eletrodos e material de campo
| Item | Qtd. | Preço est. (R$) | Observações |
|---|---|---|---|
| Varão roscado inox 1/2" × 40 cm | 4 | 40 | Cortar em ~40 cm; rosca para fixar terminal |
| Cabo PP 2×1,5 mm² (carretel 100 m) | 1 | 130 | Ligação eletrodos ↔ instrumento |
| Conectores banana 4 mm macho+fêmea | 8 pares | 30 | Terminais A, B, M, N no painel |
| Terminais tipo jacaré com cabo 30 cm | 4 | 12 | Conexão rápida nos eletrodos em campo |
| Fita isolante autofusão | 1 rolo | 15 | Vedação das emendas no campo |
| Trena de fibra 100 m | 1 | 40 | Medição precisa dos espaçamentos |
| Subtotal | ~267 |
4.4 Custo total estimado
| Categoria | Custo (R$) |
|---|---|
| Eletrônica (núcleo + injeção) | ~488 |
| Eletrodos e campo | ~267 |
| Total sem caixa | ~755 |
| Filamento PETG 1 kg (caixa 3D) | +80–150 |
| Total com caixa impressa | ~835–905 |
💡 Usando caixa de PVC elétrica (~R$ 25) em vez de impressão 3D, o custo cai para ~R$ 780.
5. Diagrama de Circuito
5.1 Circuito de injeção (alta tensão — ATENÇÃO)
🚨 SEGURANÇA: O circuito de injeção opera com 60–120V DC. Nunca toque nos terminais A e B durante a medição. Use caixa fechada e sinalize os bornes de alta tensão.
BATERIA 12V
│
├──────────────────────────────────────────────┐
│ │
┌───▼──────────┐ ┌──────▼──────┐
│ Boost MT3608 │ │ LM7805 │
│ 12V → 100V │ │ 12V → 5V │
│ Ajustar trim │ └──────┬──────┘
└───┬──────────┘ │
│ GND + 5V
┌───▼──────────────────────────┐ para Arduino
│ H-Bridge com IRF540N │
│ │
│ Q1 ─── Drain: V+boost │ ← PWM D22 (INJECT_EN)
│ Q2 ─── Gate: GND │ ← PWM D23 (INJECT_POL)
│ │
│ Saída +: via Shunt 0,33Ω → eletrodo A │
│ Saída −: eletrodo B │
└──────────────────────────────┘
Shunt 0,33Ω em série no circuito AB:
Ponto antes do shunt → ACS712 IP+
Ponto depois do shunt → ACS712 IP−
ACS712 OUT → Arduino A0
5.2 Circuito de medição (baixa tensão)
Eletrodo M ──┬── Divisor 100k/10k ──┬── INA128 pino 1 (−IN)
└── Diodo TVS SMAJ5 │
│
Eletrodo N ──┬── Divisor 100k/10k ──┴── INA128 pino 8 (+IN)
└── Diodo TVS SMAJ5
INA128:
Pino 1 (−IN) → eletrodo M (via proteção)
Pino 8 (+IN) → eletrodo N (via proteção)
Pino 1─8 (Rg) → Resistor 499 Ω (ganho = 1 + 50k/499 ≈ 101×)
Pino 5 (OUT) → ADS1115 pino A0
Pino 7 (VS+) → +5V
Pino 4 (VS−) → GND
ADS1115:
SDA → Arduino Mega pino 20 (SDA)
SCL → Arduino Mega pino 21 (SCL)
ADDR → GND (endereço I2C = 0x48)
VDD → 3,3V
Ganho configurado por software: GAIN_SIXTEEN (±0,256V → 7,8 µV/bit)
5.3 Divisor de tensão para proteção dos pinos M e N
Os eletrodos M e N podem receber tensões inesperadamente altas (> 5V) em solos muito resistivos. O divisor de tensão reduz a tensão de entrada do INA128 para níveis seguros:
Eletrodo M/N
│
100kΩ (1%)
│
├──────────── Saída para INA128 (−IN ou +IN)
│
10 kΩ (1%)
│
GND
Razão do divisor: 10k / (100k + 10k) = 1/11 ≈ 0,0909
Faixa útil: até ±11 × 0,256V = ±2,8V no eletrodo (sem o ganho INA128)
Compensar no software multiplicando a leitura por 11.
5.4 Pinagem completa Arduino Mega
| Pino Arduino | Função | Componente |
|---|---|---|
| D20 (SDA) | I2C dados | ADS1115 + LCD + RTC |
| D21 (SCL) | I2C clock | ADS1115 + LCD + RTC |
| D22 | INJECT_EN — habilita injeção | Gate MOSFET Q1 |
| D23 | INJECT_POL — controla polaridade | Gate MOSFET Q2 |
| D10 (RX2) | Bluetooth RX | HC-05 TX |
| D11 (TX2) | Bluetooth TX | HC-05 RX |
| D53 (SS) | Chip Select SD | Módulo Micro SD |
| D51 (MOSI) | SPI dados | Módulo Micro SD |
| D50 (MISO) | SPI dados | Módulo Micro SD |
| D52 (SCK) | SPI clock | Módulo Micro SD |
| A0 | Leitura corrente | ACS712 OUT |
6. Firmware Arduino
6.1 Dependências
Instale via Ferramentas → Gerenciar Bibliotecas na IDE Arduino:
Adafruit ADS1X15(por Adafruit) — ADC 16-bitLiquidCrystal I2C(por Frank de Brabander) — displaySD(built-in) — cartão SDRTClib(por Adafruit) — relógio de tempo real
6.2 Código principal
// ================================================================
// resistivimetro_diy.ino
// Resistivímetro DC de Baixo Custo — Wenner / Schlumberger
// Baseado em OhmPi (INRAE) e Clark & Page (2011)
// Versão 1.0 — Uso educacional e de pesquisa
// ================================================================
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <RTClib.h>
#include <SoftwareSerial.h>
// ── Pinos ────────────────────────────────────────────────────────
#define PIN_INJECT_EN 22 // Habilita injeção de corrente
#define PIN_INJECT_POL 23 // Controla polaridade (H-bridge)
#define PIN_ACS712 A0 // Saída analógica do sensor de corrente
#define PIN_SD_CS 53 // Chip Select do cartão SD
// ── Constantes de calibração ─────────────────────────────────────
#define ACS712_SENSITIVITY 0.066 // V/A (modelo 30A; ajustar após calibração)
#define ACS712_OFFSET 2.5 // V (VCC/2; medir com corrente zero)
#define ACS712_VCC 5.0 // Tensão de referência do sensor
#define INA128_GAIN 101.0 // Ganho = 1 + 50k/Rg com Rg = 499Ω
#define DIVISOR_RATIO 11.0 // Divisor 100k/10k = razão 1/11
#define NUM_SAMPLES 64 // Amostras para média (reduz ruído)
#define INJECT_STABILIZE_MS 300 // ms para estabilização após injeção
// ── Objetos ───────────────────────────────────────────────────────
Adafruit_ADS1115 ads;
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS3231 rtc;
SoftwareSerial bluetooth(10, 11); // RX=10, TX=11 → HC-05
// ── Estado do instrumento ─────────────────────────────────────────
enum Arranjo { WENNER, SCHLUMBERGER };
Arranjo arranjoAtual = WENNER;
float param_a = 1.0; // Espaçamento 'a' em metros (Wenner) ou MN/2 (Schlumberger)
float param_L = 5.0; // AB/2 em metros (apenas Schlumberger)
int medicao_num = 0; // Contador de medições
// ════════════════════════════════════════════════════════════════
// SETUP
// ════════════════════════════════════════════════════════════════
void setup() {
Serial.begin(9600);
bluetooth.begin(9600);
// Pinos de controle
pinMode(PIN_INJECT_EN, OUTPUT);
pinMode(PIN_INJECT_POL, OUTPUT);
digitalWrite(PIN_INJECT_EN, LOW); // Injeção desligada por padrão
digitalWrite(PIN_INJECT_POL, LOW);
// ADS1115
ads.setGain(GAIN_SIXTEEN); // ±0.256V → 7.8125 µV/LSB
if (!ads.begin()) {
Serial.println("ERRO: ADS1115 não encontrado!");
}
// LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0); lcd.print("ResistivDIY v1.0");
lcd.setCursor(0, 1); lcd.print("Inicializando...");
// SD Card
if (!SD.begin(PIN_SD_CS)) {
lcd.setCursor(0, 2); lcd.print("SD: FALHA");
Serial.println("AVISO: SD Card não encontrado. Log desabilitado.");
} else {
// Cria cabeçalho do CSV se arquivo não existe
if (!SD.exists("dados.csv")) {
File f = SD.open("dados.csv", FILE_WRITE);
if (f) {
f.println("num,timestamp,arranjo,a_m,L_m,I_mA,dV_mV,K,rho_ohm_m,qualidade");
f.close();
}
}
}
// RTC
if (!rtc.begin()) {
Serial.println("AVISO: RTC DS3231 não encontrado.");
}
lcd.setCursor(0, 1); lcd.print("Pronto. ");
lcd.setCursor(0, 2); lcd.print("Arranjo: Wenner ");
lcd.setCursor(0, 3); lcd.print("a=1.0m ");
Serial.println("=== ResistivDIY v1.0 ===");
Serial.println("Comandos: MEDIR | SET_A:[m] | SET_L:[m] | WENNER | SCHLUMBERGER | STATUS | AJUDA");
enviarBT("PRONTO");
}
// ════════════════════════════════════════════════════════════════
// FUNÇÕES DE MEDIÇÃO
// ════════════════════════════════════════════════════════════════
// Mede corrente pelo ACS712 (média de N amostras)
float medirCorrente() {
long soma = 0;
for (int i = 0; i < NUM_SAMPLES; i++) {
soma += analogRead(PIN_ACS712);
delayMicroseconds(200);
}
float tensao = (soma / (float)NUM_SAMPLES) * (ACS712_VCC / 1023.0);
float corrente = (tensao - ACS712_OFFSET) / ACS712_SENSITIVITY;
return abs(corrente); // Amperes
}
// Mede tensão diferencial MN pelo ADS1115 + INA128
float medirTensao() {
long soma = 0;
for (int i = 0; i < NUM_SAMPLES; i++) {
soma += ads.readADC_Differential_0_1();
delay(2); // Aguarda próxima conversão ADS1115
}
float raw = soma / (float)NUM_SAMPLES;
float vADS = raw * 0.0000078125; // 7.8125 µV/bit com GAIN_SIXTEEN
float vMN_amp = vADS / INA128_GAIN; // Desfaz ganho INA128
float vMN_real = vMN_amp * DIVISOR_RATIO; // Desfaz divisor de tensão
return vMN_real; // Volts
}
// Calcula o fator geométrico K para o arranjo configurado
float calcularK() {
if (arranjoAtual == WENNER) {
return 2.0 * PI * param_a;
} else {
// Schlumberger: K = π · (L²/2a − a/2)
return PI * ((param_L * param_L) / (2.0 * param_a) - param_a / 2.0);
}
}
// Realiza medição completa com inversão de polaridade
// Retorna resistividade em Ω·m, ou -1 em caso de erro
float medirResistividade(float &I_out, float &dV_out) {
// ── Polaridade direta ────────────────────────────────────────
digitalWrite(PIN_INJECT_POL, LOW);
digitalWrite(PIN_INJECT_EN, HIGH);
delay(INJECT_STABILIZE_MS);
float I1 = medirCorrente();
float dV1 = medirTensao();
// ── Polaridade invertida (cancela polarização eletrolítica) ──
digitalWrite(PIN_INJECT_POL, HIGH);
delay(INJECT_STABILIZE_MS);
float I2 = medirCorrente();
float dV2 = medirTensao();
// ── Desliga injeção ──────────────────────────────────────────
digitalWrite(PIN_INJECT_EN, LOW);
// ── Médias ───────────────────────────────────────────────────
I_out = (I1 + I2) / 2.0;
dV_out = (abs(dV1) + abs(dV2)) / 2.0;
if (I_out < 0.001) return -1.0; // Corrente abaixo de 1 mA: erro
float K = calcularK();
float rho = K * (dV_out / I_out);
return rho;
}
// ════════════════════════════════════════════════════════════════
// LOG E SAÍDA
// ════════════════════════════════════════════════════════════════
void enviarBT(String msg) {
bluetooth.println(msg);
}
void logCSV(float rho, float I, float dV) {
File f = SD.open("dados.csv", FILE_WRITE);
if (!f) return;
DateTime now = rtc.now();
medicao_num++;
f.print(medicao_num); f.print(",");
f.print(now.timestamp(DateTime::TIMESTAMP_FULL)); f.print(",");
f.print(arranjoAtual == WENNER ? "Wenner" : "Schlumberger"); f.print(",");
f.print(param_a, 3); f.print(",");
f.print(param_L, 3); f.print(",");
f.print(I * 1000.0, 3); f.print(","); // mA
f.print(dV * 1000.0, 4); f.print(","); // mV
f.print(calcularK(), 3); f.print(",");
f.print(rho, 2); f.print(",");
f.println(rho > 0 ? "OK" : "ERRO");
f.close();
}
void atualizarLCD(float rho, float I, float dV) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(arranjoAtual == WENNER ? "Wenner a=" : "Schlumb L=");
lcd.print(arranjoAtual == WENNER ? param_a : param_L, 1);
lcd.print("m");
lcd.setCursor(0, 1);
lcd.print("Rho: ");
lcd.print(rho < 0 ? 0 : rho, 1);
lcd.print(" Om.m");
lcd.setCursor(0, 2);
lcd.print("I="); lcd.print(I * 1000.0, 1); lcd.print("mA");
lcd.setCursor(10, 2);
lcd.print("dV="); lcd.print(dV * 1000.0, 2); lcd.print("mV");
lcd.setCursor(0, 3);
lcd.print("Med#"); lcd.print(medicao_num);
}
// ════════════════════════════════════════════════════════════════
// LOOP PRINCIPAL — interpretação de comandos
// ════════════════════════════════════════════════════════════════
void loop() {
String cmd = "";
if (Serial.available()) cmd = Serial.readStringUntil('\n');
if (bluetooth.available()) cmd = bluetooth.readStringUntil('\n');
if (cmd.length() == 0) return;
cmd.trim();
cmd.toUpperCase();
// ── MEDIR ────────────────────────────────────────────────────
if (cmd == "MEDIR") {
lcd.clear();
lcd.print("Injetando...");
Serial.println("Iniciando medicao...");
float I = 0, dV = 0;
float rho = medirResistividade(I, dV);
atualizarLCD(rho, I, dV);
logCSV(rho, I, dV);
String resp = "RHO:" + String(rho, 2)
+ ",I:" + String(I * 1000.0, 2)
+ ",dV:" + String(dV * 1000.0, 3)
+ ",K:" + String(calcularK(), 3)
+ ",A:" + String(param_a)
+ ",L:" + String(param_L)
+ ",N:" + String(medicao_num);
Serial.println(resp);
enviarBT(resp);
// ── SET_A ────────────────────────────────────────────────────
} else if (cmd.startsWith("SET_A:")) {
param_a = cmd.substring(6).toFloat();
lcd.setCursor(0, 3); lcd.print("a=" + String(param_a, 2) + "m ");
String r = "OK:A=" + String(param_a, 3);
Serial.println(r); enviarBT(r);
// ── SET_L ────────────────────────────────────────────────────
} else if (cmd.startsWith("SET_L:")) {
param_L = cmd.substring(6).toFloat();
lcd.setCursor(0, 3); lcd.print("L=" + String(param_L, 2) + "m ");
String r = "OK:L=" + String(param_L, 3);
Serial.println(r); enviarBT(r);
// ── WENNER / SCHLUMBERGER ────────────────────────────────────
} else if (cmd == "WENNER") {
arranjoAtual = WENNER;
lcd.setCursor(0, 2); lcd.print("Arranjo: Wenner ");
String r = "OK:WENNER";
Serial.println(r); enviarBT(r);
} else if (cmd == "SCHLUMBERGER") {
arranjoAtual = SCHLUMBERGER;
lcd.setCursor(0, 2); lcd.print("Arranjo: Schlumb");
String r = "OK:SCHLUMBERGER";
Serial.println(r); enviarBT(r);
// ── STATUS ───────────────────────────────────────────────────
} else if (cmd == "STATUS") {
String resp = "STATUS:"
+ String(arranjoAtual == WENNER ? "Wenner" : "Schlumberger")
+ ",A:" + String(param_a, 3)
+ ",L:" + String(param_L, 3)
+ ",N:" + String(medicao_num);
Serial.println(resp); enviarBT(resp);
// ── AJUDA ────────────────────────────────────────────────────
} else if (cmd == "AJUDA") {
String h = "Comandos:\n"
" MEDIR → realiza medicao\n"
" SET_A:[metros] → define espac. a (Wenner) ou MN/2\n"
" SET_L:[metros] → define AB/2 (Schlumberger)\n"
" WENNER → seleciona arranjo Wenner\n"
" SCHLUMBERGER → seleciona arranjo Schlumberger\n"
" STATUS → exibe configuracao atual\n"
" AJUDA → esta mensagem";
Serial.println(h); enviarBT(h);
} else {
Serial.println("CMD_DESCONHECIDO: " + cmd);
}
}
6.3 Formato do arquivo CSV de saída
O cartão SD grava dados.csv com o seguinte formato:
num,timestamp,arranjo,a_m,L_m,I_mA,dV_mV,K,rho_ohm_m,qualidade
1,2025-06-15T09:23:11,Schlumberger,0.500,1.000,45.230,12.3450,3.141,0.86,OK
2,2025-06-15T09:24:05,Schlumberger,0.500,1.500,43.110,28.7610,11.00,7.33,OK
3,2025-06-15T09:25:18,Schlumberger,0.500,2.000,41.890,55.2300,22.78,29.94,OK
7. Interface Android via Bluetooth
7.1 Configuração do módulo HC-05
Antes de usar em campo, configure o HC-05 no modo AT (segurar o botão ao energizar; LED pisca lentamente):
// Comunicação com HC-05 em modo AT: 38400 baud, sem paridade
// Use monitor serial do Arduino IDE ou terminal serial
AT → OK (testa comunicação)
AT+NAME=ResistivDIY → OK (define nome Bluetooth)
AT+PSWD=1234 → OK (define senha de pareamento)
AT+UART=9600,0,0 → OK (baud rate para modo normal)
AT+ROLE=0 → OK (modo escravo — aguarda conexão)
Após configurar, reinicie o HC-05 normalmente (sem segurar o botão). O LED passa a piscar rapidamente quando aguardando conexão.
7.2 Opção 1: MIT App Inventor 2 (recomendado — sem programação)
Acesse appinventor.mit.edu e crie um novo projeto. Componentes necessários:
Designer (interface visual):
| Componente | Tipo | Propriedade relevante |
|---|---|---|
ListPickerBT |
ListPicker | Para selecionar dispositivo BT |
BtClient |
BluetoothClient | Gerencia conexão |
BtnMedir |
Button | Text: "MEDIR" |
BtnWenner |
Button | Text: "Wenner" |
BtnSchlumb |
Button | Text: "Schlumberger" |
TxtA |
TextBox | Hint: "Espaçamento a (m)" |
TxtL |
TextBox | Hint: "AB/2 = L (m)" |
LblRho |
Label | FontSize: 24, Text: "ρ = --- Ω·m" |
LblI |
Label | Text: "I = --- mA" |
LblDV |
Label | Text: "ΔV = --- mV" |
Clock1 |
Clock | TimerInterval: 500 ms |
TinyDB1 |
TinyDB | Armazenamento local |
Blocos de lógica (pseudocódigo):
// Conectar ao HC-05
quando ListPickerBT.AfterPicking:
BtClient.Connect(ListPickerBT.Selection)
// Botão MEDIR
quando BtnMedir.Click:
se BtClient.IsConnected:
BtClient.SendText("MEDIR\n")
// Botão SET arranjo
quando BtnWenner.Click:
BtClient.SendText("WENNER\n")
// Definir espaçamento a
quando TxtA.LostFocus:
BtClient.SendText("SET_A:" + TxtA.Text + "\n")
// Definir L (Schlumberger)
quando TxtL.LostFocus:
BtClient.SendText("SET_L:" + TxtL.Text + "\n")
// Receber dados (Clock a cada 500ms)
quando Clock1.Timer:
se BtClient.IsConnected e BtClient.BytesAvailableToReceive > 0:
texto = BtClient.ReceiveText(512)
se texto.contains("RHO:"):
partes = texto.split(",")
rho = partes[0].split(":")[1] // "RHO:XX.X" → "XX.X"
I = partes[1].split(":")[1] // "I:XX.X"
dV = partes[2].split(":")[1] // "dV:XX.X"
LblRho.Text = "ρ = " + rho + " Ω·m"
LblI.Text = "I = " + I + " mA"
LblDV.Text = "ΔV = " + dV + " mV"
// Salvar no TinyDB
TinyDB1.StoreValue(tag: "med_" + Clock1.Now, value: texto)
7.3 Opção 2: Serial Bluetooth Terminal (sem programação alguma)
O app Serial Bluetooth Terminal (gratuito, Play Store) permite uso imediato:
- Instalar o app
- Parear o celular com o HC-05 (senha: 1234)
- Abrir o app → conectar ao "ResistivDIY"
- Digitar comandos manualmente:
MEDIR,SET_A:1.5, etc. - O log completo de texto pode ser exportado via email ou salvo como
.txt
Configurar atalhos no app:
- Macro 1: MEDIR\n
- Macro 2: STATUS\n
- Macro 3: SCHLUMBERGER\n
- Macro 4: WENNER\n
7.4 Opção 3: App Python com Buildozer (avançado)
Para quem deseja um app dedicado com gráfico de curva SEV em tempo real, é possível usar Kivy + python-for-android:
# Instalar dependências no PC de desenvolvimento (Linux recomendado):
# pip install buildozer kivy
# sudo apt install android-sdk
# arquivo main.py (Kivy)
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.garden.matplotlib import FigureCanvasKivyAgg
import matplotlib.pyplot as plt
import numpy as np
class ResistivLayout(BoxLayout):
def __init__(self, **kw):
super().__init__(orientation='vertical', **kw)
self.medicoes = [] # lista de (L, rho)
self.lbl = Label(text='ρ = --- Ω·m', font_size='20sp', size_hint_y=0.1)
self.add_widget(self.lbl)
self.fig, self.ax = plt.subplots()
self.ax.set_xlabel('AB/2 (m)')
self.ax.set_ylabel('ρ aparente (Ω·m)')
self.ax.set_xscale('log')
self.ax.set_yscale('log')
self.ax.grid(True, which='both', alpha=0.4)
self.canvas_widget = FigureCanvasKivyAgg(self.fig)
self.add_widget(self.canvas_widget)
btn = Button(text='MEDIR', size_hint_y=0.1)
btn.bind(on_press=self.medir)
self.add_widget(btn)
def medir(self, *args):
# Enviar comando via BT e parsear resposta
# (implementar conexão BT via jnius ou bleak)
pass
def atualizar_grafico(self, L, rho):
self.medicoes.append((L, rho))
Ls = [m[0] for m in self.medicoes]
rhos = [m[1] for m in self.medicoes]
self.ax.clear()
self.ax.loglog(Ls, rhos, 'bo-', markersize=6)
self.ax.set_xlabel('AB/2 (m)')
self.ax.set_ylabel('ρ aparente (Ω·m)')
self.ax.grid(True, which='both', alpha=0.4)
self.canvas_widget.draw()
class ResistivApp(App):
def build(self):
return ResistivLayout()
if __name__ == '__main__':
ResistivApp().run()
8. Caixa em Impressão 3D
8.1 Parâmetros de impressão recomendados
| Parâmetro | Valor recomendado |
|---|---|
| Dimensões externas | 220 × 160 × 90 mm (corpo + tampa) |
| Espessura da parede | 3–4 mm |
| Material | PETG (resistência UV + calor) ou ASA (UV exterior) |
| Infill | 40%, padrão gyroid |
| Temperatura bico (PETG) | 230–240°C |
| Temperatura mesa | 70–80°C com brim |
| Suportes | Sim, para furos laterais dos conectores |
| Camada inicial | 0,2–0,3 mm |
| Acabamento vedação | Borracha EPDM 10×3 mm no friso + 4× parafusos M3 inox |
| Inserts metálicos | M3 heat-set para postes do Arduino e PCB |
8.2 Elementos do design
Tampa (face superior):
- Janela recortada 98×40 mm para encaixe do LCD 20×4
(borda de 2 mm ao redor do visor, chanfro 45°)
- 4× furos M3 passantes nos cantos para fechamento
- Ranhura lateral 6×3 mm para saída do cabo da antena HC-05
- Texto em relevo: "ResistivDIY" + seta de aterramento
- Friso perimetral 3×3 mm para gaxeta EPDM
Corpo (base):
- 4× postes Ø6 mm H=10 mm com insert M3 heat-set para Arduino Mega
- 2× postes menores para PCB de medição (espaçamento: medir antes)
- Painel frontal com furos:
- 6× furo Ø4,2 mm para conectores banana 4 mm (A, B, M, N + 2 reservas)
- 1× furo Ø12 mm para chave gangorra 220V/15A (LIGA/DESLIGA)
- 1× janela 30×15 mm para LED de status (vermelho = injeção ativa)
- 1× furo Ø6 mm para conector DC 5,5/2,1 mm (entrada bateria)
- Painel traseiro:
- 1× furo Ø6 mm para slot cartão SD (acesso externo)
- Saída de cabo PP para eletrodos (prensa-cabo M16)
- Compartimento interno direito: 80×50×60 mm para bateria 12V
- Canal de roteamento de cabos em relevo no fundo (H=5 mm)
- 4× pés Ø12×3 mm na base (imprimir em TPU, ou colar borracha autoadesiva)
8.3 Onde encontrar modelos de referência
| Fonte | Busca sugerida | Observações |
|---|---|---|
| gitlab.irstea.fr/reversaal/OhmPi | Repositório oficial | Arquivos STL da caixa OhmPi v2023 |
| Thingiverse.com | "Arduino Mega enclosure field" | Templates adaptáveis |
| Printables.com | "IP65 electronics enclosure" | Modelos com vedação |
| GrabCAD | "geophysics field instrument box" | Modelos CAD paramétricos |
8.4 Alternativa sem impressora 3D
Caixas de PVC para instalações elétricas (padrão ABNT NBR 5410):
- Legrand/Schneider 200×150×80 mm — ~R$ 25 em lojas de material elétrico
- Furar com serra-copo Ø32 mm para os conectores banana
- Usar prensa-cabos M16/M20 para entrada dos cabos de eletrodos
- Vedar tampas com fita autofusão ou silicone neutro
9. Procedimento de Campo
9.1 Preparação pré-campo
- [ ] Carregar bateria 12V completamente (verificar com multímetro: ≥ 12,6V)
- [ ] Formatar cartão SD (FAT32) e verificar espaço livre
- [ ] Verificar RTC (hora e data corretas via
STATUS) - [ ] Testar conexão Bluetooth com o celular/tablet
- [ ] Preparar planilha de campo impressa (ver modelo na seção 9.4)
- [ ] Carregar carretel de cabo PP (100 m)
- [ ] Verificar eletrodos: sem oxidação severa, rosca funcional
- [ ] Preparar solução salina (30 g NaCl por litro d'água) para umedecer eletrodos
9.2 Sequência de medição — SEV Schlumberger
Passo 1 — Marcação e instalação inicial
1. Escolha uma linha reta de ~200 m em terreno aberto (evite cercas metálicas,
postes de energia e estruturas metálicas a menos de 30 m da linha).
2. Marque o centro (ponto C) com uma estaca.
3. Instale os eletrodos MN:
- M: 0,25 m a OESTE do centro
- N: 0,25 m a LESTE do centro
(MN = 0,5 m → a = MN/2 = 0,25 m)
4. Instale A e B simetricamente:
- A: 1,0 m a OESTE do centro (AB/2 = L = 1,0 m)
- B: 1,0 m a LESTE do centro
5. Umedeça os 4 eletrodos com solução salina (reduz resistência de contato).
6. Conecte os cabos: A→terminal A, B→terminal B, M→terminal M, N→terminal N.
Passo 2 — Sequência de espaçamentos
Sequência padrão para SEV com MN = 0,5 m (a = 0,25 m):
| Passo | AB/2 = L (m) | MN (m) | a = MN/2 (m) | K Schlumberger | Ação MN? |
|---|---|---|---|---|---|
| 1 | 1,0 | 0,5 | 0,25 | 11,78 | — |
| 2 | 1,5 | 0,5 | 0,25 | 27,49 | — |
| 3 | 2,0 | 0,5 | 0,25 | 49,74 | — |
| 4 | 3,0 | 0,5 | 0,25 | 113,9 | — |
| 5 | 5,0 | 0,5 | 0,25 | 313,7 | Mover MN para 2,0 m |
| 6 | 5,0 | 2,0 | 1,00 | 74,61 | — |
| 7 | 7,0 | 2,0 | 1,00 | 151,0 | — |
| 8 | 10,0 | 2,0 | 1,00 | 313,1 | Mover MN para 5,0 m |
| 9 | 10,0 | 5,0 | 2,50 | 119,4 | — |
| 10 | 15,0 | 5,0 | 2,50 | 277,5 | — |
| 11 | 20,0 | 5,0 | 2,50 | 497,0 | Mover MN para 10,0 m |
| 12 | 20,0 | 10,0 | 5,00 | 232,5 | — |
| 13 | 30,0 | 10,0 | 5,00 | 534,1 | — |
| 14 | 50,0 | 10,0 | 5,00 | 1492 | — |
Regra: Quando
L ≥ 5 × a, mover MN paraMN_novo = L/5 × 2. Repetir a medição com o novo MN antes de continuar avançando AB.
Passo 3 — Medição em cada ponto
Para cada espaçamento AB/2 = L:
1. Enviar SET_L:[valor] pelo app Android (ou digitar no Serial Monitor)
2. Se MN foi reposicionado, enviar SET_A:[novo_a]
3. Verificar tensão da bateria no LCD (deve ser ≥ 11,5V)
4. Pressionar MEDIR (ou enviar comando "MEDIR")
5. Aguardar ~3–5 s para a medição com inversão de polaridade
6. Anotar na planilha: ρ_ap, I (mA), ΔV (mV)
7. Repetir 3× — verificar consistência (desvio < 5% entre leituras)
8. Usar a média das 3 repetições como valor final
Passo 4 — Controle de qualidade em campo
| Situação | Causa provável | Ação |
|---|---|---|
I < 1 mA |
Solo muito resistivo ou contato ruim | Umedecer eletrodos; aumentar V_boost |
ΔV > ADS_RANGE (saturação) |
Ganho INA128 muito alto | Reduzir ganho (aumentar Rg para 100 Ω → ganho ~501) |
| Desvio entre repetições > 10% | Ruído elétrico ou eletrodo solto | Verificar contatos; aguardar horário com menos RFI |
| ρ negativo | Polarização residual | Aumentar INJECT_STABILIZE_MS para 500 ms |
| LCD mostra ERRO | Corrente < 1 mA | Ver linha acima |
9.3 Planilha de campo
Projeto: ________________________ Data: ________ Operador: _______________
Localização: ___________________ Coord. GPS: _____________________________
Solo: __________________ Chuva nas últimas 24h: Sim / Não
Obs. gerais: ____________________________________________________________
Ponto C (sondagem): ___________________________________________________
AB/2 MN/2 K I (mA) ΔV (mV) ρ_ap (Ω·m) Rep1 Rep2 Rep3 Média
(m) (m) (calc)
---- ---- ------ ------ ------- ---------- ---- ---- ---- -----
1,0 0,25 11,78 ____ ____ ____ ____ ____ ____ ____
1,5 0,25 27,49 ____ ____ ____ ____ ____ ____ ____
2,0 0,25 49,74 ____ ____ ____ ____ ____ ____ ____
3,0 0,25 113,9 ____ ____ ____ ____ ____ ____ ____
5,0 0,25 313,7 ____ ____ ____ ____ ____ ____ ____
5,0 1,00 74,61 ____ ____ ____ ____ ____ ____ ____
7,0 1,00 151,0 ____ ____ ____ ____ ____ ____ ____
10,0 1,00 313,1 ____ ____ ____ ____ ____ ____ ____
10,0 2,50 119,4 ____ ____ ____ ____ ____ ____ ____
15,0 2,50 277,5 ____ ____ ____ ____ ____ ____ ____
20,0 2,50 497,0 ____ ____ ____ ____ ____ ____ ____
20,0 5,00 232,5 ____ ____ ____ ____ ____ ____ ____
30,0 5,00 534,1 ____ ____ ____ ____ ____ ____ ____
50,0 5,00 1492 ____ ____ ____ ____ ____ ____ ____
10. Calibração e Validação
10.1 Calibração do ACS712 (sensor de corrente)
Passo 1 — Verificar offset em repouso:
- Com injeção DESLIGADA (PIN_INJECT_EN = LOW)
- Medir tensão no pino OUT do ACS712 com multímetro
- Deve ser exatamente VCC/2 = 2,500V
- Se diferir, atualizar ACS712_OFFSET no firmware
Passo 2 — Verificar sensibilidade:
- Conectar resistor de carga conhecido (ex: 100 Ω 5W)
- Medir corrente com amperímetro de referência
- Comparar com o valor calculado pelo firmware
- Ajustar ACS712_SENSITIVITY se necessário
- Valor nominal: 0,066 V/A (modelo 30A)
10.2 Calibração do circuito de tensão (INA128 + ADS1115)
Passo 1 — Ganho do INA128:
- Aplicar tensão conhecida (ex: 100 mV de uma fonte ou divisor de precisão)
- Verificar saída esperada: 100 mV × 101 = 10,1 V
- Comparar com leitura do ADS1115 reconvertida no Serial Monitor
- Se diferir > 2%, medir Rg real com multímetro e atualizar INA128_GAIN
Passo 2 — Divisor de tensão:
- Aplicar tensão conhecida no eletrodo M (ex: 1,000V de fonte estabilizada)
- Esperado no ADS1115: 1,000 / 11 / 101 = ~900 µV
- Verificar na saída do Serial Monitor: "dV = 1,000 V"
- Ajustar DIVISOR_RATIO se necessário
10.3 Validação em cuba com água salina
Procedimento:
1. Preparar solução de NaCl de condutividade conhecida
(ex: 1 g/L → σ ≈ 1,5 mS/cm → ρ ≈ 6,7 Ω·m)
2. Medir condutividade com condutivímetro de referência
3. Converter: ρ_ref (Ω·m) = 10 / σ (mS/cm)
4. Montar arranjo Wenner dentro da cuba com eletrodos de inox
(espaçamento a = 5 cm, por exemplo)
5. Medir com o resistivímetro DIY
6. Comparar: erro aceitável < 10% para uso educacional
Soluções de referência:
- 0,5 g NaCl/L: σ ≈ 0,7 mS/cm → ρ ≈ 14 Ω·m
- 1,0 g NaCl/L: σ ≈ 1,5 mS/cm → ρ ≈ 6,7 Ω·m
- 5,0 g NaCl/L: σ ≈ 7,0 mS/cm → ρ ≈ 1,4 Ω·m
- 35 g NaCl/L: σ ≈ 53 mS/cm → ρ ≈ 0,19 Ω·m (água do mar)
10.4 Validação cruzada em campo
Para publicações científicas:
- Realizar levantamento SEV no mesmo perfil com o instrumento DIY e com equipamento comercial de referência (Syscal, ABEM Terrameter, ou similar)
- Comparar curvas de ρ_ap × AB/2 em gráfico bilogarítmico
- Calcular RMSE e desvio relativo por ponto
- Critério de aceitação: RMSE < 10% e desvio relativo médio < 5%
- Documentar diferenças sistemáticas e possíveis causas (ruído, resolução ADC, polarização residual)
11. Processamento dos Dados
11.1 Pré-processamento do CSV
# pre_processa_sev.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Ler dados do SD Card
df = pd.read_csv("dados.csv")
# Filtrar apenas medições OK
df = df[df["qualidade"] == "OK"].copy()
# Converter unidades
df["I_A"] = df["I_mA"] / 1000.0
df["dV_V"] = df["dV_mV"] / 1000.0
df["rho"] = df["K"] * (df["dV_V"] / df["I_A"])
# Quando MN muda, o mesmo L foi medido com dois MN diferentes:
# usar a média ponderada ou o valor com MN menor
df_sev = df.groupby("L_m").agg({"rho": "mean"}).reset_index()
df_sev.columns = ["AB2_m", "rho_ohm_m"]
df_sev = df_sev.sort_values("AB2_m")
print(df_sev)
# Plot da curva SEV
fig, ax = plt.subplots(figsize=(8, 5))
ax.loglog(df_sev["AB2_m"], df_sev["rho_ohm_m"], "bo-", markersize=7, linewidth=1.5)
ax.set_xlabel("AB/2 (m)", fontsize=12)
ax.set_ylabel("ρ aparente (Ω·m)", fontsize=12)
ax.set_title("Curva SEV — Resistividade Aparente × Espaçamento", fontsize=13)
ax.grid(True, which="both", alpha=0.4)
ax.grid(True, which="minor", linestyle=":", alpha=0.3)
plt.tight_layout()
plt.savefig("curva_sev.png", dpi=150)
plt.show()
# Salvar para IPI2WIN (formato .wf)
with open("sev_ipi2win.wf", "w") as f:
f.write("SEV ResistivDIY\n")
f.write("Schlumberger\n")
for _, row in df_sev.iterrows():
f.write(f"{row['AB2_m']:.3f} {row['rho_ohm_m']:.3f}\n")
print("Arquivo sev_ipi2win.wf exportado.")
11.2 Softwares de inversão gratuitos
| Software | Tipo | Sistema | Download | Uso |
|---|---|---|---|---|
| IPI2WIN | SEV 1D | Windows | geol.msu.ru | Inversão Schlumberger/Wenner — interface simples |
| ResIPy | ERT 2D/3D | Python/Win/Linux | hkex.ac.uk/ResIPy | Open source, inversão avançada com interface gráfica |
| RES2DINV | ERT 2D | Windows | geotomosoft.com | Versão demo (limitada a 300 pontos) |
| ZondRes2d | ERT 2D | Windows | zond-geo.ru | Versão demo disponível |
| pyGIMLi | ERT 2D/3D | Python | pygimli.org | Open source, altamente configurável |
11.3 Interpretação básica de curvas SEV
Padrões típicos de curvas Schlumberger:
Tipo A (ρ₁ < ρ₂ < ρ₃): curva sempre crescente
→ camadas progressivamente mais resistivas
Ex: argila → areia → rocha sã
Tipo H (ρ₁ > ρ₂ < ρ₃): mínimo intermediário
→ camada condutora entre duas resistivas
Ex: solo → aquífero → rocha
Tipo K (ρ₁ < ρ₂ > ρ₃): máximo intermediário
→ camada resistiva entre duas condutoras
Ex: argila → areia seca → argila saturada
Tipo Q (ρ₁ > ρ₂ > ρ₃): curva sempre decrescente
→ camadas progressivamente mais condutoras
Ex: rocha → saprólito → argila
12. Referências e Recursos
Projetos científicos de referência
-
Clark, L. & Page, R. (2011)
Geophysical characterisation of groundwater resources in semi-arid regions of sub-Saharan Africa.
Hydrogeology Journal, 19(8), 1479–1492.
DOI: 10.1007/s10040-010-0692-0
→ Design seminal de resistivímetro DIY DC por ~US$250. Validado em campo em Chad, Tanzania, Nigéria e Ruanda. -
Clément, R. et al. (2020)
OhmPi: An open source data logger for dedicated applications of electrical resistivity imaging.
SoftwareX, 11, 100455.
DOI: 10.1016/j.softx.2020.100455
→ Projeto OhmPi com Raspberry Pi. Até 32 eletrodos por ~US$500. Código Python open source.
Site oficial: ohmpi.org -
Vega, M. de la et al. (2021)
Design of a Low‐Cost Electrical Resistivity Meter for Near Surface Surveys.
Earth and Space Science, 8(12), e2020EA001575.
DOI: 10.1029/2020EA001575
→ Arduino DUE. Arranjos Dipolo-Dipolo, Wenner-Schlumberger e Wenner. Erro relativo 0,6–5,5% vs. comercial. -
Sirota, D. & Roth, G. (2022)
Development and validation of a low-cost direct current resistivity meter for humanitarian geophysics applications.
Geophysics, 87(1), WA1–WA14.
DOI: 10.1190/geo2021-0058.1
→ Redesenho e validação do instrumento Clark & Page com data logger Raspberry Pi. -
Fauzi, M. et al. (2019)
Low-cost multi electrode resistivity meter based on microcontroller for electric resistivity tomography purpose.
IOP Conf. Series: Journal of Physics, 1153, 012022.
DOI: 10.1088/1742-6596/1153/1/012022
→ Arduino Mega 2560 com multiplexação via IC74HC595 e relés para ERT multieletrodo.
Recursos de software
- OhmPi GitLab (código fonte, esquemas, STL da caixa): gitlab.irstea.fr/reversaal/OhmPi
- ResIPy (inversão ERT open source, Python): hkex.ac.uk/ResIPy
- IPI2WIN (inversão SEV 1D, gratuito): geol.msu.ru/deps/geophys/resist
- pyGIMLi (inversão geofísica avançada, Python): pygimli.org
- MIT App Inventor 2 (app Android sem código): appinventor.mit.edu
Bibliotecas Arduino utilizadas
Adafruit ADS1X15 → github.com/adafruit/Adafruit_ADS1X15
LiquidCrystal I2C → github.com/johnrickman/LiquidCrystal_I2C
RTClib → github.com/adafruit/RTClib
SD → (built-in na IDE Arduino)
Wire → (built-in na IDE Arduino)
SoftwareSerial → (built-in na IDE Arduino)
Documentação elaborada com base em projetos científicos publicados e validados. Para uso educacional e de pesquisa. Não substitui equipamentos profissionais para prospecção comercial.
Baseado em: OhmPi (INRAE France), Clark & Page (2011), Vega et al. (2021), Sirota & Roth (2022).