Baliza WSPR + CW simple

//13/9/17 Agregado identificacion en CW.

//12/9/17 Agregada banda 137 y 472 KHz.

//8/9/17, con arduino 328 empezo a andar sin problemas

//19/8. Lo guardo porque funciona bien sin UART pero con disparo por pin externo.

//15/8/17. Anda bien temporizado y lectura GPS. Se clava cuando uso TX_WSPR.

//14/8/17 logre que el timestamp de gps comience la trama pero es a frecuencia constante...

//13/8/17. Conflicto entre timer1 y uart. Ambos andan por separado pero no juntos.

//Usar otra forma de timer que no sea output compare?? otra forma de leer uart?

//13/8/17 Problema al lanzar TIMSK1 me bloquea el codigo.

//10/08/17 seudocodigo en espera del GPS

//8/8/17 Anda parte de generacion de tonos,

//falta parte de PPS del GPS y lectura datos HHMMSS del GPS.

//05/08/2017 Andando

#include <Wire.h> //Libreria que necesita NT7S

#include <si5351.h> //Libreria NT7S

#include <avr/io.h>

#include <avr/interrupt.h>

Si5351 si5351;

volatile int cont=0,cont_scaler=0, flag_timer=0,flag_pps=0,flag_gps=0,be_prepared_wspr=0,be_prepared_cw=0,enableTX=0,timer_cont=0;

volatile int timer_scaler=42, mode_flag=0;

String GPS_string="";

//char GPS_string[60];

//unsigned long long f0,f1,f2,f3,f4;

//volatile unsigned long long f0=704010000, f1=704010146, f2=704010293, f3=704010439, f4=704030000;

volatile unsigned long long f0, f1, f2, f3, f4;

//Mensajes

/*volatile byte WSPR_DATA_LU3HO_FF54_30[] = {3,1,2,0,0,2,2,2,3,

0,2,2,1,1,1,0,2,0,1,0,2,3,2,1,1,1,3,2,2,0,0,0,

2,2,3,0,2,1,2,3,0,2,2,2,0,0,3,2,3,1,0,0,1,1,2,3,2,0,2,3,1,0,3,0,

0,0,0,1,1,0,3,2,1,2,1,0,1,2,0,3,2,0,3,0,1,3,2,2,0,3,1,0,3,0,3,2,

2,2,1,0,0,2,0,2,1,0,2,1,0,2,1,1,1,0,1,3,0,2,1,1,2,3,0,2,2,1,3,1,

2,0,0,2,2,1,2,3,0,0,1,1,2,0,0,2,2,0,2,1,3,2,3,2,3,3,2,0,2,3,1,2,

0,2}; //LU3HO FF54 30

*/

volatile byte WSPR_DATA_LU3HO_FF54_35[] = {3,1,2,2,0,0,2,0,3,

2,2,2,1,1,1,2,2,0,1,0,2,3,2,3,1,1,3,0,2,2,0,0,2,2,3,0,2,3,2,

1,0,2,2,2,0,2,3,2,3,3,0,2,1,1,2,1,2,0,2,3,1,0,3,2,0,0,0,3,1,

2,3,2,1,2,1,0,1,0,0,1,2,2,3,2,1,3,2,0,0,3,1,2,3,2,3,2,2,2,1,

2,0,0,0,0,1,0,2,3,0,0,1,1,1,0,1,3,0,0,1,1,2,1,0,0,2,3,3,3,2,

0,0,0,2,1,2,3,0,2,1,1,2,2,0,2,2,2,2,3,3,0,3,2,3,3,2,2,2,1,1,

2,0,2}; //LU3HO FF54 35

volatile byte CW_DATA_LU3HO_FF54[]={ // "LU3HO/M FF54"

1,0,1,1,1,0,1,0,1,/*L*/

0,0,0,/*esp*/

1,0,1,0,1,1,1,/*U*/

0,0,0,/*esp*/

1,0,1,0,1,0,1,1,1,0,1,1,1,/*3*/

0,0,0,/*esp*/

1,0,1,0,1,0,1,0,/*H*/

0,0,0,/*esp*/

1,1,1,0,1,1,1,0,1,1,1,/*O*/

0,0,0,/*esp*/

1,1,1,0,1,0,1,0,1,1,1,0,1,/*"/"*/

0,0,0,/*esp*/

1,1,1,0,1,1,1,/*M*/

0,0,0,/*esp*/

0,0,0,/*esp*/

0,0,0,/*esp*/

0,0,0,/*esp*/

1,0,1,0,1,1,1,0,1,/*F*/

0,0,0,/*esp*/

1,0,1,0,1,1,1,0,1,/*F*/

0,0,0,/*esp*/

1,0,1,0,1,0,1,0,1,/*5*/

0,0,0,/*esp*/

1,0,1,0,1,0,1,0,1,1,1,/*4*/

0,0,0,/*esp*/

0,0,0,/*esp*/

0,0,0,/*esp*/

0,0,0,/*esp*/

0,0,0,/*esp*/

0,0/*esp final sin coma*/

//162

};

/**************************************************************************/

void setup(void)

