AD9850 Arduino vfo

Hardware en software.
Bericht
Auteur
pe1ryx
Berichten: 19
Lid geworden op: 06 mar 2014, 19:53
Roepletters: pe1ryx

AD9850 Arduino vfo

#1 Bericht door pe1ryx »

Hallo,

Ben bezig met een arduino based vfo.
Als code gebruik ik de sketch van AD7C
Hoe krijg ik de offset nu de andere kant op?
Iffreq is 9mhz

Op dit moment is de frequentie die uit de schakeling komt 9mhz lager dan wat er op het display weergegeven word.
Hoe draai je dit om?

Ben nieuw met Arduino derhalve kom ik er niet uit.

Tevens zou het mooi zijn om de stappen die je met de Rotary-encoder maakt ook in 2 richtingen zou kunnen up en down??

Kan iemand me hiermee verder helpen?

Alvast dank!

Code die ik er nu in heb staan is deze:



*/

// Include the library code
#include <LiquidCrystal.h>
#include <rotary.h>
#include <EEPROM.h>

//Setup some items
#define W_CLK 8 // Pin 8 - connect to AD9851 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 pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses. Must be interrupt pins.
LiquidCrystal lcd(12, 13, 7, 6, 5, 4); // I used an odd pin combination because I need pin 2 and 3 for the interrupts.
int_fast32_t rx=12000000; // Base (starting) frequency of VFO. This only loads once. To force load again see ForceFreq variable below.
int_fast32_t rx2=1; // variable to hold the updated frequency
int_fast32_t increment = 10; // starting VFO update increment in HZ.
int_fast32_t iffreq = 9000000; // Intermedite Frequency - Amount to subtract (-) from base frequency. ********************************************
int buttonstate = 0;
int buttonstate2 = 0;
int GoIF = 1;
String hertz = "10 Hz";
int hertzPosition = 5;
byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ; //Placeholders
String freq; // string to hold the frequency
int_fast32_t timepassed = millis(); // int to hold the arduino miilis since startup
int memstatus = 1; // value to notify if memory is current or old. 0=old, 1=current.


int ForceFreq = 1; // Change this to 0 after you upload and run a working sketch to activate the EEPROM memory. YOU MUST PUT THIS BACK TO 0 AND UPLOAD THE SKETCH AGAIN AFTER STARTING FREQUENCY IS SET!



void setup() {
pinMode(A0,INPUT); // Connect to a button that goes to GND on push
pinMode(A5,INPUT); // IF sense **********************************************
digitalWrite(A0,HIGH);
digitalWrite(A5,HIGH);
lcd.begin(16, 2);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
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 on the AD9851 - Datasheet page 12.
lcd.setCursor(hertzPosition,1);
lcd.print(hertz);

// Load the stored frequency
if (ForceFreq == 0) {
freq = String(EEPROM.read(0))+String(EEPROM.read(1))+String(EEPROM.read(2))+String(EEPROM.read(3))+String(EEPROM.read(4))+String(EEPROM.read(5))+String(EEPROM.read(6));
rx = freq.toInt();
}
}

void loop() {
// Update the display and frequency if the new Freq NEQ the old Freq
if (rx != rx2){
showFreq();
sendFrequency(rx);
rx2 = rx;
}

// Rotate through the rate of tuning as you hold down the button
buttonstate = digitalRead(A0);
if(buttonstate == LOW) {
setincrement();
};

// Check for PIN low to drive IF offset Freq
buttonstate = digitalRead(A5);
if (buttonstate != buttonstate2){
if(buttonstate == LOW) {
lcd.setCursor(15,1);
lcd.print(".");
GoIF = 0;
buttonstate2 = buttonstate;
sendFrequency(rx);
}
else{
lcd.setCursor(15,1);
lcd.print(" ");
GoIF = 1;
buttonstate2 = buttonstate;
sendFrequency(rx);
};
};

// Write the frequency to memory if not stored and 2 seconds have passed since the last frequency change.
if(memstatus == 0){
if(timepassed+2000 < millis()){
storeMEM();
}
}

}


// Interrupt routine to catch the rotary encoder
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result) {
if (result == DIR_CW){rx=rx+increment;}
else {rx=rx-increment;};
if (rx >=39000000){rx=rx2;}; // UPPER VFO LIMIT
if (rx <=9000000){rx=rx2;}; // LOWER VFO LIMIT
}
}

// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
void sendFrequency(double frequency) {
if (GoIF == 1){frequency=frequency-iffreq;}; //If pin = low, subtract the IF frequency.
int32_t freq = frequency * 4294967295/125000000; // note 125 MHz clock on 9850. You can make 'slight' tuning variations here by adjusting the clock frequency.
for (int b=0; b<4; b++, freq>>=8) {
tfr_byte(freq & 0xFF);
}
tfr_byte(0x000); // Final control byte, all 0 for 9851 chip
pulseHigh(FQ_UD); // Done! Should see output
}
// transfers a byte, a bit at a time, LSB first to the 9851 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
}
}

