Created
June 3, 2023 05:02
-
-
Save alexanderturner/4db1ab26450ae84493e041d8a093c9ff to your computer and use it in GitHub Desktop.
HackRF One SDR FFT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <math.h> | |
#include <libhackrf/hackrf.h> | |
#include <fftw3.h> | |
#include <sys/time.h> // Added for gettimeofday | |
#define SAMPLE_RATE 20000000 // Sample rate in Hz | |
#define DEFAULT_BASEBAND_FILTER_BANDWIDTH (12500) | |
#define CHANNEL_FREQUENCY 476650000 // Center frequency in Hz | |
#define SIGNAL_FREQUENCY 476650000 // FM signal frequency in Hz | |
#define SIGNAL_BANDWIDTH 1250 // FM signal bandwidth in Hz | |
#define SIGNAL_THRESHOLD_DB 58 // Threshold in dB for detecting FM signal | |
#define PULSE_DURATION 500 // Duration of a single pulse in microseconds | |
#define NUM_PULSES 3 // Number of key-on pulses to detect before timeout | |
#define TIMEOUT_DURATION 5000000 // Timeout duration in microseconds (5 seconds) | |
typedef enum { | |
STATE_IDLE, | |
STATE_DETECT_KEY_ON, | |
STATE_TIMER_RUNNING | |
} State; | |
static int64_t lastKeyOnTime = 0; | |
static int pulseCount = 0; | |
static State state = STATE_IDLE; | |
int64_t getTimeInMicroseconds() { | |
struct timeval currentTime; | |
gettimeofday(¤tTime, NULL); | |
return currentTime.tv_sec * 1000000 + currentTime.tv_usec; | |
} | |
int hackrf_callback(hackrf_transfer* transfer) { | |
int16_t* samples = (int16_t*)transfer->buffer; | |
int numSamples = transfer->valid_length / sizeof(int16_t); | |
int consecutiveSamples = 0; | |
double pulseThreshold = 0.0; | |
int fftSize = 20; | |
// Perform FFT analysis on the received samples | |
fftw_complex* fftInput = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * numSamples); | |
fftw_complex* fftOutput = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * numSamples); | |
fftw_plan fftPlan = fftw_plan_dft_1d(numSamples, fftInput, fftOutput, FFTW_FORWARD, FFTW_ESTIMATE); | |
// Copy samples to FFT input array | |
for (int i = 0; i < numSamples; i++) { | |
// max[i] = 0; | |
fftInput[i][0] = (double)samples[i]; | |
fftInput[i][1] = 0.0; | |
} | |
// Perform FFT | |
fftw_execute(fftPlan); | |
// // Calculate the frequency range for the bandpass filter | |
double binSize = SAMPLE_RATE / numSamples; | |
double firstBin = SIGNAL_FREQUENCY - (SAMPLE_RATE / 2.0); | |
// | |
// // Calculate the frequency bins for the signal bandwidth | |
int startBin = round(((SIGNAL_FREQUENCY - (SIGNAL_BANDWIDTH/2)) - firstBin) / binSize); | |
int endBin = round(((SIGNAL_FREQUENCY + (SIGNAL_BANDWIDTH/2)) - firstBin) / binSize); | |
double signalPower = 0.0; | |
for (int i = startBin; i <= endBin; i++) { | |
double real = fftOutput[i][0] * 1.0f / fftSize; | |
double imag = fftOutput[i][1] * 1.0f / fftSize; | |
signalPower += (real * real) + (imag * imag); | |
} | |
signalPower /= (endBin - startBin) + 1; | |
double signalPowerdBm = log2(signalPower) * 10.0f / log2(10.0f); | |
printf("val: %f\n", signalPowerdBm); | |
// Cleanup FFT resources | |
fftw_destroy_plan(fftPlan); | |
fftw_free(fftInput); | |
fftw_free(fftOutput); | |
return 0; | |
} | |
int main() { | |
hackrf_device* device; | |
int result; | |
// Initialize hackrf library | |
result = hackrf_init(); | |
if (result != HACKRF_SUCCESS) { | |
fprintf(stderr, "Failed to initialize hackrf library.\n"); | |
return EXIT_FAILURE; | |
} | |
// Open hackrf device | |
result = hackrf_open(&device); | |
if (result != HACKRF_SUCCESS) { | |
fprintf(stderr, "Failed to open hackrf device.\n"); | |
hackrf_exit(); | |
return EXIT_FAILURE; | |
} | |
// Set sample rate | |
result = hackrf_set_sample_rate(device, SAMPLE_RATE); | |
if (result != HACKRF_SUCCESS) { | |
fprintf(stderr, "Failed to set sample rate.\n"); | |
hackrf_close(device); | |
hackrf_exit(); | |
return EXIT_FAILURE; | |
} | |
// Set center frequency | |
result = hackrf_set_freq(device, CHANNEL_FREQUENCY); | |
if (result != HACKRF_SUCCESS) { | |
fprintf(stderr, "Failed to set center frequency.\n"); | |
hackrf_close(device); | |
hackrf_exit(); | |
return EXIT_FAILURE; | |
} | |
result = hackrf_set_baseband_filter_bandwidth(device, DEFAULT_BASEBAND_FILTER_BANDWIDTH); | |
if (result != HACKRF_SUCCESS) { | |
fprintf(stderr,"hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); | |
return EXIT_FAILURE; | |
} | |
// Start receiving samples | |
result = hackrf_start_rx(device, hackrf_callback, NULL); | |
if (result != HACKRF_SUCCESS) { | |
fprintf(stderr, "Failed to start receiving samples.\n"); | |
hackrf_close(device); | |
hackrf_exit(); | |
return EXIT_FAILURE; | |
} | |
int64_t startTime = getTimeInMicroseconds(); | |
while (1) { | |
// usleep(10000); // Sleep for 10 milliseconds | |
int64_t currentTime = getTimeInMicroseconds(); | |
} | |
// Stop receiving samples | |
hackrf_stop_rx(device); | |
// Close hackrf device | |
hackrf_close(device); | |
// Cleanup hackrf library | |
hackrf_exit(); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment