Author Topic: Converting this UNO code to Nano problem  (Read 969 times)

0 Members and 1 Guest are viewing this topic.

Offline Mozee

  • Contributor
  • Posts: 47
  • Country: us
Converting this UNO code to Nano problem
« on: April 22, 2018, 06:42:11 pm »

I have used this code for a function generator project utilizing the AD9851 module and a rotary encoder and It works flawlessly using the UNO,

Now that I want to build a small plastic box for it and fit everything in I want to use the Smaller Nano for this project and to be honest I have very very little Arduino programming knowledge so any help is highly appreciated

The original Uno code is
Main code by Richard Visokey AD7C -
Revision 2.0 - November 6th, 2013...  ever so slight revision by  VK8BN for AD9851 chip Feb 24 2014

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

//Setup some items
#define W_CLK 8   // Pin 8 - connect to AD9851 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=1000000; // Starting frequency of VFO =============================================================================(    )
int_fast32_t rx2=1; // variable to hold the updated frequency
int_fast32_t increment = 1000000; // 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
  lcd.begin(16, 2);
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(RESET, OUTPUT);
  pulseHigh(FQ_UD);  // this pulse enables serial mode on the AD9851 - see datasheet
   // Load the stored frequency
  if (ForceFreq == 0) {
    freq = String(;
    rx = freq.toInt();

void loop() {
  if (rx != rx2){   
        rx2 = rx;
  buttonstate = digitalRead(A0);
  if(buttonstate == LOW) {

  // 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()){

ISR(PCINT2_vect) {
  unsigned char result = r.process();
  if (result) {   
    if (result == DIR_CW){rx=rx+increment;}
    else {rx=rx-increment;};       
      if (rx >=70000000){rx=rx2;}; // UPPER VFO LIMIT
      if (rx <=1){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 * 6442560000./180000000;  // note 180 MHz clock on 9851. also note slight adjustment of this can be made to correct for frequency error of onboard crystal
  for (int b=0; b<4; b++, freq>>=8) {
    tfr_byte(freq & 0xFF);
  tfr_byte(0x001);   // Final control byte, LSB 1 to enable 6 x xtal multiplier on 9851 set to 0x000 for 9850
  pulseHigh(FQ_UD);  // Done!  Should see output
// transfers a byte, a bit at a time, LSB first to the 9851 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 == 1){increment = 10; hertz = "10 Hz"; hertzPosition=5;}
  else 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 = 1; hertz = "1 Hz"; hertzPosition=5;};
     lcd.print("           ");
   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.print("                ");
   if (millions > 9){lcd.setCursor(0,0);}
    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!
   memstatus = 1;  // Let program know memory has been written


The error I'm getting when trying to upload to my NANO

 In file included from /Users/mirxan/Documents/Arduino/Arduino-AD9851-DDS-Direct-Digital-synthesizer-Signal-Generator-master/Arduino DDS 2/AD9851_LCD_ROTARY_WMENUS/AD9851_LCD_ROTARY_WMENUS.ino:9:0:
/Users/mirxan/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/libraries/EEPROM/src/EEPROM.h:43:30: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     operator const uint8_t() const       { return **this; }
/Users/mirxan/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/libraries/EEPROM/src/EEPROM.h:92:26: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     operator const int() const          { return index; }
/Users/mirxan/Documents/Arduino/Arduino-AD9851-DDS-Direct-Digital-synthesizer-Signal-Generator-master/Arduino DDS 2/AD9851_LCD_ROTARY_WMENUS/AD9851_LCD_ROTARY_WMENUS.ino: In function 'void loop()':
/Users/mirxan/Documents/Arduino/Arduino-AD9851-DDS-Direct-Digital-synthesizer-Signal-Generator-master/Arduino DDS 2/AD9851_LCD_ROTARY_WMENUS/AD9851_LCD_ROTARY_WMENUS.ino:77:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       if(timepassed+2000 < millis()){
Archiving built core (caching) in: /var/folders/1y/gz925xkn7hbfdksl2kvf66ch0000gn/T/arduino_cache_84420/core/core_arduino_avr_nano_cpu_atmega328_fa1b08b34ccd52872ebff4bfcb4298c8.a
Sketch uses 7050 bytes (22%) of program storage space. Maximum is 30720 bytes.
Global variables use 219 bytes (10%) of dynamic memory, leaving 1829 bytes for local variables. Maximum is 2048 bytes.
avrdude: ser_open(): can't open device "/dev/cu.usbmodem1421": No such file or directory
Problem uploading to board.  See for suggestions.
Invalid library found in /Users/mirxan/Documents/Arduino/libraries/RotarySource: /Users/mirxan/Documents/Arduino/libraries/RotarySource
Invalid library found in /Users/mirxan/Documents/Arduino/libraries/RotarySource: /Users/mirxan/Documents/Arduino/libraries/RotarySource

Any suggestions?

We always learn, till the moment we’re dying , we learn how it feels to be dead

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 8781
Re: Converting this UNO code to Nano problem
« Reply #1 on: April 22, 2018, 07:41:49 pm »
Current production Arduino Nano boards have the same MCU (ATmega328P) at the same (16MHz) frequency as an Arduino Uno, and the same I/O pins just rearranged a bit.  You should therefore be able to use AVRDUDE to load a Nano with the Uno build of your project, and as long as you've got the pins hooked up correctly, if it worked on the Uno it should work first time on the Nano.

I don't know what's up with the const qualifiers in eeprom.h,  but as that's a part of the Arduino core, its likely those warnings can be ignored.

The warning: comparison between signed and unsigned integer expressions
Code: [Select]
if(timepassed+2000 < millis()){is an easy fix - just declare timepassed as uint32_t.   

The error:
Code: [Select]
avrdude: ser_open(): can't open device "/dev/cu.usbmodem1421": No such file or directory
Problem uploading to board.
indicates AVRDUDE cant open the USB COM port its expecting the Nano to appear as and the 'No such file or directory' indicates its because the port doesn't exist.   Maybe its a bad Nano, maybe its a bad USB cable or maybe the Nano is appearing as a different port and you haven't selected it yet in the IDE.

Offline picandmix

  • Frequent Contributor
  • **
  • Posts: 395
  • Country: gb
Re: Converting this UNO code to Nano problem
« Reply #2 on: April 22, 2018, 07:52:55 pm »

I built that project some years ago, like you using a Uno.

Just copied your code and reloaded his Rotary library and as you can see it complies  and uploads ok to my clone Nano board.

Using Arduino ide 1.8.5


Online newbrain

  • Frequent Contributor
  • **
  • Posts: 885
  • Country: se
Re: Converting this UNO code to Nano problem
« Reply #3 on: April 23, 2018, 06:13:12 pm »
The warning: comparison between signed and unsigned integer expressions
Code: [Select]
if(timepassed+2000 < millis()){is an easy fix - just declare timepassed as uint32_t.   
Correct, but only half of the fix: the comparison will not work correctly when timepassed is greater than UINT32_MAX-2000 and millis() has not yet wrapped around.
The comparison guaranteed to work in any case is:
Code: [Select]
if(millis()-timepassed > 2000u)){
Granted, you have 49 days 17 hours 2 minutes and some seconds before this becoming a problem, but:
  • It's not unfathomable that a function generator be left running for a very long time
  • It's a well known "trap for young (and old) players", so better make sure one learns how to avoid it  :blah:
Nandemo wa shiranai wa yo, shitteru koto dake.
The following users thanked this post: Ian.M

Offline metrologist

  • Super Contributor
  • ***
  • Posts: 1840
  • Country: 00
Re: Converting this UNO code to Nano problem
« Reply #4 on: April 23, 2018, 07:15:56 pm »
Thanks for the code. I created probably something similar a few years ago so it will be good to compare notes...

Online westfw

  • Super Contributor
  • ***
  • Posts: 3241
  • Country: us
Re: Converting this UNO code to Nano problem
« Reply #5 on: April 24, 2018, 02:28:36 am »
November 6th, 2013
Note that all of these warnings are probably more because you're using a newer version of the IDE with slightly different error detection and "warning levels" reporting, rather than differences between the Uno and the Nano (which should be essentially identical, SW-wise.)
I'd be very surprised if you don't get the same warnings re-compiling for the Uno.

Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo