2017-01-10 48 views
1

我正在使用WiringPi寶石。這個代碼塊按預期工作:無法多次運行方法

pinNumber = 7 
io = WiringPi::GPIO.new do |gpio| 
    gpio.pin_mode(pinNumber, WiringPi::INPUT) 
end 

pin_state = io.digital_read(pinNumber) 
return pin_state 

然而,當我附上這一個方法,所以我可以用Sinatra打電話,我得到以下錯誤,當我嘗試刷新:

wiringPiSetup *:每次程序運行只能調用一次。這是致命錯誤 。請修正您的代碼。

爲什麼這隻能運行一次,什麼是最好的解決方案?每次我導航到根網址時,最終都需要檢索pin_state

下面是完整的代碼:

require 'wiringpi' 
require 'sinatra' 

def getstate() 
    pinNumber = 7 
    io = WiringPi::GPIO.new do |gpio| 
     gpio.pin_mode(pinNumber, WiringPi::INPUT) 
    end  

    pin_state = io.digital_read(pinNumber) 
    return pin_state 
end 

get '/' do 
    getstate() 
end 

回答

1
pinNumber = 7 

def io 
    @io ||= begin 
     WiringPi::GPIO.new do |gpio| 
      gpio.pin_mode(pinNumber, WiringPi::INPUT) 
     end 
    end 
end 

def getstate() 
    pin_state = io.digital_read(pinNumber) 
    return pin_state 
end 

get '/' do 
    getstate() end 

初始化API一旦你的應用程序啓動(外面的getState()方法)時。您正在多次初始化API,因此出現錯誤。

+0

謝謝,但不幸的是當我移動它的一部分代碼的方法之外,我得到「未定義的局部變量或方法'IO」爲#」,當我瀏覽到URL的第一次。 –

+0

@AaronThomas你需要緩存方法外的'io'對象。初始化該對象並將其保存到變量中,然後在'getstate'方法內使用該變量。將'do .. end'塊中的部分移動到'getstate'方法的主體中。 – zetetic

+0

@zetetic我不追隨 - 你能舉一個你想到的例子嗎? –

2

創建您的GPIO實例後,您可以重複調用以從中讀取引腳。但是,您的代碼正在每個呼叫中​​創建一個新實例。

require 'wiringpi' 
require 'sinatra/base' 

class MyApp < Sinatra::Base 
    InputPin = 7 

    IO = WiringPi::GPIO.new do |gpio| 
    gpio.pin_mode(InputPin, WiringPi::INPUT) 
    end  

    def get_state(pin_number = MyApp::InputPin) 
    MyApp::IO.digital_read(pin_number) 
    end 

    get '/' do 
    get_state 
    end 
end 
+0

這證明了Ruby成語的良好用法。常量值InputPin被實現爲....常量! – zetetic

+0

運行這個給我一個404錯誤,即使我把「get_state」替換爲「hello world」。也許還需要其他一些樣板文件? –

+0

@AaronThomas您必須爲模塊化應用程序需要'sinatra/base',而不是用於頂級應用程序的'sinatra'。此外,您可能需要根據範圍調整您訪問'get_state'方法的方式。 Sinatra做了一些讓人困惑的箍跳。如有疑問,請[查看文檔](http://www.sinatrarb.com/intro.html)。 – coreyward