(need help coding) making a square wave generator 30 to 1MHz

Hi. i am new to coding and i am trying to make square wave generator(50% duty cycle)but i ran into a problem. The code that i found and use starts jumping numbers when the frequency gets higher(and i want it to go up or down one at a time).I tried to modify the code but with no success.
Can you please help me?...Thank you and have a nice day!

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include <FrequencyTimer2.h>

#include <Bounce2.h>

#define BUTTON_PIN_1 2
#define BUTTON_PIN_2 3
#define BUTTON_PIN_3 4

#define LED_PIN 13


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

static const unsigned char PROGMEM logo[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x3F, 0x80,
0x07, 0x9E, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x03, 0xFC, 0x3F, 0x80,
0x07, 0x9E, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x03, 0xFC, 0x3F, 0x80,
0x07, 0x9E, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0x3E, 0x73, 0x9C, 0x00, 0x78, 0x3E, 0x3E, 0xF0, 0xF0, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0x7F, 0x33, 0x98, 0x00, 0x78, 0x7F, 0x3E, 0xF1, 0xF8, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0x7F, 0x33, 0xB8, 0x00, 0x78, 0x7F, 0x3E, 0xF3, 0xFC, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0xFE, 0xE7, 0x33, 0xB8, 0x00, 0x78, 0x73, 0xBE, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0xFE, 0xE7, 0x3F, 0xF9, 0xF0, 0x78, 0x73, 0xBE, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0xFE, 0xE7, 0x3F, 0xF9, 0xF0, 0x78, 0x73, 0xBE, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0xFE, 0xE7, 0x3F, 0xF8, 0x00, 0x78, 0x73, 0xBE, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0xE7, 0x3F, 0xF0, 0x00, 0x78, 0x73, 0xBE, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0xE7, 0x1F, 0xF0, 0x00, 0x78, 0x73, 0xBE, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0xE7, 0x1E, 0xF0, 0x00, 0x78, 0x73, 0xBF, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0xE7, 0x1E, 0xF0, 0x00, 0x78, 0x73, 0xBF, 0xF3, 0x9C, 0x00, 0x03, 0x0C, 0x30, 0x00,
0x07, 0x9E, 0x7F, 0x1E, 0xF0, 0x00, 0x78, 0x7F, 0x3F, 0xE3, 0xFC, 0x00, 0x7F, 0x0F, 0xF0, 0x00,
0x07, 0x9E, 0x7E, 0x1E, 0xF0, 0x00, 0x78, 0x3F, 0x3F, 0xC1, 0xF8, 0x00, 0x7F, 0x0F, 0xF0, 0x00,
0x07, 0x9E, 0x1C, 0x1C, 0xE0, 0x00, 0x78, 0x1C, 0x3F, 0x00, 0xF0, 0x00, 0x7F, 0x0F, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#define SSD1306_LCDHEIGHT 64
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

float P=7042;
unsigned int P1;
unsigned long Hout;
unsigned long Sp;
unsigned long Sm;
unsigned long H;
unsigned long N1=1;
unsigned long N2=10;
unsigned long N3=20;
unsigned long N4=150;
unsigned long E=LOW;
unsigned long E1=0;

unsigned long Min;
unsigned long Plus;

// Instantiate a Bounce object
Bounce debouncer1 = Bounce(); 

// Instantiate another Bounce object
Bounce debouncer2 = Bounce(); 


// Instantiate another Bounce object
Bounce debouncer3 = Bounce(); 

void setup() {
pinMode(FREQUENCYTIMER2_PIN, OUTPUT);

  // Setup the first button with an internal pull-up :
  pinMode(BUTTON_PIN_1,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  debouncer1.attach(BUTTON_PIN_1);
  debouncer1.interval(5); // interval in ms

   // Setup the second button with an internal pull-up :
  pinMode(BUTTON_PIN_2,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  debouncer2.attach(BUTTON_PIN_2);
  debouncer2.interval(5); // interval in ms
  
   // Setup the second button with an internal pull-up :
  pinMode(BUTTON_PIN_3,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  debouncer3.attach(BUTTON_PIN_3);
  debouncer3.interval(5); // interval in ms

 
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  display.display();
  display.clearDisplay();
  display.drawBitmap(0, 0, logo, 128, 32, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();

  FrequencyTimer2::setPeriod(200);
  FrequencyTimer2::enable();
}

volatile unsigned long burpCount = 0;

void Burp(void) {
  burpCount++;
}


void loop() {

  debouncer1.update();
  debouncer2.update();
  debouncer3.update();
  
  // Get the updated value :
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();
  int value3 = debouncer3.read();



if(P1==1){
  Min = Min;
}
else {
  Min = Hout - (1000000/(P1+1));
}

Plus = Hout - (1000000/(P1+1));

  // Turn on the LED if either button is pressed :
  if ( value2 == LOW ) {
    Sp++;
    if(Sp > N1){
    P++;}
    if(Sp > N2){
    P = P + 10;}
    if(Sp > N3){
    P = P + 100;}
    if(Sp > N4){
    P = P + 1000;}
    if (P>100000){
      P = P+5000;
    }
    digitalWrite(LED_PIN, HIGH );
  } 

 if ( value1 == LOW) {
    Sp++;
    if(Sp > N1){
    P--;}
    if(Sp > N2){
    P = P - 10;}
    if(Sp > N3){
    P = P - 100;}
    if(Sp > N4){
    P = P - 1000;}
    digitalWrite(LED_PIN, HIGH );
  } 


 if ( value3 == LOW) {
    E1++;
    if (E1 == 1){
      E = !E;
    }
    
    digitalWrite(LED_PIN, HIGH );
  } 

if ( value1 == HIGH  && value2 == HIGH && value3 == HIGH ){
  E1=0;
  Sp=0;
  digitalWrite(LED_PIN, LOW );
}



if (E == HIGH){
  FrequencyTimer2::enable();
}
if (E == LOW){
  FrequencyTimer2::disable();
}

if (P<30){
  P=30;
}
if (P>1000000){
  P=1000000;
}

P1 = 1000000/P;

FrequencyTimer2::setPeriod(P1);

static unsigned long v = 0;
  if ( Serial.available()) {
    char ch = Serial.read();
    switch(ch) {
      case '0'...'9':
        v = v * 10 + ch - '0';
        break;
      case 'p':
        FrequencyTimer2::setPeriod(v);
        Serial.print("set ");
        Serial.print((long)v, DEC);
        Serial.print(" = ");
        Serial.print((long)FrequencyTimer2::getPeriod(), DEC);
        Serial.println();
        v = 0;
        break;
      case 'r':
        Serial.print("period is ");
        Serial.println(FrequencyTimer2::getPeriod());
        break;
      case 'e':
        FrequencyTimer2::enable();
        break;
      case 'd':
        FrequencyTimer2::disable();
        break;
      case 'o':
        FrequencyTimer2::setOnOverflow(Burp);
        break;
      case 'n':
        FrequencyTimer2::setOnOverflow(0);
        break;
      case 'b':
        unsigned long count;
        noInterrupts();     // disable interrupts while reading the count
        count = burpCount;  // so we don't accidentally read it while the
        interrupts();       // Burp() function is changing the value!
        Serial.println(count, DEC);
        break;
    }
  }

Hout = 1000000/FrequencyTimer2::getPeriod();


display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(Hout);
display.println("Hz");
if (E == LOW){
  display.println("OFF");
}
if (E == HIGH){
  display.println("ON");
}
//display.println(P1);
//display.println(Sp);
display.display();
}

The code that i found and use starts jumping numbers when the frequency gets higher(and i want it to go up or down one at a time)

What does that mean?
Do you mean you want the frequency to increment in steps of one Hz at each step?

If so forget it just using the Arduino, you need some hardware help.

Yes ....and i have the hardware schematic in the attached file

pmetru:
Yes ....and i have the hardware schematic in the attached file

No read that reply again. I said YOU need some hardware help with this, that means you need to add hardware to get what you need.

Ok thanks ...but can you tell me what i need to add in order to make this thing work properly.?sorry if this seems stupid but i am new to this and is also a learning process.

An Arduino runs at 16 MHz clock; that's the resolution of frequency you can get.

1 MHz is no problem.

1,000,001 Hz doesn't work. But do you really need that kind of steps?

pmetru:
can you tell me what i need to add in order to make this thing work properly?

If by properly you mean in 1Hz steps then something like this might work:- http://uk.farnell.com/analog-devices/ad9833brmz/waveform-generator-9833-msop10/dp/1581966
You can get similar things on a breakout board from ebay.

sorry if this seems stupid but i am new to this and is also a learning process.

Not stupid at all.

However as an important part of learning is to learn what specification you need. So if you tell us what you are doing and why we can assess if having a 1Hz resolution is desirable or even feasible.

You see one Hz in 106 Hz is more accurate than the crystal on an Arduino anyway, so generating something with that accuracy requires a much more accurate clock than you actually have. So in most cases setting the frequency to the next whole number of Hz is meaningless. Don't get me wrong you can do this but it is not a throw together project. It will require quite a bit of skill and some expensive test equipment.

i am trying to make this wave generator because i want to test an electrolytic cell at different frequencies to find the best efficiency of the cell(I think if i have all the frequencies I will have a better result)

I think if i have all the frequencies I will have a better result

No, you won't. You don't have time to test one million frequencies.

Ten widely spaced frequencies selected from the entire range would be a good start.

Indeed, you don't need every single frequency. Also as 1 Hz - 2 Hz is a much bigger step than 1,000,000 Hz - 1,000,001 Hz.

From experience/literature you will likely know where to start, and where to expect the most optimal frequency. Do a sweep starting say two orders of magnitude lower, each step doubling the frequency, then you can narrow it down, take a smaller range, smaller resolution. Ending up doing 1% steps around the frequency where you find the optimum is almost certainly good enough.

I think if i have all the frequencies I will have a better result

As the others have said, no it won't be better. You will have far too much information to be able to cope with.

When you say test a capacitor what are you testing?

And what do you mean by:-

to find the best efficiency of the cell

Capacitors don't have "efficiency" they have capacitave reactance and inductive reactance. At the above the resonant point the capacitor looks like an inductor to the circuit and no longer acts as a capacitor. You could find that resonant point but that is not a frequency you want to use a capacitor at. You need to use it well below this point.

When I saw "electrolytic cell" I was thinking about electrolyses, rather than a capacitor.

Now electrolyses is usually done using DC, so it still doesn't make sense.

pmetru:
i am trying to make this wave generator because i want to test an electrolytic cell at different frequencies to find the best efficiency of the cell(I think if i have all the frequencies I will have a better result)

OK, so what you actually want is a series of frequency steps, each of which is say, approximately 1.5 times the previous. Rather like the preferred resistor values series in fact, so 1.0, 1.5, 2.2, 3.3, 4.7, 6.8, 10, then 15, 22, 33 and so on.

With this range of frequencies, you can do the generation quite easily with the timers in the Arduino.

FHJBRA9J80GN0YN.LARGE.jpg

Mind you, you do need to explain what it is you are doing and what you mean by an "electrolytic cell". But I cannot imagine it is a resonant device, so the frequency will not need to be in any way exact.

it is a an electrolysis cell ....and yes ....i am I'm looking for the resonant frequency of the entire system(i have a inductor and the cell would be like a capacitor)

What is the use of AC in electrolysis, other than preventing it from happening in the first place?

If you measure the capacitance and inductance of your system you can get at the very least a ball park figure for the resonant frequency. That saves you doing that first 1.5-times-stepping sweep of the full range (and hope your resonance is actually there).