miércoles, 8 de julio de 2020

VFO DDS AD9850 transceptor ORVA BLU-100 (parte 3) SOFTWARE

Soft para atmega328  (DESACTIVAR EL TRADUCTOR AUTOMÁTICO DE GOOGLE)


/////////////////////////////////////////////////////////////////////////////
//     DDS VFO Ver2.04
//                         JA2NKD 2016.07.19
//
//   <Rotary.h>           https://github.com/brianlow/Rotary
//   <EF_AD9850.h> http://forum.arduino.cc/index.php?topic=77483.0
//   "Ucglib.h"            https://github.com/olikraus/ucglib
//
//----------------------------------------------------------------------------
//   Added      EEPROM function             2016/7/31 JA2GQP
//   Added      Doble Rotary                      2020/4/12 LU1DEH
//
///////////////////////////////////////////////////////////////////////////////

// Library include
#include <SPI.h>
#include <Rotary.h>
#include <EEPROM.h>
#include "Ucglib.h"


//----------   I/O setting  ---------------

/////////////////////
//  Hardware SPI Pins:
//  Arduino nano sclk=13, data=11
/////////////////////

const byte   __CS = 10;
const byte   __DC = 9;
const byte   __RST = 8;

const byte  W_CLK = A0; 
const byte  FQ_UD = A1; 
const byte  DATA = A2;                     

const byte modeout1 = 7;               

const byte modesw = 1;                 
const byte stepsw = 12;             
const byte ritsw = 6;                      
const byte txsw = A3;                       
const byte s_meter = A5;                
const byte t_meter = A4;                 

/////////////////////                     
// DDS parameter
/////////////////////

const unsigned long  DDS_CLK = 125000000L; // AD9850 Clock
const unsigned long  TWO_E32 = 4294967295L;// 2^32
const byte  DDS_CMD = B00000000;           // AD9850 Command

//----------  EEPROM Memory Address   ---------- 

const byte  Frq_Eep = 0x00;              
const byte  Stp_Eep = 0x10;            
const byte  Chn_Eep = 0x20;              
const byte  Mode_Eep = 0x22;             
const byte  Eep_Int = 0x2e;               

const byte  Max_Chn = 1;             
const byte  Int_End = 73;               

//----------- Default Value -------------------- 

const long  DEF_FRQ = 7050000L;       
const long  DEF_STP = 100L;            
const byte  DEF_Mode = 0;              

//----------  Encorder Pin Assign(INT)  --------

Rotary r = Rotary(2, 3);
Rotary r1 = Rotary(4, 5);

//----------  TFT Ucglib Assign --------

Ucglib_ST7735_18x128x160_HWSPI ucg(/*sclk= 13, data= 11, */ /*cd=*/ 9 , /*cs=*/ 10, /*reset=*/ 8);

//----------  Memory Assign  --------------------------------

long int freq = DEF_FRQ;
long int freqmax = 10000000;
long int freqmin = 1000000;
long int freqold = 0;
long int freqrit = 0;
String freqt = String(freq);
long int ifshift = 0;
long int ifshiftLSB = -2000000;
long int ifshiftUSB = 2000000;
long int txshiftLSB = -2000000;
long int txshiftUSB = 2000000;
long int ddsfreq = 0;
char f10m, fmega, f100k, f10k, f1k, f100;
int ddsstep = 2;
int rit = 0;
int fstep = DEF_STP;
int fsteprit = 10;
int fmode;
int fmodeold = 1;
int flagrit = 0;
int fritold = 0;
int flagmode = 0;
int smeterval1 = 0;
int tmeterval = 0;
byte Byt_Chn;                       
byte Byt_Chnb;                     

//----------  Initialization  Program  ----------------------

void setup() {

  delay(100);
  Serial.begin(9600);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);  
  ucg.clearScreen();
  ucg.setRotate270();
  ucg.setFont(ucg_font_fub20_tf);
  ucg.setPrintPos(25, 75);           //75,45
  ucg.setColor(255, 255, 255);
  ucg.print("LU1DEH");
  delay(2000);
  ucg.clearScreen();

  pinMode(stepsw, INPUT_PULLUP);
  pinMode(ritsw, INPUT_PULLUP);
  pinMode(txsw, INPUT_PULLUP);
  pinMode(modesw, INPUT_PULLUP);
  pinMode(modeout1, OUTPUT);

  PCICR |= (1 << PCIE2) | (1 << PCIE1);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19) | (1 << PCINT20) | (1 << PCINT21);
  sei();

  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);

  screen01();

  if (EEPROM.read(Eep_Int) != Int_End) {     
    delay(10);
    Fnc_Eep_Int();
  }

  Byt_Chn = EEPROM.read(Chn_Eep);        
  Byt_Chnb = Byt_Chn;                      
  Fnc_Eep_Rd();                         
  modeset();                           
  modeset(); 

  steplcd();
  freqt = String(freq);
  freqlcd();
}

//----------  Main program  ---------------------------------

void loop() {
  if (digitalRead(stepsw) == LOW) {
    setstep();
  }
  if (digitalRead(modesw) == LOW) {
    modeset();
  }
  if (digitalRead(ritsw) == LOW) {
    setrit();  // <JA2GQP>
    Fnc_Eep_Wt(Byt_Chn);
  }
  if (digitalRead(txsw) == LOW) {
    txset();
  }

  if (Byt_Chnb != Byt_Chn) {              
    Fnc_Eep_Wt(Byt_Chnb);
    Byt_Chnb = Byt_Chn;
    Fnc_Eep_Rd();
    steplcd();
  }

  if (flagrit == 1) {
    if (freqrit == fritold) {
      smeter();
    }

    if (freqrit != fritold) {
      ddswrite();
      fritold = freqrit;
    }
  }
  else {
    if (freq == freqold) {
      smeter();
    }
    ddswrite();
    freqt = String(freq);
    freqlcd();
    freqold = freq;
  }
}

//---------- Function Eeprom Initialization ------------  

void Fnc_Eep_Int() {
  int i;

  for (i = 0; i < 48; i++)                     
    EEPROM.write(i, 0);

  for (i = 0; i < Max_Chn; i++) {
    Fnc_Eep_Sav4(DEF_FRQ, Frq_Eep + i * 4);    
    Fnc_Eep_Sav4(DEF_STP, Stp_Eep + i * 4);    
  }

  EEPROM.write(Chn_Eep, 0);
  EEPROM.write(Mode_Eep, DEF_Mode);
  EEPROM.write(Eep_Int, Int_End);            
}

//----------  Function EEPROM Read  ---------     

