WSPR: Arduino sederhana

From OnnoWiki
Jump to navigation Jump to search

Sumber: http://blog.riyas.org/2015/01/weak-signals-and-random-piece-of-wire-arduino-ad9850-WSPR.html



/* 
 * A simple single freq AD9850 Arduino test script
 * Original AD9851 DDS sketch by Andrew Smallbone at www.rocketnumbernine.com
 * Modified for testing the inexpensive AD9850 ebay DDS modules
 * Pictures and pinouts at nr8o.dhlpilotcentral.com
 * 9850 datasheet at http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
 * From http://www.george-smart.co.uk/wiki/Arduino_WSPR
 *  modification by http://blog.riyas.org
 * Use freely
 */
 
#define W_CLK 8       // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 9       // Pin 9 - connect to freq update pin (FQ)
#define DATA 10       // Pin 10 - connect to serial data load pin (DATA)
#define RESET 11      // Pin 11 - connect to reset pin (RST).
#define LED       13 //flashes duty cycle
#define SWITCH    A0 // connect this to a switch and the other end to vcc via 10k resistor
#define CLOCKLED  3 //flash every seconds 

#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }

#define WSPR_TX_B     7.040000e6  // this is the bottom of the band. The station moves about.
// DDS Offset in Hz
#define DDS_OSET  50  //DDS #2
#define WSPR_DUTY  3 // transmit every N slices.

// WSPR Tone Data - line breaks in no parciular place, just to look pretty. (0-161).
//callsign locator power in dbm
// to bulid this array see:http://www.george-smart.co.uk/wiki/Arduino_WSPR
static byte WSPR_DATA_HOME[] = {1,1,0,0,1,1,0,0,3,0,0,2,3,3,1,2,2,2,1,2,2,1,0,3,3,3,3,0,0,2,0,2,...................................,2}; 

#define WSPR_DATA WSPR_DATA_HOME

#include <stdint.h>

// Variables
unsigned long  WSPR_TXF = 0;
unsigned long minute =1;
unsigned long seconds=0;
unsigned long tstart=0;


unsigned long startT = 0, stopT = 0;
char sz[32];
int duty=0;
int val=0;
int band=0;
 
// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
void tfr_byte(byte data)
{
  for (int i=0; i<8; i++, data>>=1) {
    digitalWrite(DATA, data & 0x01);
    pulseHigh(W_CLK);   //after each bit sent, CLK is pulsed high
  }
}
// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
void sendFrequency(double frequency) {
  int32_t freq = frequency * 4294967295/125000000;  // note 125 MHz clock on 9850
  for (int b=0; b<4; b++, freq>>=8) {
    tfr_byte(freq & 0xFF);
  }
  tfr_byte(0x000);   // Final control byte, all 0 for 9850 chip
  pulseHigh(FQ_UD);  // Done!  Should see output
}

void setup() {
 // configure arduino data pins for output
  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(RESET, OUTPUT);
    
  pulseHigh(RESET);
  pulseHigh(W_CLK);
  pulseHigh(FQ_UD);  // this pulse enables serial mode - Datasheet page 12 figure 10
  
  pinMode (LED,       OUTPUT);
  pinMode (CLOCKLED,       OUTPUT);
  pinMode(SWITCH, INPUT);
  
 
  Serial.begin(9600);
  
  sprintf(sz, "\nLB7UG Compiled %s %s", __TIME__, __DATE__);
  Serial.println(sz);  
  Serial.print("\n\nDDS Reset   ");
  delay(900);
  delay(100);
  Serial.println("OK");  
  duty = 0;  
 

}

void loop() {


  //let us make a poor mans clock which needs a click on SWITCH pin to high at an even minute
        
         val=analogRead(SWITCH);
         //Serial.println(val);
         if (val == 1023) { 
          //reset the clock here
     tstart = millis()/1000UL;
         wsprTX(); 
         Serial.println(tstart);
     }

     //WSPR_TXF = (WSPR_TX_B+DDS_OSET) + random(10, 190); // always choose a frequency,  a little with the pRNG.
     WSPR_TXF = (WSPR_TX_B+DDS_OSET); // always choose a frequency,  a little with the pRNG.
          //wsprTX();
         // UPDATING TIME DO NOT INSERT COMMANDS BELOW!!
     seconds=(millis()/1000UL)-tstart;
     minute= seconds/60UL; 
         //Serial.println(minute);

      if ( (minute % 2 == 0) && (minute > 1) && (seconds >= 1) && (seconds <= 4) ) {  // start transmission 
        //if (duty % WSPR_DUTY == 0) {
          if (1) {
          //Serial.print("Beginning WSPR Transmission on ");
          //Serial.print(WSPR_TXF-DDS_OSET);
          //Serial.println(" Hz.");
          wsprTX();
          duty++;
          band++;
          //Serial.println(" Transmission Finished.");    
        } else {
          duty++;
          digitalWrite (LED, LOW);          
          flash_led(WSPR_DUTY, LED); // flash the WSPR duty.
        }
      }
     //update time again 
     seconds=(millis()/1000UL)-tstart;  

     if ((seconds % 2 ==0) && (tstart!=0)){  // oru bhangikku vendi
     digitalWrite(CLOCKLED, HIGH);
     }
     else
     {
     digitalWrite(CLOCKLED, LOW);
     }
      
 } 
 

void flash_led(unsigned int t, int l) {
  unsigned int i = 0;
  if (t > 25) {
    digitalWrite(l, HIGH);
    delay(2000);
    digitalWrite(l, LOW);
  } else {
    for (i=0;i<t;i++) {
      digitalWrite(l, HIGH);
      delay(250);
      digitalWrite(l, LOW);
      delay(250);
    }
  }
}
  
void wsprTX() {
  int i = 0; 

  digitalWrite(LED, HIGH);
  for (i=0;i<162;i++) {
    wsprTXtone( WSPR_DATA[i] );
    delay(682);
  }
  sendFrequency(0);
  digitalWrite(LED, LOW);
}
    
void wsprTXtone(int t) {
  if ((t >= 0) && (t <= 3) ) {
     //Serial.print((WSPR_TXF + (t * 2)));
    sendFrequency((WSPR_TXF + (t * 2))); // should really be 1.4648 Hz not 2.
  } else {
    Serial.print("Tone #");
    Serial.print(t);
    Serial.println(" is not valid.  (0 <= t <= 3).");
  }
} 



Referensi