
#include "DDSDualModule.h"


// Globals for the command interpreter.
String g_command      = "";
const String MHZ      = "mhz";
const String KHZ      = "khz";
const String HZ       = "hz";

//xxxxxxxxxxxxxxxxxxxxx

#include <Wire.h> // biblioteca comunicação
#include <LiquidCrystal_I2C.h> // biblioteca LCD
#include <IRremote.h> // biblioteca controle remoto

#define FREQCORR 0 // correção de frequencia por software

volatile unsigned long frequencia = 1000000;    // Starts at 10mhz
String letra; // uma letra ou numero considerado como letra
String palavra = ""; //uma palavra ou sequencia de letras
long numero = 0; // um numero a palavra transformada em numero
volatile unsigned long frequ; // valor da frequencia 
int IRRX_pino = 11; // define o pino de recepção do IR como D11
IRrecv irrecv(IRRX_pino);
decode_results resultado; // apresenta o valor lido no IR em resultado
float armazenavalor; // aramzena o valor lido do IR
int num = 0; // num é um flag ou bandeira se altera a bandeira ocorre algo
int digi = 5; // posição do cursor da frequencia começa no meio 5
double degrau = 0.1; // é o valor em que o cursor da frequencia esta
int i = 1; // 
long frmax = 45000000;
long frmin = 10;
int espa = 1;
String branco = " ";
// Inicializa o display, geralmente. no endereco 0x27 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// teclas do controle remoto 
float n0 = 0xFF6897  ; //tecla 0
float n1 = 0xFF30CF  ; // tecla 1
float n2 = 0xFF18E7  ; //tecla 2
float n3 = 0xFF7A85  ; //tecla 3
float n4 = 0xFF10EF  ; //tecla 4
float n5 = 0xFF38C7  ; //tecla 5
float n6 = 0xFF5AA5  ; //tecla 6
float n7 = 0xFF42BD  ; //tecla 7
float n8 = 0xFF4AB5  ; //tecla 8
float n9 = 0xFF52AD  ; //tecla9
float nn = 0xFF629D  ; //tecla CH entrar valor numerico da freq. em kHz
float nncfm = 0xFF906F  ; //tecla EQ confirma valor numerico da frequencia
float nce = 0xFF22DD  ; //tecla <<= seta cursor a esquerda
float ncd = 0xFF02FD  ; //tecla =>> seta cursor a direita
float nsobe = 0xFFA857  ; //tecla + sobe um valor na posição do cursor
float ndesce = 0xFFE01F  ; //tecla - abaixa um valor na posição do cursor


DDSDualModule * g_dualDDS;
void setup() {
  
    // Pins for the DDS modules.
    const int DDS_ResetPin = 4;
    const int DDS_DataPin = 5;
    const int DDS_FreqUpdatePin = 6; 
    const int DDSA_DataClockPin = 7;
    const int DDSB_DataClockPin = 8;

    // Initialise the serial port.
    Serial.begin(9600);
    delay(500);
    lcd.begin (16, 2);
    irrecv.enableIRIn(); // Inicializa o receptor IR
    

    // Instantiate a DDSDualModule with the correct pins.
    g_dualDDS = new DDSDualModule(DDS_ResetPin, DDS_FreqUpdatePin, DDS_DataPin, DDSA_DataClockPin, DDSB_DataClockPin);  
}
void loop () {
  if (frequencia > frmax) {
    (frequencia = frmax) ;
  }
  if (frequencia < frmin) {
    (frequencia = frmin);
  }
  if (frequencia >= 10000000)
  {
    espa = 1;
    branco = " ";
  }
  if ((frequencia < 10000000) && (frequencia > 999999))
  {
    (espa = 2);
    branco = " 0";
  }
  if ((frequencia < 1000000) && (frequencia > 99999))
  {
    (espa = 3);
    branco = " 00";
  }
  if ((frequencia < 100000) && (frequencia > 9999))
  {
    (espa = 4);
    branco = " 000";
  }
  if ((frequencia < 10000) && (frequencia > 999))
  {
    (espa = 5);
    branco = " 0000";
  }
  if ((frequencia < 1000) && (frequencia > 99))
  {
    (espa = 6);
    branco = " 00000";
  }
  if ((frequencia < 100) && (frequencia > 9))
  {
    (espa = 7);
    branco = " 00000";
  }
  lcd.setCursor(2, 0);
  lcd.print("Frequencia");
  lcd.setCursor(0, 1);
  lcd.print(branco);
  lcd.setCursor(espa, 1);
  //sendFrequency(frequencia);
 if (frequencia!=frequ){
 unsigned long freq = frequencia;
  g_dualDDS->SetFreq(freq);
 }
  frequ=frequencia;
  lcd.print(frequencia);
  lcd.print(" Hz");
  if (irrecv.decode(&resultado))
  {
    armazenavalor = (resultado.value);
    if (armazenavalor == nn)
    {
      lcd.clear();
      lcd.setCursor(10, 0);
      lcd.print("in kHz");
      delay (1000);
      numerico();
      lcd.clear();
    }
    if (armazenavalor == ncd)
    {
      digi = (digi + 1);
      if (digi > 8 )
      {
        digi = 1 ;
      }
      lcd.setCursor(digi, 1);
      lcd.cursor();
      delay(1000);
    }
    if (armazenavalor == nce)
    {
      digi = (digi - 1);
      if (digi < 1 )
      {
        digi = 8 ;
      }
      lcd.setCursor(digi, 1);
      lcd.cursor();
      delay(1000);
    }
    if (armazenavalor == nsobe) //soma
    {
      do
      {
        degrau = degrau * 10;
        i = i + 1;
      } while (i < (10 - digi));
      frequencia = frequencia + degrau;
      delay(500);
      i = 1;
      degrau = 0.1;
    }
    if (armazenavalor == ndesce) //abaixa
    {
      do
      {
        degrau = degrau * 10;
        i = i + 1;
      } while (i < (10 - digi));
      frequencia = frequencia - degrau;
      delay(500);
      i = 1;
      degrau = 0.1;
    }
    lcd.noCursor();
    irrecv.resume();
  }
  num = 0;
}

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