void Fnc_Eep_Rd() {
  if ((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
    freq = Fnc_Eep_Lod4(Frq_Eep + Byt_Chn * 4);
  else {
    freq = Fnc_Eep_Lod4(Frq_Eep + 0);
    Byt_Chn = 0;
  }

  if ((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
    fstep = Fnc_Eep_Lod4(Stp_Eep + Byt_Chn * 4);
  else
    fstep = Fnc_Eep_Lod4(Stp_Eep + 0);

  fmode = EEPROM.read(Mode_Eep);
}

//----------  Function EEPROM Write  -------------------

void Fnc_Eep_Wt(byte chn) {
  if ((0 <= chn) && (chn < Max_Chn)) {
    Fnc_Eep_Sav4(freq, Frq_Eep + chn * 4);
    Fnc_Eep_Sav4(fstep, Stp_Eep + chn * 4);
  }

  EEPROM.write(Chn_Eep, Byt_Chn);
  EEPROM.write(Mode_Eep, fmode);
}

//----------  Function Save EEPROM 4byte  --------    

void Fnc_Eep_Sav4(long value, int address) {
  address += 3;
  for (int i = 0; i < 4; i++) {
    byte toSave = value & 0xFF;
    if (EEPROM.read(address) != toSave) {
      EEPROM.write(address, toSave);
    }
    value = value >> 8;
    address--;
  }
}

//----------  Function Load EEPROM 4byte  ---------      

long Fnc_Eep_Lod4(int address) {
  long value = 0;
  for (int i = 0; i < 4; i++) {
    value = value | EEPROM.read(address);
    if ( i < 3) {
      value = value << 8;
      address++;
    }
  }
  return value;
}

//----------  Function DDS set  ---------------          

void Fnc_Dds(double frquency) {
  unsigned long wrk = frquency * TWO_E32 / DDS_CLK;

  digitalWrite(FQ_UD, LOW);

  shiftOut(DATA, W_CLK, LSBFIRST, wrk);
  shiftOut(DATA, W_CLK, LSBFIRST, (wrk >> 8));
  shiftOut(DATA, W_CLK, LSBFIRST, (wrk >> 16));
  shiftOut(DATA, W_CLK, LSBFIRST, (wrk >> 24));
  shiftOut(DATA, W_CLK, LSBFIRST, DDS_CMD); 

  digitalWrite(FQ_UD, HIGH);
}

//---------- S-meter --------------------------

void smeter() {
  smeterval1 = analogRead(s_meter);
  smeterval1 = smeterval1 / 50;
  if (smeterval1 > 14) {
    smeterval1 = 14; 
  }
  int sx1 = sx1 + (smeterval1 * 9);    
  sx1 = sx1 + 21;                    
  int sx2 = 0;
  sx2 = sx2 + (40 + ((15 - smeterval1) * 9)); 
  ucg.setFont(ucg_font_fub20_tf);      
  ucg.setColor(0, 0, 0);               
  ucg.drawBox(sx1, 93, sx2, 8);
  ucg.setPrintPos(20, 104);            
  for (int i = 1; i <= smeterval1; i++) {
    if (i <= 8) {
      ucg.setColor(0, 255, 0);
      ucg.print("-");
    }
    else {
      ucg.setColor(255, 0, 0);
      ucg.print("-");
    }
  }
}

//---------- Transmission Power meter ------------------

void tmeter() {
  ucg.setColor(0, 0, 0);               
  ucg.drawBox(19, 69, 135, 8);          
  tmeterval = analogRead(t_meter);
  tmeterval = tmeterval / 50;
  if (tmeterval > 14) {
    tmeterval = 14;
  }
  int sx1 = sx1 + (tmeterval * 9);
  sx1 = sx1 + 21;
  int sx2 = 0;
  sx2 = sx2 + (40 + ((15 - tmeterval) * 9));
  ucg.setFont(ucg_font_fub20_tf);     
  ucg.setColor(0, 0, 0);               
  ucg.drawBox(sx1, 69, sx2, 8);
  ucg.setPrintPos(20, 80);            
  for (int i = 1; i <= tmeterval; i++) {
    if (i <= 10) {
      ucg.setColor(255, 185, 0);
      ucg.print("-");
    }
    else {
      ucg.setColor(250, 0, 0);
      ucg.print("-");
    }
  }
}

//---------- Encoder Interrupt -----------------------

ISR(PCINT2_vect) {
  if (flagrit == 1) {
    unsigned char result1 = r1.process();
    if (result1) {
      if (result1 == DIR_CW) {
        freqrit = freqrit + fsteprit;
        if (freqrit >= 3000) {
          freqrit = 3000;
        }
      }
      else {
        freqrit = freqrit - fsteprit;
        if (freqrit <= -3000) {
          freqrit = -3000;
        }
      }
    }
  }

  else {
    unsigned char result = r.process();
    if (result) {
      if (result == DIR_CW) {
        freq = freq + fstep;
        if (freq >= freqmax) {
          freq = freqmax;
        }
      }
      else {
        freq = freq - fstep;
        if (freq <= freqmin) {
          freq = freqmin;
        }
      }
    }
  }
}

//------------ On Air -----------------------------

void txset() {
  noInterrupts();
  if (flagmode == 0) {ddsfreq = freq + txshiftLSB;}
  if (flagmode == 1) {ddsfreq = freq + txshiftUSB;}

  Fnc_Dds(ddsfreq);                       

  ucg.setColor(0, 0, 0);
  ucg.drawBox(5, 3, 24, 22);

  while (digitalRead(txsw) == LOW) {
    tmeter();
    ucg.setFont(ucg_font_logisoso18_tr);
    ucg.setPrintPos(5, 23);
    ucg.setColor(255, 0, 0);
    ucg.print("Tx");
  }

  ddswrite();
  ucg.setColor(0, 0, 0);
  ucg.drawBox(19, 69, 135, 8);
  ucg.drawBox(19, 93, 135, 8);
  ucg.drawBox(5, 3, 24, 22);
  interrupts();
  ucg.setPrintPos(5, 23);
  ucg.setColor(0, 255, 0);
  ucg.print("Rx");
}

//------------- Mode change(LSB-USB) ------------

void modeset() {
  ucg.setFont(ucg_font_6x10_mf);  
  if (fmode == 1) {                         
    ifshift = ifshiftUSB;
    flagmode = 1;                          
    ucg.setColor(255, 255, 0);             
    ucg.setPrintPos(47, 43);                
    ucg.print("USB");
    ucg.setPrintPos(12, 43);               
    ucg.setColor(0, 0, 0);                  
    ucg.print("LSB");
  }

  if (fmode == 0) {                       
    ifshift = ifshiftLSB;
    flagmode = 0;                           
    ucg.setPrintPos(12, 43);               
    ucg.setColor(255, 255, 0);              
    ucg.print("LSB");
    ucg.setPrintPos(47, 43);                
    ucg.setColor(0, 0, 0);                
    ucg.print("USB");
  }

  fmode = fmode + 1;

  Byt_Chn++;                            
  if (Byt_Chn > 1)
    Byt_Chn = 0;

  if (fmode == 2) {
    fmode = 0;
  }
  while (digitalRead(modesw) == LOW);
}

//------------ Rit SET ------------------------------

void setrit() {
  if (flagrit == 0) {
    flagrit = 1;
    ucg.setFont(ucg_font_6x10_mf);        
    ucg.setPrintPos(82, 43);                 
    ucg.setColor(255, 255, 0);
    ucg.print("RIT");
  }
  else {
    flagrit = 0;
    ddsfreq = freq + ifshift;
    Fnc_Dds(ddsfreq);                    
    freqt = String(freq);
    ucg.setFont(ucg_font_6x10_mf);       
    ucg.setPrintPos(82, 43);             
    ucg.setColor(0, 0, 0);
    ucg.print("RIT");
    freqrit = 0;
  }
  while (digitalRead(ritsw) == LOW);
}

//-------------- Encorder frequency step set -----------

void setstep() {
  noInterrupts();
  if (fstep == 100) {
    fstep = 2500;
  }

  else {
    fstep = fstep * 4 / 100;
  }

  steplcd();
  while (digitalRead(stepsw) == LOW);
  interrupts();
}

//------------- Step Screen ---------------------------

void steplcd() {
  ucg.setColor(0, 0, 0);                 
  ucg.setFont(ucg_font_6x10_mf);        
  ucg.setPrintPos(120, 43);              
  if (fstep == 100) {
    ucg.print("Fast");
  }
  ucg.setColor(255, 255, 0);
  if (fstep == 2500) {
    ucg.print("Fast");
  }
}

//----------- Main frequency screen -------------------

void freqlcd() {
  ucg.setFont(ucg_font_logisoso18_hn);
  int mojisuu = (freqt.length());

  if (f10m != (freqt.charAt(mojisuu - 8))) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(55, 5, 14, 19);
    ucg .setPrintPos(55, 23);
    ucg.setColor(0, 255, 0);
    ucg.print(freqt.charAt(mojisuu - 8));
    f10m = (freqt.charAt(mojisuu - 8));
  }

  if (freq < 10000000) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(55, 5, 14, 19);
  }

  if (fmega != (freqt.charAt(mojisuu - 7))) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(70, 5, 14, 19);
    ucg .setPrintPos(70, 23);
    ucg.setColor(0, 255, 0);
    ucg.print(freqt.charAt(mojisuu - 7));
    fmega  = (freqt.charAt(mojisuu - 7));
  }

  if (freq >= 1000000) {
    ucg.setPrintPos(82, 23);
    ucg.setColor(0, 255, 0);
    ucg.print(".");
  }

  if (freq < 1000000) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(70, 5, 14, 19);          
    ucg.drawBox(82, 5, 7, 19);
  }

  if (f100k != (freqt.charAt(mojisuu - 6))) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(89, 5, 14, 19);        
    ucg.setPrintPos(89, 23);            
    ucg.setColor(0, 255, 0);
    ucg.print(freqt.charAt(mojisuu - 6));
    f100k = (freqt.charAt(mojisuu - 6));
  }

  if (freq < 100000) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(89, 5, 14, 19);         
  }

  if (f10k != (freqt.charAt(mojisuu - 5))) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(104, 5, 14, 19);         
    ucg.setPrintPos(104, 23);            
    ucg.setColor(0, 255, 0);
    ucg.print(freqt.charAt(mojisuu - 5));
    f10k = (freqt.charAt(mojisuu - 5));
  }

  if (freq < 10000) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(104, 5, 14, 19);          
  }

  if (f1k != (freqt.charAt(mojisuu - 4))) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(119, 5, 14, 19);    
    ucg.setPrintPos(119, 23);            
    ucg.setColor(0, 255, 0);
    ucg.print(freqt.charAt(mojisuu - 4));
    f1k  = (freqt.charAt(mojisuu - 4));
  }

  if (freq >= 1000) {
    ucg.setPrintPos(131, 23);          
    ucg.setColor(0, 255, 0);
    ucg.print(".");
  }

  if (freq < 1000) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(119, 5, 14, 19);         
  }

  if (f100 != (freqt.charAt(mojisuu - 3))) {
    ucg.setColor(0, 0, 0);
    ucg.drawBox(138, 5, 14, 19);        
    ucg.setPrintPos(138, 23);          
    ucg.setColor(0, 255, 0);
    ucg.print(freqt.charAt(mojisuu - 3));
    f100 = (freqt.charAt(mojisuu - 3));
  }

  if (freq <= 5000000) {
    digitalWrite(modeout1, HIGH);
  }

  else {
    digitalWrite(modeout1, LOW);
  }
}

