Go Down

Topic: Arduino VLF SDR + FHT (Read 250 times) previous topic - next topic

megavoid

Mar 01, 2017, 03:37 pm Last Edit: Mar 01, 2017, 04:16 pm by megavoid
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?

Code: [Select]

#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);
    */
  }
}

Go Up