Transceptor QRP Chingolito

//08/05: Vuelto a LSB

//28/03: USB en 40m, cambie frec inyeccion del DDS y rutina que suma/resta FI al TX.

// Hay que corroborar si TX y RX en misma frec.

//26/03: volvi a LSB en 40m. Agregue un decimal mas al dial.

//12/03: Cambie banda de 40m a USB solo RX.

//11/03: agrande rango a 100 KHz de cada banda para experimentar RX de WSPR

//22/02: afine valores de ADC del pote de opcion banda/step

//18/02: se saco divisor resisitivo para cambio banda/step,

//se reemplazo por un potenciometro en A6. Ademas se incorpora

//activación del rele del medidor de ROE por arduino seleccionandolo

//con la perilla de funciones que sirve para configurar usos del dial.

//Mensaje de inicio agregado.

//16/02: modificado texto del display

//11/02: modificado maxi para que sea 2000, no mas 2048.

//10/02: Agregado XIT y limpieza RIT/XIT on dial-

//10/02: Solucionado problema RIT, no mas pote, uso mismo encoder del dial.

//Solucionar seleccion de dial o clarificador con segundo pote...

// 09/02 agregado lectura ADC para RIT, apagado en extremos del pote.

//PROBLEMA: lectura del ADC varia con ruido y hace variar frec TX <<<<=====

// 07/02 modificado para TX y RX en misma frecuencia e inicios de banda.

// 04/02 modificado paso de 100 y 500 hz, y modificado a solo 40 khz de banda y lcd

//22/01/2017 - 14:30 Hs. Malargue.

//Manipulador implementado por interrupcion

//Sintonia implementada por interrupcion

//Banda y paso de sintonia implementado mediante ADC en loop principal

//FI de 7MHZ seteada en 44319000

#include <math.h>

#include <LiquidCrystal.h>

volatile unsigned long int shift=0,stepp=1,FREC,rit=1024,ritt=0,rit_on,xit=1024,xitt=0;

int base=0;

volatile int TX=0;

LiquidCrystal lcd(14,13,19,18,17,16);

//RS-EN-D4-D5-D6-D7

#define mini 0.0

#define maxi 2000.0

#define diferencia 0 //diferencia entre frec real y mostrada en display

//60 = 600 Hz

#define RS 14 //A0 // define nombres de los pines del LCD

#define EN 13 //D13-LED

#define D4 19 //A5 Dato 4 LCD

#define D5 18 //A4 Dato 5 LCD

#define D6 17 //A3 Dato 6 LCD

#define D7 16 //A2 Dato 7 LCD

#define A 2 //D2 - INT0: encoder, pin 1

#define B 4 //D4 - encoder pin 2

#define RXTX 3 //D3 - INT1: manipulador, cambio de RX a TX.

//#define LED 13

#define FREC7 114314500 //OK - 7.000MHZ por arriba cristal rojo (recibe bien LSB)

//#define FREC7 25685500 //USB??? cambiar rutina que suma o resta frec, sino solo funciona RX

#define FREC14 95687000 //OK - 14.000MHZ por abajo USB

//#define FREC14 96357000 //OK - 14.068MHZ por abajo

#define REFCLK 1250000000 //Referencia del DDS

#define TUNE_Range 100 //Rango sintonia KHz

#define RIT_Range 5 //Rango RIT +/- KHz

#define XIT_Range 5 //Rango XIT +/- KHz

#define FASE 0

#define data 6 //D6 - Pin DDS

#define fqud 7 //D7 - Pin DDS

#define clk 8 //D8 - Pin DDS

#define RELE 9 //D9 - Pin que activa rele de cambio de banda.

#define SWR 15 //A1 - pin que activa rele de medidor de ROE SWR

#define FI07 44313500 //OK- Frecuencia intermedia 7MHZ OK.

#define FI14 44314500 //OK - Frecuencia intermedia 14MHZ OK.

