AD9850 Arduino vfo
AD9850 Arduino vfo
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
};
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
};
Re: AD9850 Arduino vfo
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.
Anders eens kijken op het geselecteerde stukje in de code. Daar wordt de frequentie omgerekend met de offset.
.... But will it blend?
Re: AD9850 Arduino vfo
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
// 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).
"Nescius omnium curiosus sum" (Ik weet niets maar ben nieuwsgierig naar alles).
Re: AD9850 Arduino vfo
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?
Re: AD9850 Arduino vfo
Je kunt de 9Mhz er toch bij optellen??
if (GoIF == 1){frequency=frequency+iffreq;};
if (GoIF == 1){frequency=frequency+iffreq;};
73's Egbert PAØEJH. Licensed since 1971.
En meer dan 50 Jaar radio-actief
En meer dan 50 Jaar radio-actief
Re: AD9850 Arduino vfo
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.
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.
Re: AD9850 Arduino vfo
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
En meer dan 50 Jaar radio-actief
Re: AD9850 Arduino vfo
idd voor ontvanger van 0-30
12mhz start de boel alleen mee op.
12mhz start de boel alleen mee op.
Re: AD9850 Arduino vfo
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.
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.
73's Egbert PAØEJH. Licensed since 1971.
En meer dan 50 Jaar radio-actief
En meer dan 50 Jaar radio-actief
Re: AD9850 Arduino vfo
Wordt van het weekend dat ik het kan testen(is namelijk voor mijn vader)
Laat het dan direkt weten
Laat het dan direkt weten
- PA1EJO
- Berichten: 226
- Lid geworden op: 29 feb 2016, 08:28
- Roepletters: PA1EJO
- Locatie: Rotterdam
- Contacteer:
Re: AD9850 Arduino vfo
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
73 Ernst, PA1EJO
Re: AD9850 Arduino vfo
Code geprobeerd maar zonder succes
Re: AD9850 Arduino vfo
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 .
Re: AD9850 Arduino vfo
Niemand suggesties verder?