I have a few sketches for a SI5351 board and UNO . One sketch does the uploading well, but when I power off the UNO the sketch is not available in the storage so l have to upload this sketch every time. What is wrong? Other sketches work well,
Welcome back!
Please read this post:
How to get the best out of this forum
We need a lot more information. What are the sketches? Please post both of them in code tags. What is your circuit like? Please post a schematic.
storage? do you mean flash memory? how do you know sketch is not in memory?
Ok not in memory. When I disconnect the UNO board from power(usb) and I later connect the UNO board, the LCD that makes part of the sketch is empty. Other sketches shows the desired information well.
may i see this mystical sketch? not forget to place the code between CODE tags
-
This kinda implies what the problem is.
-
Always show us a good schematic of your proposed circuit.
-
Show us good images of your ‘actual’ wiring.
-
Give links to components.
-
In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.
-
Use the < CODE / > icon from the ‘posting menu’ to attach the copied sketch.
Does the sketch work if you press the reset button on the UNO?
Did you upload the code to the Uno or to SI5153?
No, it does not work after reset.
To the UNO . Btw it is a si5351.
// --------------------------------------------------------------------------------------------------------------------------------------------------
//
// M0NTV Homebrewing
//
// D I G I T A L O S C I L L A T O R
//
// VERSION 4.5
// (March 26th 2022)
//
// -------------------------------------------------------------------------------------------------------------------------------------------------
//
// This is an adaptation of code created by Jason Mildrum (NT7S), Przemek Sadowski (SQ9NJE) and Tommy Hall (AK2B).
// It includes modifications to use the etherkit/Si5351 Arduino library (https://github.com/etherkit/Si5351Arduino)
//
// 17m SUPERHET VERSION (NEW VFO/BFO)
#include <Rotary.h>
#include <si5351.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define F_MIN 100000000UL // Lower frequency limit - Set this to where you want
#define F_MAX 5000000000UL // Upper frequency limit - Set this to where you want
#define ENCODER_A 2 // Encoder pin A (NB. If you encoder works in reverse (i.e. anticlockwise = increment; clockwise = decrement) then swap pins 2 and 3 over)
#define ENCODER_B 3 // Encoder pin B
#define ENCODER_BTN A3
//I2C pins declaration
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // Change to (0x27,20,4) for 20x4 LCD.
LiquidCrystal_I2C lcd(0x27, 16,2);
Si5351 si5351;
Rotary r = Rotary(ENCODER_A, ENCODER_B);
// SETTING UP THE VFO & BFO
//
// NB. You'll need to know the -6dB bandwidth of your crystal filter. It's done pretty easily with a NanoVNA (see my video 'Crystal Filters For The Fearful').
//
//
//
// For USB: The figure is simply the top edge of your crystal sideband filter + an optional 300 Hz offset to attenuate the sub 300 Hz frequencies and allow more higher frequencies through the pass band.
//
// For LSB: To avoid sideband inversion the BFO (and LO) are dropped by the filter bandwidth plus a further 300 Hz frequency offset (see above). So LSB = top edge of filter - filter B/W - 300 Hz.
volatile uint32_t LSB = 1332460000ULL; // 2.4 kHz 13.3 MHz (8 Pole) Filter
volatile uint32_t USB = 1332790000ULL; // 2.4 kHz 13.3 MHz (8 Pole) Filter
volatile uint32_t bfo = 1332790000ULL; // 2.4 kHz 13.3 MHz (8 Pole) Filter (USB)
//These USB/LSB frequencies are added to or subtracted from the vfo frequency in the "Loop()"
volatile uint32_t vfo = 1806800000ULL / SI5351_FREQ_MULT; // Starting RF frequency - the LO is calculated from this and the BFO
//volatile uint32_t vfo = 380000000ULL / SI5351_FREQ_MULT; // Starting RF frequency - the LO is calculated from this and the BFO
volatile uint32_t radix = 1000; //start step size - change to suit
boolean changed_f = 0;
String tbfo = "";
//------------------------------- Set Optional Features here --------------------------------------
//Remove comment (//) from the option you want to use. Pick only one
#define IF_Offset //Output is the display plus or minus the bfo frequency
//#define Direct_conversion //What you see on display is what you get
//#define FreqX4 //output is four times the display frequency
//--------------------------------------------------------------------------------------------------
/**************************************/
/* Interrupt service routine for */
/* encoder frequency change */
/**************************************/
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result == DIR_CW)
set_frequency(1);
else if (result == DIR_CCW)
set_frequency(-1);
}
/**************************************/
/* Change the frequency */
/* dir = 1 Increment */
/* dir = -1 Decrement */
/**************************************/
void set_frequency(short dir)
{
if (dir == 1)
vfo += radix;
if (dir == -1)
vfo -= radix;
// if(vfo > F_MAX)
// vfo = F_MAX;
// if(vfo < F_MIN)
// vfo = F_MIN;
changed_f = 1;
}
/**************************************/
/* Read the button with debouncing */
/**************************************/
boolean get_button()
{
if (!digitalRead(ENCODER_BTN))
{
delay(20);
if (!digitalRead(ENCODER_BTN))
{
while (!digitalRead(ENCODER_BTN));
return 1;
}
}
return 0;
}
/**************************************/
/* Displays the frequency */
/**************************************/
void display_frequency()
{
uint16_t f, g;
lcd.setCursor(3, 0);
f = vfo / 1000000;
if (f < 10)
lcd.print(' ');
lcd.print(f);
lcd.print('.');
f = (vfo % 1000000) / 1000;
if (f < 100)
lcd.print('0');
if (f < 10)
lcd.print('0');
lcd.print(f);
lcd.print('.');
f = vfo % 1000;
if (f < 100)
lcd.print('0');
if (f < 10)
lcd.print('0');
lcd.print(f);
lcd.print("Hz");
lcd.setCursor(0, 1);
lcd.print(tbfo);
Serial.println(vfo + bfo);
Serial.println(vfo);
Serial.println(tbfo);
}
/**************************************/
/* Displays the frequency change step */
/**************************************/
void display_radix()
{
lcd.setCursor(9, 1);
switch (radix)
{
case 1:
lcd.print(" 1");
break;
case 10:
lcd.print(" 10");
break;
case 100:
lcd.print(" 100");
break;
case 1000:
lcd.print(" 1k");
break;
case 10000:
lcd.print(" 10k");
break;
case 100000:
// lcd.setCursor(10, 1);
lcd.print(" 100k");
break;
case 1000000:
// lcd.setCursor(9, 1);
lcd.print(" 1M"); //1MHz increments
break;
}
lcd.print("Hz");
}
void splash_screen()
{
lcd.setCursor(2, 0);
lcd.print("M 0 N T V");
lcd.setCursor(3, 1);
lcd.print("HOMEBREWING");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Basic Si5351 VFO");
lcd.setCursor(3, 1);
lcd.print("Version 4.5");
delay(2000);
lcd.clear();
}
void setup()
{
Serial.begin(19200);
lcd.begin(16,2);
lcd.backlight();// Initialize and clear the LCD
lcd.clear();
Wire.begin();
pinMode(13, OUTPUT); // Transmit LED - You'll need a wire from pin 13 to a red LED via a biasing resistor.
pinMode(12, INPUT); // PTT Sensor - You'll need a wire from pin 12 which will be the PTT line. When this line is grounded (by the switch in your microphone) then the Arduino goes into Transmit Mode.
digitalWrite(12, HIGH); // Set PTT Sensor to HIGH so actual pressing of PTT will ground it and make it LOW
splash_screen();
//SET Si5351 Calibration Correct Factor in 3rd paramater to ".init()" below. (Mine are: Tartan Tin = 29700, Rainbow Striped Tin = 97400)
//initialize the Si5351
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 97400); // If you're using a 27Mhz crystal, put in 27000000 instead of 0
// 0 is the default crystal frequency of 25Mhz.
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
// Set CLK0 to output the starting "vfo" frequency as set above.
//SET Si5351 Drive Strength:
si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_4MA); // Use 2 mA for driving an NE602/612 (SA602/612) active mixer (but more for a passive diode ring mixer)
//si5351.drive_strength(SI5351_CLK1,SI5351_DRIVE_2MA); // You can set these drive levels to 2MA, 4MA, 6MA or 8MA - measured into a 50 Ohm load
si5351.drive_strength(SI5351_CLK2,SI5351_DRIVE_8MA); //
#ifdef IF_Offset
volatile uint32_t vfoT = (vfo * SI5351_FREQ_MULT) + bfo;
tbfo = "USB"; // SET TO STARTUP SIDEBAND
// Set CLK2 to output bfo frequency
si5351.set_freq( bfo, SI5351_CLK2);
#endif
#ifdef Direct_conversion
si5351.set_freq((vfo * SI5351_FREQ_MULT), SI5351_CLK0);
#endif
#ifdef FreqX4
si5351.set_freq((vfo * SI5351_FREQ_MULT) * 4, SI5351_CLK0);
#endif
pinMode(ENCODER_BTN, INPUT_PULLUP);
PCICR |= (1 << PCIE2); // Enable pin change interrupt for the encoder
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
display_frequency(); // Update the display
display_radix();
}
void loop()
{
// ---------------------------------------------------------------------
// Determine TRANSMIT or RECEIVE Mode
// ---------------------------------------------------------------------
if (digitalRead(12) == LOW) // If PTT is pressed then we are in TRANSMIT
{
// Things that need to happen in TRANSMIT mode:
digitalWrite(13, HIGH); // Transmit LED is switched ON
}
else
{
// Things that need to happen in RECEIVE mode:
digitalWrite(13, LOW); // Transmit LED is switched OFF
}
// ---------------------------------------------------------------------
// Update the display if the frequency has been changed
if (changed_f)
{
display_frequency();
#ifdef IF_Offset
si5351.set_freq((vfo * SI5351_FREQ_MULT) + bfo, SI5351_CLK0);
//you can also subtract the bfo to suit your needs
//si5351.set_freq((vfo * SI5351_FREQ_MULT) - bfo , SI5351_CLK0);
if (vfo >= 10000000ULL & tbfo != "USB")
{
bfo = USB;
tbfo = "USB";
si5351.set_freq( bfo, SI5351_CLK2);
Serial.println("We've switched from LSB to USB");
}
else if (vfo < 10000000ULL & tbfo != "LSB")
{
bfo = LSB;
tbfo = "LSB";
si5351.set_freq( bfo, SI5351_CLK2);
Serial.println("We've switched from USB to LSB");
}
#endif
#ifdef Direct_conversion
si5351.set_freq((vfo * SI5351_FREQ_MULT), SI5351_CLK0);
tbfo = "";
#endif
#ifdef FreqX4
si5351.set_freq((vfo * SI5351_FREQ_MULT) * 4, SI5351_CLK0);
tbfo = "";
#endif
changed_f = 0;
}
// Button press changes the frequency change step for 1 Hz steps
if (get_button())
{
switch (radix)
{
case 1:
radix = 10;
break;
case 10:
radix = 100;
break;
case 100:
radix = 1000;
break;
case 1000:
radix = 10000;
break;
case 10000:
radix = 100000;
break;
case 100000:
radix = 1000000;
break;
case 1000000:
radix = 1;
break;
}
display_radix();
}
}
Try placing Wire.begin() before lcd.begin(), or removing Wire.begin() completely (the LiquidCrystal_I2C library I have here already calls Wire.begin() inside the library).
try so
void setup()
{
Serial.begin(19200);
lcd.init();
lcd.init(); // yes, twice, this helps some ppl
lcd.backlight();// Initialize and clear the LCD
lcd.clear();
lcd.print(" start");
pinMode(13, OUTPUT); // Transmit LED - You'll need a wire from pin 13 to a red LED via a biasing resistor.
pinMode(12, INPUT); // PTT Sensor - You'll need a wire from pin 12 which will be the PTT line. When this line is grounded (by the switch in your microphone) then the Arduino goes into Transmit Mode.
digitalWrite(12, HIGH);
but still not clear why it work after upload
Be careful with swapping lcd.init() for lcd.begin(), the library that supports begin() likely does not have an init().
for sure. i think, init()
and begin()
difference allows to use both type of devices w/out collision.
Another suggestion, put delay(1000) at the start of setup(), there may be something about the LCD that requires a longer reset time, although I've never had that problem.
The bootloader on the UNO will execute the sketch code immediately after a power-on reset, but delays a couple of seconds after any other type of reset, such as that caused by uploading a sketch or opening the serial monitor.
Welcome back!
Please read this post:
How to get the best out of this forum
We need a lot more information, What are the sketches? Please post both of them in code tags. What is your circuit like? Please post a schematic.
David. I placed the Wire.begin() before Lcd.begin() and it works! Thanks a lot! Hans
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.