Importing this code into a nano

Hello group. First time posting here and a total newbie. I am having some issues with the code listed below.
I am hoping they are easy answers for ya all. :slight_smile:
Loading the code into Nano worked ok but the version of code that saves the last freq used, into eeprom does not.
Changing the 1 to 0 makes the nano go wacky.

"int ForceFreq = 1; // Change this to 0 after you upload and run a working sketch to activate the EEPROM memory. YOU MUST PUT THIS BACK TO 0 AND UPLOAD THE SKETCH AGAIN AFTER STARTING FREQUENCY IS SET!"

Apparently it has something to do with interrupts and there was a fix posted on the blog.
As follows:

"I don’t have a full sketch but I can tell you the main item you need to adjust is the interrupt.
The Nano uses different interrupt pin assignments.
Your problem is here:
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);

I think you move it to 8 and 9 if I remember correctly.
Rich
AD7C"

I am not exactly sure what to do here.

Next, I have a LCD module I bought that came with a I2C interface module attached.
Apparently you can use the LCD Module with I2C, thus freeing up some pins on the controller.

Here is the fix that was posted:

"Nicolo, did you have succes with I2C display?
If not, do the following:
Connect MF freq. shift to A1 instead of A5
A4 is SDA for I2C
A5 is SCL for I2C
Obviously you don’t need the wiring from Arduino D4,5,6,7 an D12,13
Don’t forget to change the assignment for A5 to A1
Cheers,
Gerard"

I am not exactly sure what to do here.
here is the line in code that defines the lcd.

"LiquidCrystal lcd(12, 13, 7, 6, 5, 4); // I used an odd pin combination because I need pin 2 and 3 for the interrupts."

Do I just remove (12, 13, 7, 6, 5, 4) and replace it with (A4, A5) and also redefine A5 to A1?

Since I am an absolute beginner to coding, I am a little confused about how to implement these fixes.
I am hoping it is an easy question for someone to help me with.
Once I get to a point where I can easily understand the code,
I plan do some changes and add some functionality, if it will fit.
Thanks in advance

/*
Main code by Richard Visokey AD7C - www.ad7c.com
Revision 2.0 - November 6th, 2013
*/

// Include the library code
#include <LiquidCrystal.h>
#include <rotary.h>
#include <EEPROM.h>

//Setup some items
#define W_CLK 8   // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 9   // Pin 9 - connect to freq update pin (FQ)
#define DATA 10   // Pin 10 - connect to serial data load pin (DATA)
#define RESET 11  // Pin 11 - connect to reset pin (RST) 
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses.  Must be interrupt pins.
LiquidCrystal lcd(12, 13, 7, 6, 5, 4); // I used an odd pin combination because I need pin 2 and 3 for the interrupts.
int_fast32_t rx=6955000; // Starting frequency of VFO
int_fast32_t rx2=1; // variable to hold the updated frequency
int_fast32_t increment = 10; // starting VFO update increment in HZ.
int buttonstate = 0;
String hertz = "10 Hz";
int  hertzPosition = 5;
byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ;  //Placeholders
String freq; // string to hold the frequency
int_fast32_t timepassed = millis(); // int to hold the arduino miilis since startup
int memstatus = 1;  // value to notify if memory is current or old. 0=old, 1=current.





int ForceFreq = 1;  // Change this to 0 after you upload and run a working sketch to activate the EEPROM memory.  YOU MUST PUT THIS BACK TO 0 AND UPLOAD THE SKETCH AGAIN AFTER STARTING FREQUENCY IS SET!




void setup() {
  pinMode(A0,INPUT); // Connect to a button that goes to GND on push
  digitalWrite(A0,HIGH);
  lcd.begin(16, 2);
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();
  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(RESET, OUTPUT); 
  pulseHigh(RESET);
  pulseHigh(W_CLK);
  pulseHigh(FQ_UD);  // this pulse enables serial mode on the AD9850 - Datasheet page 12.
  lcd.setCursor(hertzPosition,1);    
  lcd.print(hertz);
   // Load the stored frequency  
  if (ForceFreq == 0) {
    freq = String(EEPROM.read(0))+String(EEPROM.read(1))+String(EEPROM.read(2))+String(EEPROM.read(3))+String(EEPROM.read(4))+String(EEPROM.read(5))+String(EEPROM.read(6));
    rx = freq.toInt();  
  }
}


