Hi, guys! I am trying to build dummy VLF SDR receiver using arduino internal ADC and FHT transform, but without any success yet. I am using voltage divider (2*10k resistors) and 1M input resistor with 10-ft wire as antenna (like in Lightning detector example), but I am unable to see even 50 Hz bin, as expected, but viewing only DC spike. Then, to check the software part I've built another voltage divider (10k to ground + 10k LDR other leg), and got that code works well enough, showing to me 28 and sometimes 60 Hz peak value (may be from my room`s LED bulbs? or probably from my TFT's @60 Hz refresh rate?) and sometimes high pulsations like 138 Hz or 174 Hz.
So, why am I able to see only the noise floor and DC using "antenna"? May be need a longer wire, about 500 ft? Or to build some kind of pre-amp before digitizing analog input?
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define PWM_PIN 3 // Display LED PWM pin
#define TFT_PIN_RST 8 // Arduino Reset-Pin
#define TFT_PIN_DC 9 // Arduino-Pin an
#define TFT_PIN_CS 10 // Arduino-Pin an Display CS
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_RST);
#define LOG_OUT 1 // use the log output function
#define FHT_N 256 // set to 256 point fht
#include <FHT.h> // include the library
#define DELAY_SAMPLING true
//#undef DELAY_SAMPLING
void setup() {
Serial.begin(115200); // use the serial port
// start display led
pinMode(PWM_PIN, OUTPUT);
analogWrite(PWM_PIN, 150);
// start display
tft.initR(INITR_BLACKTAB);
tft.fillScreen(ST7735_BLACK);
tft.setTextWrap(false);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
#ifdef DELAY_SAMPLING
pinMode(A3, INPUT);
#else
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
//ADMUX = 0x40; // use adc0
//DIDR0 = 0x01; // turn off the digital input for adc0
ADMUX = 0x43; // use adc3
#endif
}
void loop() {
while (1) { // reduces jitter
#ifndef DELAY_SAMPLING
cli(); // UDRE interrupt slows this way down on arduino1.0
#endif
for (int i = 0 ; i < FHT_N ; i++) { // save 256 samples
#ifdef DELAY_SAMPLING
fht_input[i] = analogRead(A3); // put real data into bins
delay(1); // sampling with 1kHz frequency => 4 Hz/bin, 512 Hz fft spectrum
// no delay - sampling with about 9600 Hz => 37 Hz
#else
// sampling with ~38kHz frequency => 150 Hz bin, 19 kHz fft spectrum
while (!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fht_input[i] = k; // put real data into bins
#endif
}
fht_window(); // window the data for better frequency response
fht_reorder(); // reorder the data before doing the fht
fht_run(); // process the data in the fht
fht_mag_log(); // take the output of the fht
#ifndef DELAY_SAMPLING
sei(); // UDRE interrupt slows this way down on arduino1.0
#endif
tft.fillScreen(ST7735_BLACK);
// get highest freq for 1 kHz sampling
int highest = 0;
int bin = 0;
for ( byte i = 2; i < FHT_N / 2; i++ )
{
if ( fht_log_out[i] > highest )
{
highest = fht_log_out[i];
bin = i;
}
}
tft.setCursor(1, 1);
tft.print(bin * 4);
tft.print(F(" Hz"));
for (byte i = 0; i < FHT_N / 2; i++)
{
#ifdef DELAY_SAMPLING
if ( i == 13 ) {
// tft.drawLine(i, 160, i, 160 - 128, ST7735_RED); // 50 Hz
}
#else
if ( i == 67 ) {
// tft.drawLine(i, 160, i, 160 - 128, ST7735_YELLOW); // 10 kHz
}
#endif
tft.drawLine(i, 160, i, 160 - fht_log_out[i] / 2, ST7735_GREEN);
}
/*
// to delphi
Serial.write(255); // send a start byte
Serial.write(fht_log_out, FHT_N / 2); // send out the data
Serial.flush();
*/
/*
// to serial monitor or plotter
for (int i = 0; i < FHT_N / 2; i++)
{
Serial.print( fht_log_out[i], DEC );
Serial.print( F(" ") );
}
Serial.println();
Serial.flush();
// delay(1000);
*/
}
}