2017-01-10 47 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