关闭所有功能的按钮

发布于 2025-01-23 04:30:36 字数 1703 浏览 4 评论 0原文

我是编码和嵌入式系统的新手,我想制作一个按钮,可以关闭LED,同时关闭系统中所有其他未来。

到目前为止,我已经关闭了按钮,但我似乎也无法更新电位器。由于某种原因,代码会检查按钮是否按下,如果是这样,则LED将打开,然后检查LED是否打开,如果是这样,则打开其他LED,但是当我更改电位计的值时(应切换到其他LED)不会更新并保持在同一LED上。因此,我的问题是,我该如何将另一个IF语句置于段循环中不断更新?

我想在第一个LED时要继续更新的代码是“否则代码” 希望这是有道理的。 :)

笔记: 我不知道我的方法是正确的,因为我正在查看LED而不是按钮自我,因为我的代码检查LED是否打开,而不是按下按钮。

(顺便说一句,它不是一个会使我的生活变得更轻松的开关:()

#include "mbed.h"

DigitalIn userButton (PC_10);
DigitalOut led (PC_0);

bool buttonDown = false;
BusOut leds_bus (PC_1, PB_0, PA_4);

AnalogIn pot1 (PA_5);
void init_leds ();

int cntl_val = 0;

int main ()
{
    cntl_val = pot1.read_u16 () / 32768;
    while (true)
    {
        // run forever
        if (userButton.read () == true)
        {
            // button is pressed
            if (!buttonDown)
            {           
                // a new button press
                led = !led; // toogle LED
                buttonDown = true;  // record that the button is now down so we don't count one press lots of times
                ThisThread::sleep_for (100);
            }
            else if (led.read () == true)
            {
                if (cntl_val < 1 / 3)
                {
                  leds_bus.write (4);
                }
                
                if (cntl_val > (1 / 3) && cntl_val < (2 / 3))
                {
                  leds_bus.write (2);
                }
                
                if (cntl_val > (2 / 3))
                {
                  leds_bus.write (1);
                }
            }
        }
        else
        {           
            // button isn't pressed
            buttonDown = false;
        }
    }
}    

I am new to coding and embedded systems and I wanted to make a button that turns off and on a LED and at the same time turn off all other futures in the system.

So far I had the button turn off and on but I cant seem to get it to also update the Potentiometer. For some reason the code would check if the button is pressed and if so then the LED would turn on and then check if the LED is on and if so then turn on the other LEDs but when I change the value of the Potentiometer( which should switch to other LEDs) it would not update and stay on the same LED. So my question is how can I put another if statement that would keep updating in the while loop?

the code that I wanted to keep updating while the first LED is on is the "else if code"
Hope that made sense.
:)

note:
I don't know if my approach is right as I am looking at the LED and not the button it self, as my code checks if the LED is on rather then if the button is pressed.

