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;
}
}