# Math / Logic Problem

I’ve just gotten stuck…

I have the following integers:

F1 = 1     // start frequency
F2 = 100 // stop frequency
Fd = 1    // frequency step size
Fn = 99  // number of frequency points

Now the problem is if I change Fn to 98, Fd is recalculated and is still 1. That means Fn is incorrect.

What I want to happen is if Fn is decremented, the next lowest value should be a possible number of frequency points (49 here). This allows Fd = 2. The next lowest value should be 33; the next lowest should be 24, etc.

I’m looking for the solution that results in the proper Fn points for any values of F1 and F2 (F1 is always lower than F2 and all values are positive) when changing Fn by 1s, 10s, 100s, etc.

I tried to do it by changing Fd and then calculating Fn instead of directly changing Fn, but I run into other issues when moving back and forth, I’m not landing on the right points again.

Fd = Fd - Fd * delta; // delta is multiplying by 1s, 10s, 100s, etc.
Fn = (F2 - F1) / Fn;
if (Fn < 1) {
Fd = Fd  + delta;
}
Fn = (F2 - F1) / Fd;

integers tend to be whole numbers
100/98 is not a whole number
try a float

If Fn is float, it is still wrong because the step size is limited to whole numbers.

ah I see
you want something to generate
99 = 100-1 = 100/1 - 1
49 = 50-1 = 100/2 - 1
32 = 33-1 = 100/3 - 1
24 = 25 - 1 = 100/4 - 1
19 = 20 - 1 = 100/5 - 1

can you see where this is going

Not really since all the numbers are variables and F1 and F2 can be set all the way up to 40000000.

F1 = 1000000
F2 = 3000000
Fd = 100
Fn = 20000

The next lower Fn that could be set is 19801; the next higher Fn is 20202.

ok
then you need to state the problem more clearly
which are the input variables and which are outputs
and what are the constraints

All 4 variables are user settable integers. The only constraints are that max frequency is 40 MHz and the integers must all be positive, but there are many obvious dependencies.

For example, if user changes F1, the step size is not changed, but the # of steps must be recalculated. There are a few other checks like F1 cannot be larger than F2 or F1 cannot be set closer to F2 than Fd...

I'm just stuck with the one dependency, that when user changes Fn I discovered that I cannot just have Fn increment by 1's, 10's, etc. because (F2-F1)/Fd does not result in every Fn increment.

My problem goes away if I just don't let the user adjust Fn, so I started looking for a way I could have the user believe they are changing Fn by having Fd change instead, and then update Fn based on the new Fd value. This worked partially but would get out of sync or go negative at times.

Another idea I had was to increment Fn by some calculated value based on Fd. In my first example, Fd is 1, so the next Fd is 2. When Fd is 2, Fn = (100-1)/2 = 49.5, but should result in 50, so I can just add a small constant to get the number out right. I could not get this working right all the time either.

but I got confused when the start and stop frequencies got larger.

Call you variables:

Fstart
Fstop
Fstep
Fpoints

Otherwise it is hard to follow..

I'm sure this bit of code looks strange

Fd = Fd - Fd * delta;

acboother:
I'm sure this bit of code looks strange

Fd = Fd - Fd * delta;

Why? just a backwards loop - probably ends somewhere near zero ..

I'm a little confused. Is this actual code that you are running on Arduino? Or, are you just trying to figure out some formula that works the way you want? Both?
Depending on those answers....
Which Arduino board are you using? Where's rest of code? How are you defining these integers at beginning of code? When is "delta" defined/introduced?

Without meaning to be unkind, what I can’t understand is why you ever thought this would be possible.

It seems to me that you need to have a good think about your requirements and choose some scheme that can work rather than try to find some sort of fudge to hide the fact the you can’t have an integer step size for every number of steps, or else you can’t have an integer number of steps for every step size.

…R

C2:
I’m just stuck with the one dependency, that when user changes Fn I discovered that I cannot just have Fn increment by 1’s, 10’s, etc. because (F2-F1)/Fd does not result in every Fn increment.

Robin, it is possible to limit the values to common values that work. The only number here that is really constrained is the number of steps. The step size can be any integer (as long as smaller than F2-F1 and >0).

I've used commercial sweep synthesizers that have step size limited to 10k increments, and their code will figure out the appropriate number of steps when changing that value. It does not seem like a circular reference problem, if that is what you mean by suggesting that it is not possible.

I mean its not mathematically possible to have an integer number of steps and an integer step size and every possible combination of upper and lower limit. At its simplest it is not possible to have an integer number of steps of stepsize 2 between 0 and 5 - you can only have 0, 2, 4 and 6 so you must choose to limit the range to 4 or 6.

...R

Gosh! Please try the following...

Write a small utility function that does what you want and call it from within a basic sketch (blink will do) with a the range of input values you think you want to be the input.

Post the code here and may be we can work out what your algorithm is trying to do/be.

I suspect you want integer outputs and are performing what should be floating point calculations...

Robin, that is what my problem is and what I'm trying to solve.

In that simplest case (between 0 and 5?), you CAN have two steps:

F1 = 0
F2 = 5
step size = 2
number of steps (should) = 2

The synthesizer will step (Hz): 0, 2, 4, 0, 2, 4, ... that's two steps per sweep.

I can post a complete version of my code in about 5 hours that at least functions, but will set number of steps incorrectly. It is 25k and has a lot of other intertwined functions that are hard to separate,

or

I can try and mock up a simpler example...

In my mind, your simplest (But maybe not the most elegant solution) is to do all of the calculations in float, then cast your values back into int, probably checking for duplicate numbers (or not, you'll just get duplicate results sometimes).

I can try and mock up a simpler example...

Good idea, 25k of 'other' code isn't going to help

I may use float, or another idea was to carefully multiply integers by 1000 to gain a few more significant digits, then divide the output by 1000...

C2:
I've just gotten stuck...

I have the following integers:

F1 = 1     // start frequency

F2 = 100 // stop frequency
Fd = 1    // frequency step size
Fn = 99  // number of frequency points

Now the problem is if I change Fn to 98, Fd is recalculated and is still 1. That means Fn is incorrect.

Well, you chose it (value for Fn). How are you "changing" these values? Or, how do intend to on finished project? (Typing in? Serial monitor on PC? Knob? Pot? Keypad? Speech recognition?)

What I want to happen is if Fn is decremented, the next lowest value should be a possible number of frequency points (49 here). This allows Fd = 2. The next lowest value should be 33; the next lowest should be 24, etc.

After reading this a few dozen times, I think you want "it" to limit your possible choices of values for Fn based on what the other values currently are. ....am I close? Is it decrementing itself? Is the user decrementing?

C2:
Not really since all the numbers are variables and F1 and F2 can be set all the way up to 40000000.

Not if F1 & F2 are int's & you're using an Arduino UNO...

On the Arduino Uno (and other ATMega based boards) an int stores a 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 (minimum value of -2^15 and a maximum value of (2^15) - 1).
On the Arduino Due, an int stores a 32-bit (4-byte) value. This yields a range of -2,147,483,648 to 2,147,483,647 (minimum value of -2^31 and a maximum value of (2^31) - 1).

Is this some matter of national security? Is there a reason you're limiting the amount of information you're giving us?
If your 'other code' is about 25K...I'm guessing this is just a tiny piece of a MUCH LARGER goal. Any chance of you telling us what that end goal might be? Why are you trying to get these values? How are these values being changed during use? (User input? Etc..?) What board are you using?
Do forgive me if I have somehow just overlooked some of that information.

Thank you.