{

pinMode(13, OUTPUT);

pinMode(2, OUTPUT);

pinMode(3,INPUT_PULLUP); //Pull Up de entrada, interrupcion por pin para el PPS

digitalWrite(2, HIGH);

SI5351_INIT();

GPS_string.reserve(200);

//SI_FREC(704010000);

// delay(1000);

// cli(); // disable global interrupts

TCCR2A = 0; // set entire TCCR1A register to 0

TCCR2B = 0; // same for TCCR1B

//OCR1A = 1000;

// turn on CTC mode:

TCCR2A |= (1 << WGM21);

// Set CS10 and CS12 bits for 1024 prescaler:

////TCCR1B |= (1 << CS10);

TCCR2B = 7;

// set compare match register to desired timer count:

OCR2A = 253; //254 valores

// enable timer compare interrupt:

//TIMSK1 |= (1 << OCIE1A);///////////////////////////////////////////PROBLEMA

// enable global interrupts:

// sei();

attachInterrupt(digitalPinToInterrupt(3),ISR_PPS,FALLING); //Detecta caida pulso PPS

Serial.begin(9600);

}

/**************************************************************************/

// Inicio INTERRUPCIONES

/**************************************************************************/

ISR(TIMER2_COMPA_vect){ //TIMER2

cont_scaler++;

if(cont_scaler>=timer_scaler){

flag_timer=1;

//digitalWrite(13,!digitalRead(13));

cont_scaler=0;

}

else

flag_timer=0;

}

/**************************************************************************/

void ISR_PPS(){ //PIN de INT

flag_pps=1;

}

/**************************************************************************/

void serialEvent(){ //UART

if(Serial.available()){

char input_char=(char)Serial.read();

GPS_string += input_char;

if(input_char=='\n')

flag_gps=1;

else {

flag_gps=0;

}

}

}

/**************************************************************************/

// Final INTERRUPCIONES

/**************************************************************************/

void loop(void) {

/**************************************************************************/

if(flag_gps==1){ //llego dato por uart

be_prepared_wspr=0;

be_prepared_cw=0;

//Condicionales para ejecucion rutina WPSR

if(GPS_string[0]=='$')

if(GPS_string[1]=='G')

if(GPS_string[3]=='Z')

if(GPS_string[4]=='D')

if(GPS_string[5]=='A')

if(GPS_string[10]=='1' /*|| GPS_string[10]=='3'*/ || GPS_string[10]=='5' /*|| GPS_string[10]=='7' */|| GPS_string[10]=='9')

//if(GPS_string[10]=='1' || GPS_string[10]=='3' || GPS_string[10]=='5' || GPS_string[10]=='7' || GPS_string[10]=='9')

if(GPS_string[11]=='5' )

if(GPS_string[12]=='9' ){

timer_scaler=42; //no tocar, wspr

be_prepared_wspr=1;

mode_flag=0;

}

//Condicionales para ejecucion rutina CW

if(GPS_string[0]=='$')

if(GPS_string[1]=='G')

if(GPS_string[3]=='Z')

if(GPS_string[4]=='D')

if(GPS_string[5]=='A')

//if(GPS_string[10]=='1' /*|| GPS_string[10]=='3'*/ || GPS_string[10]=='5' /*|| GPS_string[10]=='7' */|| GPS_string[10]=='9')

if(/*GPS_string[10]=='1' || */ GPS_string[10]=='3' ||/* GPS_string[10]=='5' ||*/ GPS_string[10]=='7'/* || GPS_string[10]=='9'*/)

//if(GPS_string[10]=='1' || GPS_string[10]=='3' || GPS_string[10]=='5' || GPS_string[10]=='7' || GPS_string[10]=='9')

if(GPS_string[11]=='5' )

if(GPS_string[12]=='9' ){

timer_scaler=10; //achicar para aumentar ppm de CW

be_prepared_cw=1;

mode_flag=1;

}

Serial.print(GPS_string);

GPS_string="";

flag_gps=0;

}

/**************************************************************************/

flag_pps=1;

if(flag_pps==1){ //interrupcion por pin, señal PPS. Coordina temporizado de trama.

if(be_prepared_wspr==1){ //Ejecucion rutina WSPR

BAND_SEL(40);

cont=0; //para empezar desde el inicio el mensaje

//flag_pps=0; //habilita una nueva entrada al IF

//enableTX=1;

be_prepared_wspr=0;

TCCR2B = 7; //Reconfiguro timer ya que lo apague haciendo cero el registro entero

TIMSK2 |= (1 << OCIE2A); //habilita int timer2 asi empieza a generar el temporizado de las frecuencias

}

if(be_prepared_cw==1){ //Ejecucion rutina CW

BAND_SEL(40);

cont=0; //para empezar desde el inicio el mensaje

//flag_pps=0; //habilita una nueva entrada al IF

//enableTX=1;

be_prepared_cw=0;

TCCR2B = 7; //Reconfiguro timer ya que lo apague haciendo cero el registro entero

TIMSK2 |= (1 << OCIE2A); //habilita int timer2 asi empieza a generar el temporizado de las frecuencias

}

flag_pps=0;

}

/**************************************************************************/

if(flag_timer==1){ //cordina generacion de frecuencias en el SI5351.

//WSPR

if(mode_flag==0){

if(cont<=161){ //162 tonos

digitalWrite(2, LOW); //enable cadena TX

TX_WSPR();

digitalWrite(13,!digitalRead(13));

cont++;

//flag_timer=0;

}

else{

TCCR2B = 0; //alternativa para detener timer

TIMSK2 |= (0 << OCIE2A); ///////////////////////////////////////////PROBLEMA???

cont=0;

//enableTX=0;

digitalWrite(2, HIGH); //disable cadena TX

si5351.output_enable(SI5351_CLK0, 0); //disable output

}

}

//CW

if(mode_flag==1){

if(cont<=161){ //162 tonos

//digitalWrite(2, LOW); //enable cadena TX

TX_CW();

digitalWrite(13,!digitalRead(13));

cont++;

//flag_timer=0;

}

else{

TCCR2B = 0; //alternativa para detener timer

TIMSK2 |= (0 << OCIE2A); ///////////////////////////////////////////PROBLEMA???

cont=0;

//enableTX=0;

digitalWrite(2, HIGH); //disable cadena TX

si5351.output_enable(SI5351_CLK0, 0); //disable output

}

}

flag_timer=0;

}

}