void setup(){

pinMode(A,INPUT_PULLUP); //Pull Up de entrada.

pinMode(B,INPUT_PULLUP);

pinMode(RXTX,INPUT_PULLUP);

// pinMode(LED, OUTPUT);

FREC=FREC7; //Frecuencia de arranque del equipo

pinMode(13, OUTPUT); //LED

pinMode(data, OUTPUT); //pines DDS

pinMode(fqud, OUTPUT); //pines DDS

pinMode(clk, OUTPUT); //pines DDS

pinMode(SWR, OUTPUT); //rele medidor de ROE

pinMode(A0, OUTPUT); //declaro algunos pines analogicos como salidas digitales

pinMode(A1, OUTPUT); //rele de medidor de roe

pinMode(A2, OUTPUT);

pinMode(A3, OUTPUT);

pinMode(A4, OUTPUT);

pinMode(A5, OUTPUT);

attachInterrupt(digitalPinToInterrupt(A),ISR_encoder,FALLING); //Uso falling porque tienen pullup las entradas

attachInterrupt(digitalPinToInterrupt(RXTX),ISR_key,CHANGE); //Detecta suba o baja del manipulador

Serial.begin(9600);

lcd.begin(16, 2); //seteo numero de columnas y filas del display

lcd.setCursor(0, 0);

lcd.print("QRP Chingolito "); //Imprimo mensaje

lcd.setCursor(0, 1);

lcd.print("LU3HO 3W 40/20m "); //Imprimo mensaje

delay(5000);

lcd.setCursor(0, 0);

lcd.print(" "); //Imprimo mensaje

lcd.setCursor(0, 1);

lcd.print(" "); //Imprimo mensaje

}

void loop(){

unsigned long int opt=analogRead(A6); //Lectura de los interruptores de banda y paso de sintonia

rit_on=analogRead(A7); //Lectura potenciometro de RIT

int opcion=step_band(opt); //360-300-190-0 las 4 opciones

unsigned long int shiftt;

Serial.print(opt);Serial.print("\n");

swr_meter(rit_on);

shiftt=shift*TUNE_Range*5; //sintonia= 40 KHz

ritt=(rit-1024)*RIT_Range*10; //rit= 5KHz

xitt=(xit-1024)*XIT_Range*10;

lcd_display(opcion); //escritura display

AD9851_SetFreq(FREC+shiftt+ritt,FASE); //Pone un dds en 0° y el otro en 90°.

}

//__________________________________________________________________

int lcd_display(int opcion){

char texto[16];

long int rita,xita;

lcd.setCursor(0, 0); //banda

if(opcion==1 || opcion==3)

lcd.print("14,");

else

lcd.print(" 7,");

lcd.setCursor(3, 0); //frecuencia

sprintf(texto,"%.5d",(shift)*TUNE_Range/20);

lcd.print(texto);

lcd.setCursor(8, 0);

lcd.print("MHz");

lcd.setCursor(12, 0); //Opcion dial de comando(pote)

if(rit_on<=200)

lcd.print("S"); //medidor de ROE /SWR

if(rit_on>200 && rit_on<=400)

lcd.print("F"); //comanda frecuencia

if(rit_on>400 && rit_on<600)

lcd.print("R"); //comanda RIT

if(rit_on>=600 && rit_on<800)

lcd.print("X"); //comanda XIT

if(rit_on>=800)

lcd.print("C"); //limpieza /Clear de RIT/XIT

lcd.setCursor(0, 1);

lcd.print("RX");

lcd.setCursor(2,1); //RIT

if(rit>=1024)

lcd.print("+");

if(rit<1024)

lcd.print("-");

rita=(rit-1024);

rita=pow(rita*rita,0.5); //valor absoluto del RIT

lcd.setCursor(3, 1); //frecuencia

sprintf(texto,"%.4d",rita*RIT_Range);

lcd.print(texto);

lcd.setCursor(8, 1); //XIT

lcd.print("TX");

lcd.setCursor(10,1);

if(xit>=1024)

lcd.print("+");

if(xit<1024)

lcd.print("-");

xita=(xit-1024);

xita=pow(xita*xita,0.5); //valor absoluto del XIT

lcd.setCursor(11, 1); //frecuencia

sprintf(texto,"%.4d",xita*XIT_Range);

lcd.print(texto);

}

//__________________________________________________________________

