Skip to content

Instantly share code, notes, and snippets.

@alexanderturner
Created June 3, 2023 05:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexanderturner/4db1ab26450ae84493e041d8a093c9ff to your computer and use it in GitHub Desktop.
Save alexanderturner/4db1ab26450ae84493e041d8a093c9ff to your computer and use it in GitHub Desktop.
HackRF One SDR FFT
#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(&currentTime, 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