void loop() {
  if (rx != rx2){    
        showFreq();
        sendFrequency(rx);
        rx2 = rx;
      }
      
  buttonstate = digitalRead(A0);
  if(buttonstate == LOW) {
        setincrement();        
    };

  // Write the frequency to memory if not stored and 2 seconds have passed since the last frequency change.
    if(memstatus == 0){   
      if(timepassed+2000 < millis()){
        storeMEM();
        }
      }   
}


ISR(PCINT2_vect) {
  unsigned char result = r.process();
  if (result) {    
    if (result == DIR_CW){rx=rx+increment;}
    else {rx=rx-increment;};       
      if (rx >=30000000){rx=rx2;}; // UPPER VFO LIMIT
      if (rx <=1000000){rx=rx2;}; // LOWER VFO LIMIT
  }
}



// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
void sendFrequency(double frequency) {  
  int32_t freq = frequency * 4294967295/125000000;  // note 125 MHz clock on 9850.  You can make 'slight' tuning variations here by adjusting the clock frequency.
  for (int b=0; b<4; b++, freq>>=8) {
    tfr_byte(freq & 0xFF);
  }
  tfr_byte(0x000);   // Final control byte, all 0 for 9850 chip
  pulseHigh(FQ_UD);  // Done!  Should see output
}
// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
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
  }
}

void setincrement(){
  if(increment == 10){increment = 50; hertz = "50 Hz"; hertzPosition=5;}
  else if (increment == 50){increment = 100;  hertz = "100 Hz"; hertzPosition=4;}
  else if (increment == 100){increment = 500; hertz="500 Hz"; hertzPosition=4;}
  else if (increment == 500){increment = 1000; hertz="1 Khz"; hertzPosition=6;}
  else if (increment == 1000){increment = 2500; hertz="2.5 Khz"; hertzPosition=4;}
  else if (increment == 2500){increment = 5000; hertz="5 Khz"; hertzPosition=6;}
  else if (increment == 5000){increment = 10000; hertz="10 Khz"; hertzPosition=5;}
  else if (increment == 10000){increment = 100000; hertz="100 Khz"; hertzPosition=4;}
  else if (increment == 100000){increment = 1000000; hertz="1 Mhz"; hertzPosition=6;}  
  else{increment = 10; hertz = "10 Hz"; hertzPosition=5;};  
   lcd.setCursor(0,1);
   lcd.print("                ");
   lcd.setCursor(hertzPosition,1); 
   lcd.print(hertz); 
   delay(250); // Adjust this delay to speed up/slow down the button menu scroll speed.
};

void showFreq(){
    millions = int(rx/1000000);
    hundredthousands = ((rx/100000)%10);
    tenthousands = ((rx/10000)%10);
    thousands = ((rx/1000)%10);
    hundreds = ((rx/100)%10);
    tens = ((rx/10)%10);
    ones = ((rx/1)%10);
    lcd.setCursor(0,0);
    lcd.print("                ");
   if (millions > 9){lcd.setCursor(1,0);}
   else{lcd.setCursor(2,0);}
    lcd.print(millions);
    lcd.print(".");
    lcd.print(hundredthousands);
    lcd.print(tenthousands);
    lcd.print(thousands);
    lcd.print(".");
    lcd.print(hundreds);
    lcd.print(tens);
    lcd.print(ones);
    lcd.print(" Mhz  ");
    timepassed = millis();
    memstatus = 0; // Trigger memory write
};

void storeMEM(){
  //Write each frequency section to a EPROM slot.  Yes, it's cheating but it works!
   EEPROM.write(0,millions);
   EEPROM.write(1,hundredthousands);
   EEPROM.write(2,tenthousands);
   EEPROM.write(3,thousands);
   EEPROM.write(4,hundreds);       
   EEPROM.write(5,tens);
   EEPROM.write(6,ones);   
   memstatus = 0;  // Let program know memory has been written
};