void swr_meter(int rit_on){ //funcion que activa rele medidor de roe

if(rit_on<=200){

digitalWrite(SWR,HIGH);

//activar rele pin A1

delayMicroseconds(1000);

}

else{

digitalWrite(SWR,LOW);

//desactivar rele pin A1

delayMicroseconds(1000);

}

}

//__________________________________________________________________

int step_band(unsigned long int opt){

if(opt>=0 && opt<150){ //40metros - 1 KHz if(opt>=330)

if(FREC==FREC14 || FREC==FREC14+FI14)

FREC=FREC7;

//stepp=10;

stepp=25;

digitalWrite(RELE,LOW);

lcd.setCursor(14, 0);

lcd.print("g");

return 0;

}

if(opt>=480 && opt<800){ //20metros - 1 KHz if(opt>=250 && opt<330)

if(FREC==FREC7 || FREC==FREC7-FI07)

FREC=FREC14;

//stepp=10;

stepp=25;

digitalWrite(RELE,HIGH);

lcd.setCursor(14, 0);

lcd.print("g");

return 1;

}

if(opt>=150 && opt<480){ //40metros - 100 Hz if(opt>=100 && opt<250)

if(FREC==FREC14 || FREC==FREC14+FI14)

FREC=FREC7;

stepp=1;

digitalWrite(RELE,LOW);

lcd.setCursor(14, 0);

lcd.print("f");

return 2;

}

if(opt>=800 && opt<=1023){ //20metros - 100 if(opt>=0 && opt<100)

if(FREC==FREC7 || FREC==FREC7-FI07)

FREC=FREC14;

stepp=1;

digitalWrite(RELE,HIGH);

lcd.setCursor(14, 0);

lcd.print("f");

return 3;

}

return 4;

}

//__________________________________________________________________

void ISR_encoder(){ //Parece que mas o menos anda...

if(rit_on>200 && rit_on<=400){ //comando dial principal

if(digitalRead(B)==0) //CW

if(shift<maxi &&((shift+stepp)<maxi))

//shift++;

shift=shift+stepp;

else

shift=maxi;

else //CCW

if(shift>mini &&((shift-stepp)>stepp))

//shift--;

shift=shift-stepp;

else

shift=mini;

delayMicroseconds(1000);//evita el rebote de los terminales

}

if(rit_on>400 && rit_on<600){ //comando dial secundario RIT

if(digitalRead(B)==0) //CW

if(rit<maxi &&((rit+stepp)<maxi))

//shift++;

rit=rit+stepp;

else

rit=maxi;

else //CCW

if(rit>mini &&((rit-stepp)>stepp))

//shift--;

rit=rit-stepp;

else

rit=mini;

delayMicroseconds(1000);//evita el rebote de los terminales

}

if(rit_on>=600 && rit_on<800){ //comando dial secundario RIT

if(digitalRead(B)==0) //CW

if(xit<maxi &&((xit+stepp)<maxi))

//shift++;

xit=xit+stepp;

else

xit=maxi;

else //CCW

if(xit>mini &&((xit-stepp)>stepp))

//shift--;

xit=xit-stepp;

else

xit=mini;

delayMicroseconds(1000);//evita el rebote de los terminales

}

if(rit_on>=800){ //comando dial secundario RIT

if(digitalRead(B)==0) //CW

xit=1024;

else //CCW

rit=1024;

delayMicroseconds(1000);//evita el rebote de los terminales

}

}

//__________________________________________________________________

void ISR_key(){ //cambia frecuencia del oscilador al TX

if(digitalRead(RXTX)==0)

TX=1;

else

TX=0;

/* Original LSB, anda bien

if(FREC==FREC7||(FREC>=FREC7-FI07-100000 && FREC<=FREC7-FI07+100000)){

if(digitalRead(RXTX)==0) //se presiono manipulador

FREC=FREC7-FI07-ritt+xitt; //LSB-> resta

else //se solto manipulador

FREC=FREC7;

}

*/

//prueba para USB, no olvidar modificar frecuencia del DDS

if(FREC==FREC7||(FREC>=FREC7-FI07-100000 && FREC<=FREC7-FI07+100000)){//LSB->resta

//if(FREC==FREC7||(FREC>=FREC7+FI07-100000 && FREC<=FREC7+FI07+100000)){//USB->suma

if(digitalRead(RXTX)==0) //se presiono manipulador

//FREC=FREC7+FI07-ritt+xitt; //USB->suma

FREC=FREC7-FI07-ritt+xitt; //LSB->resta

else //se solto manipulador

FREC=FREC7;

}

if(FREC==FREC14||(FREC>=FREC14+FI14-100000 && FREC<=FREC14+FI14+100000)){

if(digitalRead(RXTX)==0) //se presiono manipulador

FREC=FREC14+FI14-ritt+xitt; //USB->suma

else

FREC=FREC14; //se solto manipulador

}

}

