ESP32 펌웨어 - DIY RF 버그 탐지기용
Wikiprompt, 무료 프롬프트 백과사전에서
ESP32 펌웨어 - DIY RF 버그 탐지기용 프롬프트 for Claude Code: 휴대용 RF 신호(숨은 버그) 탐지기를 위한 완전한 Arduino/ESP32 펌웨어를 생성합니다. OLED 막대 그래프와 오디오 피드백을 포함합니다.
관련 미디어
프롬프트 내용저장
🌐
/*
* ESP32 RF Bug Detector
*
* Hardware:
* - AD8317 logarithmic RF detector on analog pin 34
* - SSD1306 OLED screen on I2C pins 21 and 22
* - Buzzer on pin 25
* - Calibration button on pin 4
* - LiPo battery powered
*
* Tuning parameters are marked with [TUNE] comments.
*/
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
// OLED configuration
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Pin definitions
#define RF_DETECTOR_PIN 34
#define BUZZER_PIN 25
#define CAL_BUTTON_PIN 4
// [TUNE] AD8317 characteristics
// AD8317 output is typically 0.5V to 2.5V for -60dBm to +10dBm
// Slope: ~22mV/dB, Intercept: ~-60dBm at 0.5V
#define AD8317_SLOPE_MV_PER_DB 22.0
#define AD8317_INTERCEPT_DBM -60.0
#define AD8317_VREF 0.5 // Reference voltage at intercept
// [TUNE] Sampling and timing
#define SAMPLE_RATE_HZ 20
#define SAMPLE_INTERVAL_MS (1000 / SAMPLE_RATE_HZ)
// [TUNE] Buzzer behavior
#define MIN_BEEP_INTERVAL_MS 500 // Slowest beep (weak signal)
#define MAX_BEEP_INTERVAL_MS 50 // Fastest beep (strong signal)
#define BEEP_DURATION_MS 30 // Length of each beep
// [TUNE] Display thresholds
#define BAR_MIN_DBM -70.0 // Bottom of bar graph
#define BAR_MAX_DBM -20.0 // Top of bar graph
#define ALERT_THRESHOLD_DB 6.0 // dB above baseline to trigger alert
// Calibration state
float baseline_dbm = -60.0; // Default baseline
bool calibrated = false;
unsigned long last_cal_time = 0;
// Timing variables
unsigned long last_sample_time = 0;
unsigned long last_beep_time = 0;
// Signal processing
float current_dbm = 0.0;
float smoothed_dbm = 0.0;
float alpha = 0.3; // [TUNE] Smoothing factor (0.1-0.5)
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(BUZZER_PIN, OUTPUT);
pinMode(CAL_BUTTON_PIN, INPUT_PULLUP);
analogReadResolution(12); // ESP32 ADC is 12-bit
// Initialize OLED
Wire.begin(21, 22);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("SSD1306 allocation failed");
for (;;); // Don't proceed if OLED fails
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// Show startup screen
display.setCursor(20, 25);
display.println("RF Bug Detector");
display.setCursor(30, 40);
display.println("Starting...");
display.display();
delay(1000);
// Initial calibration after 2 seconds
delay(2000);
calibrateBaseline();
}
void loop() {
unsigned long now = millis();
// Sample at fixed rate
if (now - last_sample_time >= SAMPLE_INTERVAL_MS) {
last_sample_time = now;
// Read and convert to dBm
int raw = analogRead(RF_DETECTOR_PIN);
float voltage = (raw / 4095.0) * 3.3;
current_dbm = voltageToDbm(voltage);
// Apply smoothing
smoothed_dbm = (alpha * current_dbm) + ((1.0 - alpha) * smoothed_dbm);
// Update display
updateDisplay();
// Update buzzer
updateBuzzer();
}
// Check calibration button (debounced)
if (digitalRead(CAL_BUTTON_PIN) == LOW && (now - last_cal_time > 500)) {
last_cal_time = now;
calibrateBaseline();
}
}
float voltageToDbm(float voltage) {
// [TUNE] Adjust this conversion for your specific AD8317
// Formula: dBm = (V - VREF) / slope + intercept
// For AD8317: slope is ~22mV/dB, VREF is 0.5V at -60dBm
float dbm = ((voltage - AD8317_VREF) * 1000.0 / AD8317_SLOPE_MV_PER_DB)
+ AD8317_INTERCEPT_DBM;
return dbm;
}
void calibrateBaseline() {
// Average several readings for stable baseline
float sum = 0.0;
int samples = 20;
for (int i = 0; i < samples; i++) {
int raw = analogRead(RF_DETECTOR_PIN);
float voltage = (raw / 4095.0) * 3.3;
sum += voltageToDbm(voltage);
delay(10);
}
baseline_dbm = sum / samples;
calibrated = true;
// Visual feedback on OLED
display.clearDisplay();
display.setCursor(15, 20);
display.println("Calibrated!");
display.setCursor(10, 35);
display.print("Baseline: ");
display.print(baseline_dbm, 1);
display.println(" dBm");
display.display();
delay(1000);
}
void updateDisplay() {
display.clearDisplay();
// Title
display.setCursor(0, 0);
display.print("RF Detector");
// Signal strength value
display.setCursor(0, 10);
display.print("Signal: ");
display.print(smoothed_dbm, 1);
display.print(" dBm");
// Baseline indicator
display.setCursor(0, 20);
display.print("Base: ");
display.print(baseline_dbm, 1);
display.print(" dBm");
// Alert indicator
if (calibrated && (smoothed_dbm > (baseline_dbm + ALERT_THRESHOLD_DB))) {
display.setCursor(80, 20);
display.print("ALERT!");
}
// Bar graph
int bar_width = SCREEN_WIDTH - 10;
int bar_height = 20;
int bar_x = 5;
int bar_y = 35;
// Draw bar background
display.drawRect(bar_x, bar_y, bar_width, bar_height, SSD1306_WHITE);
// Calculate bar fill based on dBm range
float bar_percent = (smoothed_dbm - BAR_MIN_DBM) / (BAR_MAX_DBM - BAR_MIN_DBM);
bar_percent = constrain(bar_percent, 0.0, 1.0);
// Fill bar
int fill_width = (int)(bar_percent * (bar_width - 2));
if (fill_width > 0) {
display.fillRect(bar_x + 1, bar_y + 1, fill_width, bar_height - 2, SSD1306_WHITE);
}
// Draw scale markers
for (int i = 0; i <= 4; i++) {
int marker_x = bar_x + (i * (bar_width - 2) / 4);
display.drawLine(marker_x, bar_y + bar_height, marker_x, bar_y + bar_height + 3, SSD1306_WHITE);
}
// Scale labels
display.setCursor(5, 58);
display.print((int)BAR_MIN_DBM);
display.setCursor(100, 58);
display.print((int)BAR_MAX_DBM);
display.display();
}
void updateBuzzer() {
// Calculate beep interval based on signal strength
float signal_above_baseline = smoothed_dbm - baseline_dbm;
// [TUNE] Adjust these thresholds for your environment
float min_signal = 0.0; // dB above baseline for slowest beep
float max_signal = 20.0; // dB above baseline for fastest beep
// Map signal strength to beep interval
float beep_interval = mapFloat(signal_above_baseline, min_signal, max_signal,
MIN_BEEP_INTERVAL_MS, MAX_BEEP_INTERVAL_MS);
beep_interval = constrain(beep_interval, MAX_BEEP_INTERVAL_MS, MIN_BEEP_INTERVAL_MS);
// Only beep if signal is above baseline
if (signal_above_baseline > 0.5) {
unsigned long now = millis();
if (now - last_beep_time >= beep_interval) {
last_beep_time = now;
tone(BUZZER_PIN, 2000, BEEP_DURATION_MS); // [TUNE] Adjust frequency
}
} else {
// No beep when below baseline
noTone(BUZZER_PIN);
}
}
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개