/**************************************************************************/

void SI5351_INIT(){

// Start serial and initialize the Si5351

si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);

//set output power

si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);

//calibration constant

//si5351.set_correction(20000);

si5351.set_correction(20000);

}

/**************************************************************************/

void SI_FREC(unsigned long long frec){

si5351.set_freq(frec, SI5351_CLK0);

}

/**************************************************************************/

void BAND_TIME_SEL (int minuto){

if(minuto== 0 || minuto==20 || minuto==40){return 160;}

if(minuto== 2 || minuto==22 || minuto==42){return 80;}

if(minuto== 4 || minuto==24 || minuto==44){return 40;}

if(minuto== 6 || minuto==26 || minuto==46){return 60;}

if(minuto== 8 || minuto==28 || minuto==48){return 30;}

if(minuto==10 || minuto==30 || minuto==50){return 20;}

if(minuto==12 || minuto==32 || minuto==52){return 17;}

if(minuto==14 || minuto==34 || minuto==54){return 15;}

if(minuto==16 || minuto==36 || minuto==56){return 12;}

if(minuto==18 || minuto==38 || minuto==58){return 10;}

return 0;

}

/**************************************************************************/

void BAND_SEL(int band){ //set global variables of frequency

//if(band==0) error

if(band==137){f0= 13750000; f1= 13750146; f2= 13750293; f3= 13750439; f4= 13770000;si5351.set_correction(0);}

if(band==472){f0= 47570000; f1= 47570146; f2= 47570293; f3= 47570439; f4= 47590000;si5351.set_correction(0);}

if(band==160){f0=183810000; f1=183810146; f2=183810293; f3=183810439; f4=183830000;si5351.set_correction(0);}

if(band==80) {f0=359410000; f1=359410146; f2=359410293; f3=359410439; f4=359430000;si5351.set_correction(0);}

if(band==40) {f0=704010000; f1=704010146; f2=704010293; f3=704010439; f4=704030000;si5351.set_correction(20000);}

if(band==30){f0=1014020000;f1=1014020146;f2=1014020293;f3=1014020439;f4=1014030000;si5351.set_correction(0);}

if(band==20){f0=1409710000;f1=1409710146;f2=1409710293;f3=1409710439;f4=1409730000;si5351.set_correction(0);}

if(band==17){f0=1810610000;f1=1810610146;f2=1810610293;f3=1810610439;f4=1810630000;si5351.set_correction(0);}

if(band==15){f0=2109610000;f1=2109610146;f2=2109610293;f3=2109610439;f4=2109640000;si5351.set_correction(0);}

if(band==12){f0=2492610000;f1=2492610146;f2=2492610293;f3=2492610439;f4=2492640000;si5351.set_correction(0);}

if(band==10){f0=2812610000;f1=2812610146;f2=2812610293;f3=2812610439;f4=2812640000;si5351.set_correction(14000);}

if(band==6) {f0=5029450000;f1=5029450146;f2=5029450293;f3=5029450439;f4=5029480000;si5351.set_correction(0);}

}

/**************************************************************************/

void TX_WSPR(void){

switch(WSPR_DATA_LU3HO_FF54_35[cont]){ //elegir el mensaje

case 0: SI_FREC(f0);break;

case 1: SI_FREC(f1);break;

case 2: SI_FREC(f2);break;

case 3: SI_FREC(f3);break;

default:SI_FREC(f4);break;

}

}

/**************************************************************************/

void TX_CW(void){

switch(CW_DATA_LU3HO_FF54[cont]){ //elegir el mensaje

case 0: si5351.output_enable(SI5351_CLK0,0); digitalWrite(2,HIGH); break; //No TX

case 1: SI_FREC(f4); digitalWrite(2, LOW); break; //Si TX

default:si5351.output_enable(SI5351_CLK0,0); digitalWrite(2,HIGH); break;

}

}