// Send frequency and command word to AD9850
//void sendFrequency(double frequencia) {
//  int32_t freq = frequencia * 4294967295 / (125000000 + FREQCORR); // note 125 MHz clock on 9850
 // for (int b = 0; b < 4; b++, freq >>= 8) {
 //   tfr_byte(freq & 0xFF);
 // }
 // tfr_byte(0);
 // pulseHigh(FQ_UD);
//}

void numerico() {
  // put your main code here, to run repeatedly:
  while (num == 0) {
    if (irrecv.decode(&resultado))
    {
      armazenavalor = (resultado.value);
      if (armazenavalor == n1)
      {
        letra = "1";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n2)
      {
        letra = "2";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n3)
      {
        letra = "3";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n4)
      {
        letra = "4";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n5)
      {
        letra = "5";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n6)
      {
        letra = "6";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n7)
      {
        letra = "7";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n8)
      {
        letra = "8";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n9)
      {
        letra = "9";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n0)
      {
        letra = "0";
        palavra = palavra + letra;
        delay (500);
      }
      // xero = xero + ero;
      //lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(palavra);
      lcd.print("kHz");
      // delay(2000);
      if (armazenavalor == nncfm)
      {
        palavra = (palavra + "000");
        numero = palavra.toInt();
        lcd.setCursor(0, 1);
        if (numero > 45000000) {
          (numero = 45000000);
        }
        if (numero < 1000) {
          (numero = 1000);
        }
        frequencia = numero;
        lcd.print(numero);
        //frequ = numero;
        palavra = "";
        letra = "";
        numero = 0;
        num = 1;
        delay(1000);
      }
      irrecv.resume();
    }
  }
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

//DDSDualModule * g_dualDDS;

//void ProcessCommand() {
    
    // Parse to lower case so that it makes commands easier to deal with.
  //  g_command.toLowerCase();  
    
    // Echo back the command as feedback to the user.
   // Serial.println(g_command);
    
   // if (g_command == "?") {
       // PrintHelp();
   // } else if (g_command == "pins") {
   //     PrintPins();
  //  } else if (g_command == "as") {
   //     g_dualDDS->SetASin();       
   // } else if (g_command == "ac") {
    //    g_dualDDS->SetACos();
  //  } else if (g_command == "bs") {
   //     g_dualDDS->SetBSin();
  //  } else if (g_command == "bc") {
   //     g_dualDDS->SetBCos();
  //  } else if (g_command == "g" || g_command == "w") {
   //     g_dualDDS->WriteControlBits();
  //  } else if (g_command.endsWith(MHZ)) {
   //     g_command.replace(MHZ,"");    // strip out MHZ chars, leaving just numerics
    //    if (IsNumeric(g_command)) {         
    //        unsigned long freq = g_command.toFloat() * 1000000;      
            //g_dualDDS->SetFreq(freq);
       // }
   // } else if (g_command.endsWith(KHZ)) {
      //  g_command.replace(KHZ,"");     
       // if (IsNumeric(g_command)) {
       //     unsigned long freq = g_command.toFloat() * 1000; 
        //    g_dualDDS->SetFreq(freq);
        //}
   // } else if (g_command.endsWith(HZ)) {                  
      //  g_command.replace(HZ,"");
      //  if (IsNumeric(g_command)) {
          //  const int bufSize = 10;
          //  char buf[bufSize];
        //    g_command.toCharArray(buf, bufSize);
           // unsigned long freq = atol(buf);
            //g_dualDDS->SetFreq(freq);
        //}
    //}
   // g_command = "";
//}

// Returns true if the string is a number x.y or x
//boolean IsNumeric(String str) {
 //   for(char i = 0; i < str.length(); i++) {
   //     if ( !(isDigit(str.charAt(i)) || str.charAt(i) == '.' )) {
    //        return false;
  //      }
 //   }
 //  return true;
//}

// Prints out all the commands that are available to the user.
//void PrintHelp() {
  //  Serial.println("COMMAND LIST");   
//    Serial.println("as      DDS A sine o/p ");
//    Serial.println("ac      DDS A cos o/p");
//    Serial.println("bs      DDS B sine o/p");
//    Serial.println("bc      DDS B cos o/p");
//    Serial.println("100Hz   example");
//    Serial.println("100kHz  example");
 //   Serial.println("1MHz    example");
//    Serial.println("pins    list pins");
//    Serial.println();
//}

// Prints the pin numbers to the user, used in case they need to check something.
//void PrintPins() {
//     Serial.println("Nano pins");   
//     Serial.println("DDS_ResetPin        = 4");
//     Serial.println("DDS_DataPin         = 5");
//     Serial.println("DDS_FreqUpdatePin   = 6");
//     Serial.println("DDSA_DataClockPin   = 7");
//     Serial.println("DDSB_DataClockPin   = 8"); 
//     Serial.println();
//}

// Initialisation and setup code, only gets executed once.


// Main code loop
//void loop() {
   
   // Read the incoming byte from the serial port which will make up the commands to interpret.
 //  if (Serial.available() > 0) {
   //     char incomingByte;
  //      incomingByte = Serial.read();

        // If the character is not a new line then build up command string, else process what ever is in g_command.
  //      if (incomingByte != '\n' && incomingByte != '\r') {
 //           g_command += incomingByte; 
  //      } else {
 //           ProcessCommand();
  //      }
 //   }
//}