(btw its not a switch which would have made my life a lot easier :( )

#include "mbed.h"

DigitalIn userButton (PC_10);
DigitalOut led (PC_0);

bool buttonDown = false;
BusOut leds_bus (PC_1, PB_0, PA_4);

AnalogIn pot1 (PA_5);
void init_leds ();

int cntl_val = 0;

int main ()
{
    cntl_val = pot1.read_u16 () / 32768;
    while (true)
    {
        // run forever
        if (userButton.read () == true)
        {
            // button is pressed
            if (!buttonDown)
            {           
                // a new button press
                led = !led; // toogle LED
                buttonDown = true;  // record that the button is now down so we don't count one press lots of times
                ThisThread::sleep_for (100);
            }
            else if (led.read () == true)
            {
                if (cntl_val < 1 / 3)
                {
                  leds_bus.write (4);
                }
                
                if (cntl_val > (1 / 3) && cntl_val < (2 / 3))
                {
                  leds_bus.write (2);
                }
                
                if (cntl_val > (2 / 3))
                {
                  leds_bus.write (1);
                }
            }
        }
        else
        {           
            // button isn't pressed
            buttonDown = false;
        }
    }
}    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海风掠过北极光 2025-01-30 04:30:36

您需要修复数学。 int cntl_val是一个整数,因此将其与分数1/3和2/3进行比较不会做您期望的事情。和cntl_val = pot1.read_u16()/32768;可以设置cntl_val仅为0或1。代码>小于32768,然后cntl_val将仅为0。

您可以将cntl_val更改为float,但这可能不是最好的选择。

而是尝试设置cntl_val = pot1.read_u16();(不要除以32768)。然后将cntl_val与(32768/3)和(32768*2/3)进行比较。那仍然很丑陋,但是更好。

You need to fix your math. int cntl_val is an integer so comparing it with the fractions 1/3 and 2/3 is not going to do what you expect. And cntl_val = pot1.read_u16()/32768; can set cntl_val to only 0 or 1. If the max value returned by pot.read_u16() is less than 32768 then cntl_val will only be 0.

You could maybe change cntl_val to a float but that's probably not the best option.

Instead, try setting cntl_val = pot1.read_u16(); (don't divide by 32768). And then compare cntl_val with (32768/3) and (32768*2/3). That's still ugly but better.

悲凉≈ 2025-01-30 04:30:36

从您的描述中不清楚,但我假设您有:

  • 开/关指示灯指示
  • 一个三个领导的级别指示器
  • 一个暂时的动作按钮,用于开/关控制
  • 电位计以控制输入级别。

当系统处于“ ON”状态时,您希望指示电位指示器上的电位计水平?在这种情况下,我建议:

  • 与LED状态确定分开处理按钮输入/调试。
  • 简化级别设置;您有一个0、1或2的级别,您可以通过unsigned Level =(InputLevel * 3) / 32768; < / code>进行计算。然后,您可以在位移位(1&lt;&lt; Level)中使用该级别值来确定要设置的LED。请注意,您的LED级别指示器中的高位设置为高级 - 这需要(4&gt;&gt; level),如果您要增加LED数量,这有点笨拙。在BUSOUT对象中扭转GPIO的顺序更加容易。

其他建议:

  • 范围”的规则,将本地变量,最小必要的范围(您有许多不必要的全球范围。
  • 应用“最小 否则,如果您在循环中进行其他工作,则可以不必要地确定其他工作的速度

。 /未经测试 - 将其视为一般原则的说明 - 它可能需要调试):

#include "mbed.h"

int main ()
{
    static const unsigned DEBOUNCE_MS = 20u ;
    static const unsigned NUMBER_OF_LEVELS = 3u ;

    DigitalIn OnOffButton( PC_10 ) ;
    DigitalOut OnOffLed( PC_0 ) ;
    BusOut LevelIndicator( PA_4, PB_0, PC_1 ) ;
    AnalogIn InputLevel( PA_5 ) ;
    
    bool isOn = false ;
    int previous_button_state = OnOffButton ;
    std::uint64_t button_change_time = 0 ;

    for(;;)
    {
        // If debounce time expired check for button state change
        if( Kernel::get_ms_count() - button_change_time > DEBOUNCE_MS )
        {
            int current_button_state = OnOffButton ;
            
            // If button state changed
            if( current_button_state != previous_button_state )
            {
                // If button-down
                if( current_button_state != 0 )
                {
                    // Toggle isOn
                    isOn = !isOn ;
                }
                
                // Change of state and debounce update
                previous_button_state = current_button_state ;
                button_change_time = Kernel::get_ms_count() ;
            }
        }
        
        // Set the LEDs depending on On/Off state and input level        
        if( isOn )
        {
            OnOffLed = 1 ;
            
            // Set level indicator
            LevelIndicator = 1 << (InputLevel.read_u16() * NUMBER_OF_LEVELS / 32768u)  ;
        }
        else
        {
            // System inactive (Off)
            LevelIndicator = 0 ;
            OnOffLed = 0 ;
        }
    }
}

您还可以考虑将按钮和指示器处理分为单独的功能,以增加凝聚力,最大程度地减少耦合,简化测试并提高可维护性和可理解性。

#include "mbed.h"

void updateIndicators( bool isOn ) ;
bool getOnOffState() ;

int main ()
{  
    for(;;)
    {
        updateIndicators( getOnOffState() ) ;
    }
}

bool getOnOffState()
{
    static const unsigned DEBOUNCE_MS = 20u ;

    static DigitalIn OnOffButton( PC_10 ) ;
    static bool state = false ;
    static int previous_button_state = OnOffButton ;
    static std::uint64_t button_change_time = 0 ;

    // If debounce time expired check for button state change
    if( Kernel::get_ms_count() - button_change_time > DEBOUNCE_MS )
    {
        int current_button_state = OnOffButton ;
        
        // If button state changed
        if( current_button_state != previous_button_state )
        {
            // If button-down
            if( current_button_state != 0 )
            {
                // Toggle isOn
                state = !state ;
            }
            
            // Change of state and debounce update
            previous_button_state = current_button_state ;
            button_change_time = Kernel::get_ms_count() ;
        }
    }
        
    return state ;
}

void updateIndicators( bool isOn )
{
    static const unsigned NUMBER_OF_LEVELS = 3u ;

    static DigitalOut OnOffLed( PC_0 ) ;
    static BusOut LevelIndicator( PA_4, PB_0, PC_1 ) ;
    static AnalogIn InputLevel( PA_5 ) ;

    // Set the LEDs depending on On/Off state and input level        
    if( isOn )
    {
        OnOffLed = 1 ;
        
        // Set level indicator
        LevelIndicator = 1 << (InputLevel.read_u16() * NUMBER_OF_LEVELS / 32768u)  ;
    }
    else
    {
        // System inactive (Off)
        LevelIndicator = 0 ;
        OnOffLed = 0 ;
    }
}

It is not clear from your description, but I am assuming that you have:

  • An on/off indicator LED
  • A three-LED level indicator
  • A momentary action button for on/off control
  • A potentiometer to control the input level.

And that when the system is in the "on" state you wish to indicate the potentiometer level on the level indicator? That being the case, I suggest:

  • Deal with button input/debounce separately from LED state determination.
  • Simplify the level setting; you have a level 0, 1 or 2 which you can calculate by unsigned level = (InputLevel * 3) / 32768 ;. You can then use that level value in a bit-shift (1 << level) to determine the LED to be set. Note that you had the low level set the high bit in your LED level indicator - that would require (4 >> level), which is somewhat clumsy if you were to ever increase the number of LEDs. It is easier to reverse the order of the GPIO in the BusOut object.

Additional advice:

  • Apply the rule of "minimal scope", localising variables to the minimum necessary scope (you have a number of unnecessary globals.
  • In "big-loop" scheduling, avoid thread delays during which useful work might otherwise be done. Your debounce delay unnecessarily determines the rate at which other work can be done in the loop. The advice would be different if you were polling the button and setting the LEDs in separate threads.

For example (not this is coded blind/untested - treat it as illustrative of the general principles - it may need debugging):

#include "mbed.h"

int main ()
{
    static const unsigned DEBOUNCE_MS = 20u ;
    static const unsigned NUMBER_OF_LEVELS = 3u ;

    DigitalIn OnOffButton( PC_10 ) ;
    DigitalOut OnOffLed( PC_0 ) ;
    BusOut LevelIndicator( PA_4, PB_0, PC_1 ) ;
    AnalogIn InputLevel( PA_5 ) ;
    
    bool isOn = false ;
    int previous_button_state = OnOffButton ;
    std::uint64_t button_change_time = 0 ;

    for(;;)
    {
        // If debounce time expired check for button state change
        if( Kernel::get_ms_count() - button_change_time > DEBOUNCE_MS )
        {
            int current_button_state = OnOffButton ;
            
            // If button state changed
            if( current_button_state != previous_button_state )
            {
                // If button-down
                if( current_button_state != 0 )
                {
                    // Toggle isOn
                    isOn = !isOn ;
                }
                
                // Change of state and debounce update
                previous_button_state = current_button_state ;
                button_change_time = Kernel::get_ms_count() ;
            }
        }
        
        // Set the LEDs depending on On/Off state and input level        
        if( isOn )
        {
            OnOffLed = 1 ;
            
            // Set level indicator
            LevelIndicator = 1 << (InputLevel.read_u16() * NUMBER_OF_LEVELS / 32768u)  ;
        }
        else
        {
            // System inactive (Off)
            LevelIndicator = 0 ;
            OnOffLed = 0 ;
        }
    }
}

You might also consider separating out the button and indicator processing into separate functions to increase cohesion, minimise coupling, simplify testing and improve maintainability and comprehensibility.

#include "mbed.h"

void updateIndicators( bool isOn ) ;
bool getOnOffState() ;

int main ()
{  
    for(;;)
    {
        updateIndicators( getOnOffState() ) ;
    }
}

bool getOnOffState()
{
    static const unsigned DEBOUNCE_MS = 20u ;

    static DigitalIn OnOffButton( PC_10 ) ;
    static bool state = false ;
    static int previous_button_state = OnOffButton ;
    static std::uint64_t button_change_time = 0 ;

    // If debounce time expired check for button state change
    if( Kernel::get_ms_count() - button_change_time > DEBOUNCE_MS )
    {
        int current_button_state = OnOffButton ;
        
        // If button state changed
        if( current_button_state != previous_button_state )
        {
            // If button-down
            if( current_button_state != 0 )
            {
                // Toggle isOn
                state = !state ;
            }
            
            // Change of state and debounce update
            previous_button_state = current_button_state ;
            button_change_time = Kernel::get_ms_count() ;
        }
    }
        
    return state ;
}

void updateIndicators( bool isOn )
{
    static const unsigned NUMBER_OF_LEVELS = 3u ;

    static DigitalOut OnOffLed( PC_0 ) ;
    static BusOut LevelIndicator( PA_4, PB_0, PC_1 ) ;
    static AnalogIn InputLevel( PA_5 ) ;

    // Set the LEDs depending on On/Off state and input level        
    if( isOn )
    {
        OnOffLed = 1 ;
        
        // Set level indicator
        LevelIndicator = 1 << (InputLevel.read_u16() * NUMBER_OF_LEVELS / 32768u)  ;
    }
    else
    {
        // System inactive (Off)
        LevelIndicator = 0 ;
        OnOffLed = 0 ;
    }
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文