Algorithm

Does anyone bother with creating an Algorithm before writing their code? What really is an Algorithm in the context of programming? I might be thinking of something different.

I'm trying to determine the programming approach for addressing more than one objective, and my limited programming experience makes it difficult to envision how the routines should be defined and called.

What I want to do is create a sweep frequency generator. The generator will have two modes, CW and Sweep. The setup parameters will be controlled by a single rotary knob and momentary button.

At boot, the generator starts in a default condition, CW @ 10 MHz output (set via setup).

When the button is pressed, it toggles through various settings, and the knob changes the value. The settings are not only changed in the code, but are also sent to an LCD where the cursor will blink at the selected parameter:

Mode (CW or Sweep)
Frequency decade value (toggles through each decade, then to mode)
Step decade value

The open parameter will expire after a few seconds.

Each of these pieces I can do individually in a simple loop, but I'm not sure how to accomplish these all together.

For example, I have programmed the generator for a CW frequency within a loop that monitors the rotary encoder, and can change the value a fixed amount with the encoder. I can write a loop that sweeps frequency between hard coded start and stop frequencies and step size, but have not yet added the encoder.

The hard one now seems to be when the generator is sweeping, I push the button to change the start frequency, and the knob adjusts the start while sweeping.

Anyway, rather than go the brute force way and start coding, it seems it would be more efficient to script a higher level program outline as a development guide. Something to define what should be standalone functions, what goes in the main loop, which variables need to be global, etc...

I'm likely to spend a lot of time writing some seriously messy and inefficient code if I just started cold now.

Any tips on how to start?

C2:
Does anyone bother with creating an Algorithm before writing their code?

If I need any I do. I might even write pseudocode as comments and use that as a guide to write my working code. But I draw the line at flowcharts. I don't do flowcharts.

I hope that any of this can help you.

I googled 'DDS signal generator avr' and got a load of hits, some like this up to 8 MHz one:
http://www.scienceprog.com/avr-dds-signal-generator-v20/

And there are modules capable of far higher speed for good prices:
http://www.lctech-inc.com/Hardware/Detail.aspx?id=38fd4f22-f54c-4b31-9c8e-d0aaa7a0931d
I know that company through deals I get there. You can ask for docs in English, they have even provided me with schematics when asked before.

Thanks Mr. Smoke. I do have a ton of links to DDS generators and various code. Part of the process for me is learning programming techniques so they can be applied in other areas. The signal generator is a good project to learn with. Maybe in the end I'll be lucky if I can get half of what I want to actually work... :slight_smile:

But I draw the line at flowcharts. I don’t do flowcharts.

I do do flow charts and I find them very useful for seeing the flow of the program. Not formal flowcharts but just ones with decision diamonds and action rectangles.
What you need is the technique used in the blink without delay example. Do a flow chart of that code and you will easily see how to extend it to meet your needs.

Might I suggest that you learn the Blink Without Delay example as a way to make things happen on a time basis? Then look up 'finite state engine' on the site search here as the other part to real-time coding?

Or --- both lessons combined with clear and simple explanations to go with the code?

But what if you want to blink the two LEDs at different rates? Like, once a second for LED 1 and twice a second for LED 2?

This is where the delay function doesn't really help.

Let's look at an analogy. Say you want to cook breakfast. You need to cook:

Coffee - takes 1 minute
Bacon - takes 2 minutes
Eggs - takes 3 minutes

Now a seasoned cook would NOT do this:

Put coffee on. Stare at watch until 1 minute has elapsed. Pour coffee.
Cook bacon. Stare at watch until 2 minutes have elapsed. Serve bacon.
Fry eggs. Stare at watch until 3 minutes have elapsed. Serve eggs.

The flaw in this is that whichever way you do it, something is going to be cooked too early (and get cold).

In computer terminology this is blocking. That is, you don't do anything else until the one task at hand is over.

What you are likely to do is this:

Start frying eggs. Look at watch and note the time.
Glance at watch from time to time. When one minute is up then ...
Start cooking bacon. Look at watch and note the time.
Glance at watch from time to time. When another minute is up then ...
Put coffee on. Look at watch and note the time.
When 3 minutes are up, everything is cooked. Serve it all up.

In computer terminology this is non-blocking. That is, keep doing other things while you wait for time to be up.

Does anyone bother with creating an Algorithm before writing their code?

Is there another way? :wink:

Does anyone bother with creating an Algorithm before writing their code?