//__________________________________________________________________

//FUNCIONES

void AD9851_RFDAT( int value )

{

if ( value )

digitalWrite(data, HIGH);

else

digitalWrite(data, LOW);

//delay(1);

}

void AD9851_RESET( int value ){}

void AD9851_CLK( int value )

{

if ( value )

digitalWrite(clk, HIGH);

else

digitalWrite(clk, LOW);

//delay(1);

}

void AD9851_FQUD( int value )

{

if ( value )

digitalWrite(fqud, HIGH);

else

digitalWrite(fqud, LOW);

//delay(1);

}

unsigned long int VNA_FreqToTW(unsigned long int RefClk, unsigned long int F0)

{

unsigned long long int x;

x = F0;

x <<= 32;

x += (RefClk >> 1);

x /= RefClk;

return (unsigned long int) x;

}

void AD9851_SetFreq( unsigned long int hz, unsigned long int phase )

{

int i;

unsigned long int divisor;

divisor = VNA_FreqToTW(REFCLK,hz); //reemplazado eeb0.refclk por valor refclk

// printf(" %u Hz tuning word = %u\n",hz,divisor);

// set freq(32) from divisor

for (i=0; i<32; i++)

{

if (divisor & 0x00000001L)

{

AD9851_RFDAT(1);

//AD9851_LODAT(1);

}

else

{

AD9851_RFDAT(0);

}

AD9851_CLK(1);

AD9851_CLK(0);

divisor >>= 1;

}

// set direct osc(1), test bit(1),powerup both DDS chips (1)

AD9851_RFDAT(0);

for (i=0; i<3; i++)

{

AD9851_CLK(1);

AD9851_CLK(0);

}

AD9851_RFDAT(0); // rf is always 0 deg

for (i=0; i<5; i++)

{

AD9851_CLK(1);

AD9851_CLK(0);

}

// now activate the new configuration

AD9851_FQUD(1);

AD9851_FQUD(0);

}

void AD9851_Reset( void )

{

int i;

// set dds lines in a known position

AD9851_CLK(0);

AD9851_FQUD(0);

AD9851_RESET(0);

AD9851_RFDAT(0);

// reset both dds ( needs to be > 5 ref clk periods )

AD9851_RESET(1);

AD9851_RESET(0);

// enter DDS serial programming mode

AD9851_CLK(1);

AD9851_CLK(0);

AD9851_FQUD(1);

AD9851_FQUD(0);

// we are now in serial mode but not synced

// clock a power down word into 40 bit SR

for( i=0; i<34; i++)

{

AD9851_CLK(1); // clocks 0..33

AD9851_CLK(0);

}

AD9851_RFDAT(1);

AD9851_CLK(1); // clock 34

AD9851_CLK(0);

AD9851_RFDAT(0);

for( i=0; i<5; i++)

{

AD9851_CLK(1); // clocks 35..39

AD9851_CLK(0);

}

// reset both dds ( needs to be > 5 ref clk periods )

AD9851_RESET(1);

AD9851_RESET(0);

// clock power down word into core

AD9851_FQUD(1);

AD9851_FQUD(0);

// enter DDS serial programming mode

AD9851_CLK(1);

AD9851_CLK(0);

AD9851_FQUD(1);

AD9851_FQUD(0);

// we are now in serial mode, synced and powered down

// now clock out 40 zeros to power us up

for( i=0; i<40; i++)

{

AD9851_CLK(1); // clocks 0..39

AD9851_CLK(0);

}

AD9851_FQUD(1);

AD9851_FQUD(0);

AD9851_SetFreq( 100000000, 90 ); ////AD9851_SetFreq( 100000000L, 0L ); ?????

}