Flowchart example

Hi All
for my own benefit I have done this flowchart that clarify to me the flow control of a library I was looking at (just to improve my understanding of libraries and c++ in general). You can find the library at this address: GitHub - fellipecouto/ButtonControl: Library to control push button click times. Short clicks, long clicks and double clicks. Click count and button press time..

I was struggling initially to understand the second part of (void verifyButton(bool fast, bool doubleClick) so I decided that having a small flowchart could help.

I thought that having this kind of flowcharts, where I can visually see how a function works, may help me to improve my coding. So I am putting it here in case it may help others who are learning.
If you find any mistake in it feel free to point it out and correct it.

I am pasting the function below:

void ButtonControl::verifyButton(bool fast, bool doubleClick) {
  _buttonTimes = 0;
  _buttonClicks = 0;
  _longClick = false;
  while (digitalRead(_pin) == _signal) {
    _buttonTimes++;
    if (_buttonTimes >= _continuousTime && _continuous) break;
    delay(1);
  }
  if (_buttonTimes > _debounceTime) {
    _buttonClicks++;
    if (fast) return;
    if (_buttonTimes >= _longMinClickTime) {
      _longClick = true;
    } else {
      bool loopClick = true;
      while (loopClick) {
        int timeNotPressedValue = 250;
        int timeNotPressedCount = 0;
        while (digitalRead(_pin) == !_signal) {
          timeNotPressedCount++;
          if (timeNotPressedCount >= timeNotPressedValue) {
            loopClick = false;
            break;
          }
          delay(1);
        }
        if (timeNotPressedCount < timeNotPressedValue) {
          _buttonTimes = 0;
          while (digitalRead(_pin) == _signal) {
            _buttonTimes++;
            delay(1);
          }
          if (_buttonTimes > 20) _buttonClicks++;
          if (_buttonClicks == 2 && doubleClick) loopClick = false;
        }
      }
    }
  }
}
1 Like

What kind of flowchart is that? Please post a link to any documentation for this style of flowchart.

I'd need to learn how to read such a flowchart, it is different to any I have seen, and I assume you weren't just making stuff up as you drew it.

a7

not using exactly the same symbol names as in the code makes it hard to compare the flowchart to the code.

the code is confusing. it's not clear what the purpose of verifyButton() is. does verify mean that it confirms some existing state?

looks like the code attempts to measure the # of iterations (not time despite naming symbols "time") that the pin matches the state of _signal and then optioinally, depending on the value of _buttonTimes,

  • returns immediately of fast is set or
  • returns if _buttonTimes > longMinClickTime or
  • waits for the pin to be opposite the value of _signal for timeNotPressedValue and then conditionally does something else if < timeNotPressedValue which can't be true (which mean that if statement can never be executed)

i don't clearly see these blocks of code in the flow chart.

your flow chart attempts to diagram several functions with jumps between functions. there should be separate charts for each function

even if there's an early exit from a funtion (e.g. return if fast), it would be clearer to show a jump to the end and exit point of the function, instead of back to some calling function

it would help to use the same symbol names in the chart at in the code

not sure a flow-chart can help understand code written this way. Professionally, i've never used flow chart. I have used data flow diagrams, structure charts, various types of state diagrams and timing diagrams

You're in good company. They're often used in datasheets/reference manuals etc.

Frankly, that library you linked to...I have my doubts about that implementation. I generally prefer to solve it using a finite state machine and switch-case logic. Seems more robust and easier to maintain/expand/modify than the plate of spaghetti consisting of nested if's & while's.

Maybe I should have clarified that this is not an example of how anything should be done. It's a flowchart that I did for myself and @alto777, yes, it is completely made it up :slightly_smiling_face:, in the sense that it does not follow any flowchart conventions. It was just a note for myself to try and understand the second part of the function as I was struggling to understand it's logic .

Yes it is true that using the same code terms can be confusing. for example I used the timer instead of bottonTimes as it made more sense to me... As I said... this is something I did purely as an exercise. It did help me to figure out what the code was doing so I thought it could be useful, as an exercise - for someone at my level. But I appreciate that my notes may just confuse other people.
In terms of the code, it is not a code that I have written myself, so I won't be able to answer questions regarding why it has been written in a way and not in another. However, any comments on how efficient it is, better ways to rewrite it to achieve the same or better results in a cleaner way, will certainly help me (and possibly others) in terms of learning.

Thanks. I haven't seen them before. I am looking into it. Is there any program that create flowcharts from C++ code?

my understanding of the code is this:

bool fastClick(bool continuous = true);
bool click();
bool doubleClick();
bool longClick();

that when one of the above functions is called, it will then make us of the verifyButton() function to establish if the button has been clicked, doubleclicked, etc.
for example in the case of continous click it will pass the value true to the continous argument of the functio) therefore if the button is clicked for longer than 200 ms, after debounce it will break out of the loop, will increment the number of clicks by one, then exit the function, at this point the number of click will be > 0, therefore the function will return true (even if the button is still pressed). the cicle will continue, increasing the number of clicks until the button is released.
for the double click function the matter gets a bit more confusing, hence my need to create this flowchart...
I hope I am not causing problems :stuck_out_tongue_winking_eye:

OK, I see.

That is completely fine, and very creative. I am sure it is a useful and meaningful expression of the code you are studying.

Since it does not adhere to any conventional flowchart systems, nor any graphical representation of a process or a system, at least that I have seen, it will be of limited use as a tool for communicating with others.

By analogy, if you made up your own language - words, vocabulary, pronunciation, system of writing and so forth, you could use it for personal benefit, but others would reasonably ask for a dictionary and the equivalents in order to learn that language.

I have some things like that, I bet we all have non-standard ways to think about things. Mine are so crazy I don't even think they could be described sufficiently for a general audience. Your diagram method looks like it might be coherent

TBH I sincerely hoped you were using a well-documented system, as what you shared is intriguing and looks like it might add something to what is conventional.

One thing is inescapable, however. If the code is crap to begin with, no amount of study and no alternate way if looking at it will make any more sense.

a7

In Assembly Language Programming, Flow Chart Programming is also covered where the following seven geometrical symbols (Fig-1) are used.


Figure-1:

:rofl: :rofl:

@GolamMostafa Thanks for that

1 Like

Here's an example from the reference manual of the STM32F030 series microcontroller:
image
Page 540
There's some more in that chapter as well.

I don't know; never looked into it. Sounds like something AI might be able to do - if not now, then soon. Could be one of the many things it's actually useful for.

1 Like

sounds like verify() is a generic button routine, called by the others functions to determine how the button was pressed. seems like a better approach would be to call a generic button press routine that returns the type of press: fast, long, double

wouldn't doubleClick() need to call verify twice to recognize 2 fast presses?

there's still that if case that seems impossible to execute.

1

yes I should have added return here
correction: no the code does not return to the main function here, so I believe the flowchart is correct... In the sense that there is no return statement, although clearly the function has nothing else to execute here

2

I believe this is incorrect, again I accept that calling things differntly from the code is not ideal..but when entering the second while loop the button has already been released, then it sets timeNotPressedValue to 250, and timeNotPressedCount to 0, and it start increasing timeNotPressedCount (while the button is still not pressed). If the button continues to be pressed for longer than 250 then loopclick becomes false.
If the button is pressed again before the count reaches 250 then it reset the timer, then it checks that the buttonis pressed for at least 20 (this is not actually ms but that's another matter), clicks is increased (to 2), at this point there is another if statement that checks that clinck is 2 (a bit redundant I think) and iff this is the case loopclickis set to false and the while statement won't be repeated...
I hope it make sense...
so it does work.
I have asked myself a few questions about this code, one is the timer (including the debounce) does not use milliseconds. insted is a coount which, if I am not wrong is increased at every iteration, so preatty dependent of how long it the iteration takes, plus it add 1ms. as I said above the last if statement is probably redundant (?).

Also clearly trhis code would not be suitable in certain situation as it only detects the button pressed state when the button is actually released...

No, if I understood it correctly it only calls it once; the second while loop (the one incorporating two while loops in it) seems to be taking care of that

It should have a single entry point, not four - Click, zero a timer, wait for release then check the timer for short, medium or long. If Time is between medium and long, then test whether a second Click occurs within another timespan. This will give one of four branches to take.

that's not what i meant. how does the flow chart know that when the return is executed its returning the to the fast-click function?

i see that now. but what happens if the main code calls doubleClick() or fastClick() and a long-click occurred?

i would think the main code would call some button press routine and depending on the type of press, fast, long, double, do different tings

right.
the while loop breaks either when the button is pressed again oor timeNotPresseedCounts exceeds some limit.
the following if executes if the button was released (why not just check if == _signal and will then loop if it's pressed again.

needless to say, the code is difficult to understand. i think it may be simple if it were a state machine that recognizes when a button is pressed, if it is released quickly (i.e. fast) then waits some limited amount of time to see if it's pressed again (i.e. double-click) or it is pressed longer that than the fast-click period (i.e. long-click)

Not sure I understand the question. in the flowchart I put a green arrow to show that it goes back to the calling function

that reassures me a bit, as I thought that generally people would understand the code without needing to do a flowchart...

The function works as expected, so there is no error as such I suppose. Maybe it could have been coded better or more clearly, as you all are saying.
I am sure there will be other library doing this in a different way. I'll have a look (and maybe produce another flowchart that confuses everyone :grin:... )