void setincrement(){
if(increment == 10){increment = 100; hertz = "100 Hz"; hertzPosition=4;}
else if (increment == 100){increment = 1000; hertz="1 Khz"; hertzPosition=6;}
else if (increment == 1000){increment = 10000; hertz="10 Khz"; hertzPosition=5;}
else if (increment == 10000){increment = 100000; hertz="100 Khz"; hertzPosition=4;}
else if (increment == 100000){increment = 1000000; hertz="1 Mhz"; hertzPosition=6;}
else{increment = 10; hertz = "10 Hz"; hertzPosition=5;};
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(hertzPosition,1);
lcd.print(hertz);
delay(250); // Adjust this delay to speed up/slow down the button menu scroll speed.
};

void showFreq(){
millions = int(rx/1000000);
hundredthousands = ((rx/100000)%10);
tenthousands = ((rx/10000)%10);
thousands = ((rx/1000)%10);
hundreds = ((rx/100)%10);
tens = ((rx/10)%10);
ones = ((rx/1)%10);
lcd.setCursor(0,0);
lcd.print(" ");
if (millions > 9){lcd.setCursor(1,0);}
else{lcd.setCursor(2,0);}
lcd.print(millions);
lcd.print(".");
lcd.print(hundredthousands);
lcd.print(tenthousands);
lcd.print(thousands);
lcd.print(".");
lcd.print(hundreds);
lcd.print(tens);
lcd.print(ones);
lcd.print(" Mhz ");
timepassed = millis();
memstatus = 0; // Trigger memory write
};

void storeMEM(){
//Write each frequency section to a EPROM slot. Yes, it's cheating but it works!
EEPROM.write(0,millions);
EEPROM.write(1,hundredthousands);
EEPROM.write(2,tenthousands);
EEPROM.write(3,thousands);
EEPROM.write(4,hundreds);
EEPROM.write(5,tens);
EEPROM.write(6,ones);
memstatus = 1; // Let program know memory has been written
};

PA3BAS
Berichten: 2609
Lid geworden op: 07 jan 2011, 22:19
Roepletters: PA3BAS
Locatie: JO21XX

Re: AD9850 Arduino vfo

#2 Bericht door PA3BAS »

Probeer de offset eens negatief in te geven als dat kan.

Anders eens kijken op het geselecteerde stukje in de code. Daar wordt de frequentie omgerekend met de offset.
Bijlagen
image.png
.... But will it blend?

PE1LGW
Berichten: 975
Lid geworden op: 18 mar 2010, 10:29
Roepletters: pe1lgw
Locatie: eindhoven

Re: AD9850 Arduino vfo

#3 Bericht door PE1LGW »

Software voor ziet wel voor de twee richtingen, van het instellen van de waarde