"Writing a code" does not necessarily mean you are creating/implementing an algorithm. You can easily write a code which does ie. an FFT spectral analysis of an incoming signal without having got an idea about the FFT algorithm itself. This is how arduino-ecosystem works.. :0

robtillaart:

Does anyone bother with creating an Algorithm before writing their code?

Is there another way? :wink:

Yes. I've been seeing it since I got here. It usually starts with words like "Help! Help!".

I can forsee some Help! Help! moments in my future.

I was studying Gammon's blink code and suddenly what came to me was, why are the initializations outside of the setup function?

C2:
Does anyone bother with creating an Algorithm before writing their code? What really is an Algorithm in the context of programming? I might be thinking of something different.

I'm trying to determine the programming approach for addressing more than one objective, and my limited programming experience makes it difficult to envision how the routines should be defined and called.

Very good question - in fact I think it is two questions.

First you need to understand the functionality you want to implement, in terms of the major data structures and algorithms. There are lots of different ways to represent these things and you can use whatever method works best for you in a given situation - one of the most useful skills for a designer is the ability to choose the best way to abstract something, and this largely comes with experience. Unless somebody is paying you to deliver a design, you only need to do this for the parts necessary and to the level of detail necessary for you to understand how it's going to work. If the problem is easy (relative to your capabilities) then you might do this in your head as you're writing the code, but if you're tackling something difficult you might want to write stuff down and think it through until you understand it thoroughly before you start coding.

Then you need to design the overall architecture or structure of your code. Will it be blocking or non-blocking, polling for events or triggered by callbacks, object-oriented or not, etc - what is the main control structure of your code going to look like and what approach will you use to compose it from bits of code? There is no one right answer and it depends which approaches you find easiest to understand and how complex a problem you are trying to solve, but in general I prefer a polling non-blocking approach with finite state machines where necessary, and if I need to do something several times I will usually get it working once and then move the logic and associated data into a class/classes and create as many instances as necessary. Remember to keep logically independent functional areas isolated in your code, for example you don't want the code to update your configuration from the serial port to be mixed up with the code to save your configuration in EEPROM, and you don't want any of that mixed up with code to control LEDs and so on.

C2:
I can forsee some Help! Help! moments in my future.

I was studying Gammon's blink code and suddenly what came to me was, why are the initializations outside of the setup function?

Functions are things that happen during run time.
Defines and includes are pre-compiled.

Variable declarations may be made pre-compiled or during run time and may be stored on the heap or on the stack. What code can access a variable depends on scope and pre-compiled variables are usually global in scope with exceptions requiring extra syntax.

pito:

Does anyone bother with creating an Algorithm before writing their code?

"Writing a code" does not necessarily mean you are creating/implementing an algorithm. You can easily write a code which does ie. an FFT spectral analysis of an incoming signal without having got an idea about the FFT algorithm itself. This is how arduino-ecosystem works.. :0

You are misunderstanding what an algorithm is.
Yes you don't have to know how the FFT works but the algorithm is how you are implementing that function into your code what you feed into it, what you get out of it and what you do with the output. All that is an algorithm.

This is how I was envisioning an algorithm for my RF sweep synthesizer, any suggestions welcome.

Boot default CW mode @ 10 MHz

I was thinking of putting all setting parameters into a function, all as global variables, that is called via a button interrupt. Button selects the following parameters to edit, a rotary knob changes value:

mode: cw | sweep
F1: frequency start MHz (knob +/- 1,000,000)
F1: frequency start kHz (knob +/- 1,000)
F1: frequency start Hz (knob +/- 1)
F2: frequency stop MHz (knob +/- 1,000,000)
F2: frequency stop kHz (knob +/- 1,000)
F2: frequency stop Hz (knob +/- 1)
numSteps: on | off
numSteps: (knob +/- 1)
stepSize: on | off
stepSize: MHz (knob +/- 1,000,000)
stepSize: kHz (knob +/- 1,000)
stepSize: Hz (knob +/- 1)
sweepTime: on | off
sweepTime: us (knob +/- 1)
dwellTime: on | off
dwellTime: (knob +/- 1)

The parameter edit function may exit with a button press or after a set amount of time without activity.

F2, numSteps, stepSize, sweepTime, and dwellTime only apply when sweep mode is selected.
numSteps and stepSize have to be mutually exclusive as one is automatically calculated when the other is selected.
sweepTime and dwellTime have to be mutually exclusive as one is automatically calculated when the other is selected.

The main loop calls the cw function or sweep function depending on selected mode, probably using a while loop.