2016-12-12 23 views
0

我正在研究從風速計讀取數據的Arduino程序,如果風速高於某個閾值,它將激活一個繼電器。所述閾值可以通過兩種方式來設置:解決Arduino用戶輸入的邏輯問題

1)用戶可以使用兩個按鈕來增加或減小閾值

2)如果某一個按鈕被保持2秒鐘,該閾值將與當前同步風速。

我的問題是:增加和減少按鈕更改閾值+/- 0.5 km/h。但風速以0.1 km/h的精度讀取。所以有時會發生的情況是,如果當前的風速是12.2公里/小時,並且同步按鈕被保持,那麼現在的閾值變爲12.2公里/小時。沒問題...

但是,如果用戶按下其中一個增加/減少按鈕,閾值仍會改變+/- 0.5 km/h,這意味着數值將會增加,如12.2,12.7,13.2,13.7等

我想要發生的是增加/減少按鈕將閾值,以精確到0.5倍。因此,如果使用同步按鈕,並且閾值設置爲12.2,則按增加按鈕將變爲12.5,然後從那裏繼續以0.5爲步長。

我可以想出一些方法來解決這個問題,但沒有一個是非常優雅的。我想盡可能使用最簡單的解決方案。

注:我不包括我的任何代碼,因爲這更多的是邏輯/僞代碼問題。另外,這是我的第一篇論壇帖子,所以讓我知道是否需要更改我的文章中的任何內容!

編輯:僞,按要求。

if increase button pressed 

    threshold+=0.5 

if decrease button pressed 

    threshold-=0.5 

if sync button held 

    threshold = current wind speed 
+0

聽起來像是你有3個按鈕: 「兩個按鈕來增加或減少」 和 「同步」 按鈕。那是對的嗎? – chux

+0

即使發佈僞代碼也會幫助解釋問題以及當前使用的方法。例如:當按下「同步按鈕」並導致_threshold == current_時,隨後的但是微小的改變打開並關閉繼電器,可能很多次。看起來是一個有點遲滯的好地方。 – chux

+0

我將僞添加到我的文章。是的,有3個按鈕。 – user7287356

回答

0
Handle_key_press_down(key, &threshold) { 
    min_step = 0.5 
    Hysteresis = min_step*0.6 // Avoid threshold that is exactly same as the current speed 
    New_threshold = round_to_nearest(threshold, min_step) 
    If (key == up) { 
    New_thresh = Threshold + min_step 
    Else if (key == down) { 
    New_thresh = Threshold - min_step 
    Else if (key == sync) { 
     Wait_for_release 
     If release_time >= 2.0s 
     New_thresh = round_to_nearest(Get_current() + Hysteresis, min_step) 
     Else 
     ignore 
    Endif 
    // Insure, no matter what, threshold is within design limits. 
    If (New_thresh > threshold_max) New_thresh = threshold_max 
    If (New_thresh < threshold_min) New_thresh = threshold_min 
    return New_thresh 
} 
0

複雜的C++的Arduino(GRIN)溶液

#include <math.h> 

// button == 1 increase, button == 0 decrease 
void adjust(float& level, char button) { 
    float floorVal2=floor(level*2); // level*2 is equiv to level/0.5 
    if(fabs(floorVal2-2*level)<1e-5) { 
    // they aren't close enough to consider them equal 
    level= 
     button 
     ? (floorVal2+1)/2 // this is equiv to ceil(level/0.5)*0.5 
     : floorVal2/2 // this is floor(level/0.5)*0.5 
    ; 
    } 
    else { 
    level += (button ? 0.5 -0.5) 
    } 
} 

void read(float& level) { 
    level=MySensor::getCurrentValue(); 
}