// Interrupt routine to catch the rotary encoder
ISR(PCINT2_vect) { unsigned char result = r.process();
if (result) { if (result == DIR_CW){rx=rx+increment;}
else {rx=rx-increment;};
if (rx >=39000000){rx=rx2;}; // UPPER VFO LIMIT if
(rx <=9000000){rx=rx2;}; // LOWER VFO LIMIT } }

Als op de site kijk van ad7c kijk lijkt of de encoder maar aan een is aangesloten, dan gaat hij maar een kant op.
Denk ook aan de pullup weerstanden.
Kijk even op het internet, naar voorbeelden
In de sketch worden hier pin 2 en 3 gebruikt.


MVG Rens wilde
Pe1lgw
Condor 3000, Icom7000 IC2 E, IC25, FT270, FT11, RS9044, Teleport 9, Kenwood TR2400, TMG 707, Diamond x30, realistic 2005 scanner, home made J antenne. tevens rust huis voor T813 sets, Boafeng UV-5R, TYT UV3R, DVB sticky SDR, Nokia Mobira, Philips FM1000, Yeasu vx3, ft817.
"Nescius omnium curiosus sum" (Ik weet niets maar ben nieuwsgierig naar alles).

PA3BAS
Berichten: 2609
Lid geworden op: 07 jan 2011, 22:19
Roepletters: PA3BAS
Locatie: JO21XX

Re: AD9850 Arduino vfo

#4 Bericht door PA3BAS »

De offset wordt gegeven met een getal. Volgens mij kan daar geen negatief getal in, het is een int, maar misschien heb ik ongelijk. 20 + (-30) is volgens mij -10.
.... But will it blend?

EA5JEX
Berichten: 1472
Lid geworden op: 14 nov 2007, 18:56
Roepletters: pa5cw
Locatie: Pedralba Valencia Spanje

Re: AD9850 Arduino vfo

#5 Bericht door EA5JEX »

Hier http://m0xpd.blogspot.nl/p/kanga-uk-resources.html#DDS vind je ook veel voorbeelden.

Kees

Gebruikersavatar
pa0ejh
Berichten: 1889
Lid geworden op: 05 mei 2008, 13:23
Roepletters: PA0EJH
Locatie: Brunssum

Re: AD9850 Arduino vfo

#6 Bericht door pa0ejh »

Je kunt de 9Mhz er toch bij optellen??

if (GoIF == 1){frequency=frequency+iffreq;};
73's Egbert PAØEJH. Licensed since 1971.
En meer dan 50 Jaar radio-actief

pe1ryx
Berichten: 19
Lid geworden op: 06 mar 2014, 19:53
Roepletters: pe1ryx

Re: AD9850 Arduino vfo

#7 Bericht door pe1ryx »

Heb geprobeerd een + van een - te maken maar helaas krijg het niet voor elkaar.

Dit is hoe AD7C zelf dacht hoe het moet;



if(b1 == LOW) {
lcd.setCursor(15,1);
lcd.print(".");

rx=rx+iffreq; <---------------------- This displays the LCD as the frequency + the IF. Put this in the area down below.
b2 = b1;
sendFrequency(rx);
}
else{
lcd.setCursor(15,1);
lcd.print(" ");
rx=rx-iffreq; <------------------------ Move this to the area up above.
b2 = b1;
sendFrequency(rx);

};



heb dit er ook in gehad op allerlei manieren maar ook dit werkt niet.

Gebruikersavatar
pa0ejh
Berichten: 1889
Lid geworden op: 05 mei 2008, 13:23
Roepletters: PA0EJH
Locatie: Brunssum

Re: AD9850 Arduino vfo

#8 Bericht door pa0ejh »

Ik neem aan dat het VFO voor een ontvanger is van 0-30Mhz ?? met een 9Mhz MF ?? en VFO =12Mhz ??
73's Egbert PAØEJH. Licensed since 1971.
En meer dan 50 Jaar radio-actief

pe1ryx
Berichten: 19
Lid geworden op: 06 mar 2014, 19:53
Roepletters: pe1ryx

Re: AD9850 Arduino vfo

#9 Bericht door pe1ryx »

idd voor ontvanger van 0-30

12mhz start de boel alleen mee op.

Gebruikersavatar
pa0ejh
Berichten: 1889
Lid geworden op: 05 mei 2008, 13:23
Roepletters: PA0EJH
Locatie: Brunssum

Re: AD9850 Arduino vfo

#10 Bericht door pa0ejh »

Probeer deze maar eens, we ff hernoemen naar INO want ik kan hem alleen maar als PDF hier plaatsen.

Overigens, ik werk met IDE 1.0.6 weet niet welke jij gebruikt, ik heb al verschillen gemerkt met hogere versies, maar dat gaat meestal om Timing problemen.
pe1ryx .pdf
(5.83 KiB) 259 keer gedownload
73's Egbert PAØEJH. Licensed since 1971.
En meer dan 50 Jaar radio-actief

pe1ryx
Berichten: 19
Lid geworden op: 06 mar 2014, 19:53
Roepletters: pe1ryx

Re: AD9850 Arduino vfo

#11 Bericht door pe1ryx »

Wordt van het weekend dat ik het kan testen(is namelijk voor mijn vader)

Laat het dan direkt weten

Gebruikersavatar
PA1EJO
Berichten: 226
Lid geworden op: 29 feb 2016, 08:28
Roepletters: PA1EJO
Locatie: Rotterdam
Contacteer:

Re: AD9850 Arduino vfo

#12 Bericht door PA1EJO »

Lijkt me een leuk experiment om met de AD9850 iets te gaan doen.
Zelden aanwezig op deze website vanwege de onzichtbare censuur
73 Ernst, PA1EJO

pe1ryx
Berichten: 19
Lid geworden op: 06 mar 2014, 19:53
Roepletters: pe1ryx

Re: AD9850 Arduino vfo

#13 Bericht door pe1ryx »

Code geprobeerd maar zonder succes :cry:

pd0sbr
Berichten: 162
Lid geworden op: 17 apr 2013, 23:17

Re: AD9850 Arduino vfo

#14 Bericht door pd0sbr »

Hallo heb van de codes niet zo veel verstand maar let op als je boven of onder in mengt dat LSB en USB ook om draait .

pe1ryx
Berichten: 19
Lid geworden op: 06 mar 2014, 19:53
Roepletters: pe1ryx

Re: AD9850 Arduino vfo

#15 Bericht door pe1ryx »

Niemand suggesties verder?

Plaats reactie