Since I am an absolute beginner to coding, I am a little confused about how to implement these fixes.

That is always the problem when you start with things you don't understand, rather than first learn about it.

That was rather harsh, Deva.

I haven't used that LCD library, nor the Nano, but I'll try to help.
First, you are asking multiple questions. I would recommend that you reduce your program to work on just one component at a time.

If you look at LiquidCrystal.h in a text editor, the template for the init is:
LiquidCrystal(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);

You don't say which LCD, but I am guessing a 1602, which is not an I2C device, so you still need the six data pins. If it is an I2C device, then I am thoroughly confused from your description.

So, to go further, we need a schematic (not a Fritzing picture) of your setup and a better description of your parts.

Hi,
Welcome to the forum.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

What model Arduino was that code designed for?!? There should be NO changes needed when switching from UNO to NANO.

When switching from a parallel 6-pin LCD 1602 to an I2C LCD 1602 you will need to use one of the many LiquidCrystal_I2C libraries. As a start, I suggest using Tools->Manage Libraries... to install "LiquidCrystal I2C by Frank de Brabander". The example File->Examples->LiquidCrystal I2C->HelloWorld will show you how to use the library. For the most part you only have to change "#include <LiquidCrystal.h>" to "#include <LiquidCrystal_I2C.h>". Change "LiquidCrystal lcd(12, 13, 7, 6, 5, 4);" to "LiquidCrystal_I2C lcd(0x27, 16, 2);". And change "lcd.begin(16,2); to "lcd.begin();".

That was rather harsh, Deva.

Sorry, yes it was. My issue was actually

"Nicolo, did you have succes with I2C display?
If not, do the following:
Connect MF freq. shift to A1 instead of A5
A4 is SDA for I2C
A5 is SCL for I2C
Obviously you don't need the wiring from Arduino D4,5,6,7 an D12,13
Don't forget to change the assignment for A5 to A1
Cheers,
Gerard"

So that means there is support from someone else (probably the guy that did write the code) But the OP doesn't understand how to implement whatever is needed (or not needed as John points out) And then gets us involved. I probably should have phrased it differently, but something does need to be said about it, and i suspect it was my turn to do so. Again, sorry i should have phrased that differently.

You should see my snark on Quora. Merciless.

johnwasser:
What model Arduino was that code designed for?!? There should be NO changes needed when switching from UNO to NANO.

From the comments in the code posted by the OP, the code appears to come from this project, AD9850 DDS VFO , and was written for an UNO. Should run without modification on a Nano with the exception of the changes needed for the I2C LCD, although I see several things in the code that could use some work.

Hello Guys
Thanks for the responses to my questions.
Yes David the code and project is from the website you listed. Sorry I should have included that info on the OP.
To confirm, the Lcd unit is a 1602 with a i2c adaptor module attached to it.
Thanks John for the instructions, I'll try it out.

And yes Deva you are right, I should know better. But come on man! I'm just a poor ex-oil pipeline worker trying new things. LOL. Just kidding,(except for the poor part) but I am a total newbie with big eyes. :slight_smile:

Yes the code does work in the nano, but when I toggle the code to save the last freq used it goes wacky.

Thanks for tips guys
I am on hour 10 of "24 hours to learn arduino" :confused:
Cheers

And yes Deva you are right, I should know better. But come on man!

Yeah, yeah, it is just that it is pattern reoccurring on that we see on this forum, and we and up helping people that did not write the code, and in some cases, really don't understand what or why it works. Anyway, let me give some feedback to the one who wrote this bit (and it's sister and daughter algorithm, to extract and convert the data)

 EEPROM.write(0,millions);
   EEPROM.write(1,hundredthousands);
   EEPROM.write(2,tenthousands);
   EEPROM.write(3,thousands);
   EEPROM.write(4,hundreds);       
   EEPROM.write(5,tens);
   EEPROM.write(6,ones);

Really ?? storing a 32-bit value you like that ?
Anyway it does sort of work, but it needs improving. It shouldn't be the cause to your issue, but if writing to the EEPROM is causing an issue, you may consider skipping the first 20 addresses or so.
Oh yeah .. };we don't need the semicolon there.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.