//----------- Basic Screen -------------------------

void screen01() {
  ucg.setColor(255, 255, 255);         
  ucg.drawRFrame(0, 0, 35, 28, 3);     
  ucg.drawRFrame(40, 0, 120, 28, 3);
  ucg.setColor(55, 55, 55);          
  ucg.drawRBox(5, 33, 30, 13, 1);     
  ucg.drawRBox(40, 33, 30, 13, 1);     
  ucg.drawRBox(75, 33, 30, 13, 1);     
  ucg.drawRBox(110, 33, 45, 13, 1);     
  ucg.setFont(ucg_font_logisoso18_tr);
  ucg.setPrintPos(5, 23);
  ucg.setColor(0, 255, 0);
  ucg.print("Rx");
  ucg.setFont(ucg_font_6x10_mf);      
  ucg.setPrintPos(12, 43);             
  ucg.setColor(0, 0, 0);
  ucg.print("LSB");
  ucg.setPrintPos(47, 43);             
  ucg.print("USB");
  ucg.setPrintPos(82, 43);             
  ucg.print("RIT");
  ucg.setColor(255, 255, 100);         
  ucg.setPrintPos(7, 100);           
  ucg.print("S:");
  ucg.setPrintPos(7, 76);             
  ucg.print("P:");
  ucg.setColor(255, 255, 150);
  ucg.setPrintPos(20, 110);            
  ucg.print("_1___5__7__9__10__30_");
  ucg.setPrintPos(20, 86);            
  ucg.print("0__2__4__6__8__10__+_");
  ucg.setPrintPos(45, 124);             
  ucg.setColor(235, 0, 200);
  ucg.print("ORVA BLU-100");
}

//--------------- DDS Write -------------------------------

void ddswrite() {

  if (flagrit == 0) {
    ddsfreq = freq + ifshift;
    Fnc_Dds(ddsfreq);                            
  }

  if (flagrit == 1) {
    ddsfreq = freq + ifshift + freqrit;
    Fnc_Dds(ddsfreq);                          
  }
}

3 comentarios:

  1. Buenisimooo... Felicitaciones, a todos los que han colaborado en este proyecto, tan lindo, yo fabrique mi DDS con OLED de 128x32, ahora gracias a Uds. quiero hacer este DDS, tengo casi todo, lo unico que me falta es la pantalla OLED, porque no se sus caracteristicas, tendria la amabilidad de decirme las caracteristicas de esa pantalla? Desde ya muchas gracias y un gran saludo para todos!! 73!!

    ResponderBorrar
  2. Hola grtacias por los saludos, el display que use es OLED Tft 1.8 160 X 128, abrazo

    ResponderBorrar
  3. Exelente!! tengo el cahuane 300 muy similar a este y lo quiero solo para 40m- tendras diagrama de como hacer modificacion sin retocar mucho?- muy buen trabajo y la pantalla es lcd tft no oled tengo la misma. grx 73

    ResponderBorrar