Converting this UNO code to Nano problem - Page 1
Forum section: electronics / general

author: Mozee
author_rank: Contributor
timestamp: April 22, 2018, 06:42:11 pm
content: Hello,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 appreciatedThe original Uno code is======================================================================================/*Main code by Richard Visokey AD7C -www.ad7c.comRevision 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 frequencyint_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 ; //PlaceholdersString freq; // string to hold the frequencyint_fast32_t timepassed = millis(); // int to hold the arduino miilis since startupint 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 pushdigitalWrite(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 AD9851 - see datasheetlcd.setCursor(hertzPosition,1);lcd.print(hertz);// Load the stored frequencyif (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 >=70000000){rx=rx2;}; // UPPER VFO LIMITif (rx <=1){rx=rx2;}; // LOWER VFO LIMIT}}// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32void 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 crystalfor (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 9850pulseHigh(FQ_UD); // Done! Should see output}// transfers a byte, a bit at a time, LSB first to the 9851 via serial DATA linevoid 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.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(0,0);}else{lcd.setCursor(1,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 = 1; // Let program know memory has been written};=============================================================================The error I'm getting when trying to upload to my NANOIn 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.aSketch 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 directoryProblem uploading to board. Seehttp://www.arduino.cc/en/Guide/Troubleshooting#uploadfor suggestions.Invalid library found in /Users/mirxan/Documents/Arduino/libraries/RotarySource: /Users/mirxan/Documents/Arduino/libraries/RotarySourceInvalid library found in /Users/mirxan/Documents/Arduino/libraries/RotarySource: /Users/mirxan/Documents/Arduino/libraries/RotarySourceAny suggestions?

author: Ian.M
author_rank: Super Contributor
timestamp: April 22, 2018, 07:41:49 pm
content: 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 expressionsCode:if(timepassed+2000 < millis()){is an easy fix - just declare timepassed as uint32_t.The error:Code:avrdude: ser_open(): can't open device "/dev/cu.usbmodem1421": No such file or directoryProblem 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.

author: picandmix
author_rank: Frequent Contributor
timestamp: April 22, 2018, 07:52:55 pm
content: Hi,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

author: newbrain
author_rank: Super Contributor
timestamp: April 23, 2018, 06:13:12 pm
content: Quote from: Ian.M on April 22, 2018, 07:41:49 pmCorrect, but only half of the fix: the comparison will not work correctly whentimepassedis greater than UINT32_MAX-2000 andmillis()has not yet wrapped around.The comparison guaranteed to work in any case is:Code: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 timeIt's a well known "trap for young (and old) players", so better make sure one learns how to avoid it

author: metrologist
author_rank: Super Contributor
timestamp: April 23, 2018, 07:15:56 pm
content: Thanks for the code. I created probably something similar a few years ago so it will be good to compare notes...

author: westfw
author_rank: Super Contributor
timestamp: April 24, 2018, 02:28:36 am
content: QuoteNote 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.