Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/button control #9

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Conversation

GrzegorzWojnarowicz
Copy link

@GrzegorzWojnarowicz GrzegorzWojnarowicz commented Mar 18, 2022

#2 (comment)

Keep that in mind

add Button class
alternative version of button_pressed method
fix button_pressed method
#pragma once

#include <Arduino.h>
const unsigned long debounce_delay = 75;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From line 4-14: Hide this constants/enums to class because, this values are integrated with the class and should not be accessible for other when include this file

Press output = NOT_PRESSED;
int readState = digitalRead(pinNum);

if (readState == high_button_state && (button_active == false))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For line 34 and 39: Why used high_button_state when you can use just HIGH it's more cleaner

unsigned long time_diff = release_time - press_time < 0 ? 0 : release_time - press_time;
output = time_diff > long_press ? PRESSED_LONG :
((time_diff > medium_press) && (time_diff <= long_press)) ? PRESSED_MEDIUM :
((time_diff > 0) && (time_diff <= medium_press)) ? PRESSED_SHORT : NOT_PRESSED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can split this to if but i don't see too much problem with this if its stay in that form.
But what i would change for sure you can cut this if because if time_diff > long_press is false it's for sure time_diff <= long_press so you don't need to write it in else statement. Same to medium_press.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it looks really complicated and too long.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can create a separate private methods for some if statements, for example: check_long(), check_short(), check_medium() etc.

Copy link
Contributor

@xHeler xHeler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean code

const unsigned long medium_press = 1000;
const unsigned long long_press = 5000;

enum Press {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Press what ? Maybe change to -> PressState or smth give more information

Comment on lines 19 to 23
short pinNum;
unsigned long press_time;
unsigned long release_time;
bool button_active;
unsigned long time_diff;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two different name convention. Ones you use camelCase in the other hand you use snake_case

Comment on lines 25 to 27
Button::~Button()
{
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Button::~Button() {} - in one line looks more sexy


#include <Arduino.h>
const unsigned long debounce_delay = 75;
const int high_button_state = HIGH;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary use just HIGH

PRESSED_LONG = 3
};

class Button
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the public things just under class name.
It is easier to read and use then the public methods are just under the class name.

const unsigned long medium_press = 1000;
const unsigned long long_press = 5000;

enum Press {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add unknown state :D

you can also use enum class

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the values of enum are in sequence you don't have to assign the value.

class Button
{
private:
short pinNum;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • There are two types of the cases. pinNum and press_time . Chose one and implement to others :D camelCase or snake_case

  • Use explicite types of ints. https://en.cppreference.com/w/cpp/types/integer . The pinNum can be uint8_t - unsigned int 8 bit. 0 - 255.

unsigned long time_diff = release_time - press_time < 0 ? 0 : release_time - press_time;
output = time_diff > long_press ? PRESSED_LONG :
((time_diff > medium_press) && (time_diff <= long_press)) ? PRESSED_MEDIUM :
((time_diff > 0) && (time_diff <= medium_press)) ? PRESSED_SHORT : NOT_PRESSED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it looks really complicated and too long.

unsigned long time_diff;
public:
Button(int buttonNum);
~Button();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the destructor is empty just don't use it ;)

unsigned long time_diff = release_time - press_time < 0 ? 0 : release_time - press_time;
output = time_diff > long_press ? PRESSED_LONG :
((time_diff > medium_press) && (time_diff <= long_press)) ? PRESSED_MEDIUM :
((time_diff > 0) && (time_diff <= medium_press)) ? PRESSED_SHORT : NOT_PRESSED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can create a separate private methods for some if statements, for example: check_long(), check_short(), check_medium() etc.

change pressed_button method from millis to interrupts

change from class Button to namespace ns_button
Copy link
Contributor

@Selvan66 Selvan66 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked the solution in the class more than in the namespace, but if others think it might stay that way, I have no problem with that.

Just write some example program to use this code.

@GrzegorzWojnarowicz
Copy link
Author

It is in namespace now just because interrupts had problems with classes. The problem is that when interrupt happens it calls a function (in my class it was a method, and it wouldn't know which instance of this method to call). I've seen that someone told that it may be done by static methods and address them using switch case, but he said that it's not a perfect solution.

const unsigned long medium_press = 1000;
const unsigned long long_press = 5000;

enum Button_state {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not put them all and create button class ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we need static functions as callbacks to the interrupts.
I think that the buttons have to be something static.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at it and it turns out that you can use lambda expressions in attachInterrupt(), you only need to attach the library #include <FunctionalInterrupt.h> from esp

@xHeler
Copy link
Contributor

xHeler commented Mar 26, 2022

I'd like to have examples directory with simple example of usage your buttons.
And please create README.md with information about library.

Copy link
Contributor

@delipl delipl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this pattern to function with argument. Please split this to .hpp and .cpp

if (press_time[i] != 0)
        {
            if ((millis() - press_time[i]) > debounce_delay)
            {
                release_time[i] = millis();
            }
        }else{
            if ((millis() - release_time[i]) > debounce_delay)
            {
                press_time[i] = millis();
            }
        }
    ```

change button_pressed function into set_current_state

add get_current_state function

use as state-machine using get_current_state function
add README file with class description and usage example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants