2

最新のRasbian Wheezyディストリビューションを実行しているRaspberry Pi B+でOWN (Open Weather Network )を使用してスクロール天気フィードをセットアップしようとしていますが、 Python LIRC (Linux Infrared Remote Control)を使用して IR サポートを追加するのに問題があります。

私がやろうとしていること: 気象変数には、状態、温度、湿度、風速の4 つがあります。それらは私の 16x2 LCD 画面に表示され、タイトルが一番上の行に、値が 2 番目の行に表示されます。それらは次の画面に置き換わる前に 5 秒間画面に表示されます。最後に到達すると、再びループします。180 回 (約 1 時間) ループした後、天気を更新します。IR リモコンのボタン 1 ~ 4 を使用して特定のタイルにジャンプし、そのループに戻りたいと考えています。

動作:ボタンが押されていない場合、 LIRCがブロック されている場合のように空のキューをスキップするのではなく、 lirc.nextcode()でハングし、ボタンが押されるのを待って、 KeyboardInterruptで終了します。

IRを追加するまで、すべてがうまくいきました。これで、最初の天気変数が表示され、次の変数を取得しようとすると、IR コードがキューにない場合にスキップして次のタイルに移動する代わりに、lirc.nextcode()は IR コードを受信するまでコードを停止します。これは、 LIRCブロッキングがオフになっていると発生しないはずです。

私はすべての最新バージョン ( Python LIRC 1.2.1 ) を持っています。以前のバージョンのPython LIRCには、ブロッキング パラメーターにバグがあったことを知っています。私は 2 日間かけてあらゆる可能なことを調査し、試しました。これは私が見つけた1つの可能な回避策ですが、これは同じ問題の影響を受けています: Python LIRCブロッキングシグナルの回避策が機能していません

コードの多くが不適切であることはわかっています。つまり、グローバル変数、関数内に必要なもの、3 時間ごとの OWN 更新、および 1 時間ごとの更新ですが、これは機能させるための一時的なものです。後で整理してオブジェクト指向にします。これにより一部の人が読みにくくなる場合は、事前に申し訳ありません.

import pyowm
from sys import exit
import time
import RPi.GPIO as GPIO
from RPLCD import CharLCD, cleared, cursor
import lirc

# initialize lirc and turn of blocking
sockid = lirc.init("weather", blocking=False)
lirc.set_blocking(False, sockid)

# initialize weather network
owm = pyowm.OWM('API #')

# initialize LCD
lcd = CharLCD(pin_rs=26, pin_rw=None, pin_e=24, pins_data=[22, 18, 16, 12],
                  cols=16, rows=2)

# weather data
w = None # wind m/s
wind = None # wind km/h
windkm = None
humidity = None
temper = None
COUNTER = 0 #number of cycles before update

NEXT = 1

# switches to next tile
def next_tile():
    global NEXT

ここに問題があります。Lirc.nextcode()は、 LIRCキューから次の IR コードを取得し、リストとしてcodeIRに追加する必要がありますが、ボタンが押されておらず、ブロックがオフになっている場合は、コードをスキップする必要があります。代わりに、ブロッキングがオンであるかのように動作し、ボタンが押されるまでハングします。それでもメインループを続行しません。NEXTを出力するだけで、I KeyboardInterruptが終了するまでハングします。

    codeIR = lirc.nextcode() # pulls IR code from LIRC queue.
    # checks if there's a code in codeIR and goes to that tile. If not, it 
    # goes to the next tile instead.
    if not codeIR: 
        if NEXT != 4: # if it's the last tile, cycle to the first 
            NEXT += 1
            print NEXT
            return NEXT
        else: # if not last tile, go to next
            NEXT -= 3
            print NEXT
            return NEXT
    else:
        NEXT = codeIR[0]
        print NEXT
        return NEXT

残りのコードを追加しました。すべて正常に動作しますが、私が達成しようとしていることを理解するのに役立つと確信しています。

while True:
    try:
        if COUNTER == 0:
            COUNTER = 180

            # Search for current weather in London (UK)
            observation = owm.weather_at_place('City, State')
            w = observation.get_weather()

            # Weather details
            wind = w.get_wind()                  # {'speed': 4.6, 'deg': 330}
            windkm = (wind['speed'] * 3600) / 1000 #convet to km/h
            humidity = w.get_humidity() 
            # {'temp_max': 10.5, 'temp': 9.7, 'temp_min': 9.0}
            temper = w.get_temperature('celsius')  
        else:
            while NEXT == 1:
                # prints condition to lcd
                lcd.cursor_pos = (0, 4) #adjust cursor position
                lcd.write_string('Weather') # write to lcd
                lcd.cursor_pos = (1, 5) # adjust cursor position
                lcd.write_string(w.get_status()) # write to lcd
                time.sleep(5) # leave on lcd for 5 seconds
                lcd.clear() # clear lcd
                next_tile() # switches to next tile

            while NEXT == 2:
                # prints temp to lcd
                lcd.cursor_pos = (0, 2)
                lcd.write_string('Temperature')
                lcd.cursor_pos = (1, 6)
                lcd.write_string(str(temper['temp']))
                lcd.write_string(' C')
                time.sleep(5)
                lcd.clear()
                next_tile()

            while NEXT == 3:
                # prints temp to lcd
                lcd.cursor_pos = (0, 4)
                lcd.write_string('Humidity')
                lcd.cursor_pos = (1, 6)
                lcd.write_string(str(humidity))
                lcd.write_string(' %')
                time.sleep(5)
                lcd.clear()
                next_tile()

            while NEXT == 4:
                # prints wind speed to lcd
                lcd.cursor_pos = (0, 3)
                lcd.write_string('Wind Speed')
                lcd.cursor_pos = (1, 6)
                lcd.write_string(str(int(windkm)))
                lcd.write_string('km')
                time.sleep(5)
                lcd.clear()
                COUNTER -= 1
                codeIR = lirc.nextcode()
                next_tile()

    # quit with ctrl+C
    except(KeyboardInterrupt, SystemExit):
        print 'quitting'
        lcd.close(clear=True)
        lirc.deinit()
        exit()

KeyboardInterruptアウトすると、Traceback常にlirc.nextcode()につながります。エラーを投稿しますが、コードを少し変更したところ、lirc.nextcode()を含む関数までしかトレースされません。

私はこれを解決するために 2 日間を費やしましたが、髪をほとんど引き抜いているので、皆さんが私に与えることができる解決策または回避策を講じます. 事前に感謝します。私が見つけることができる助けに本当に感謝します。Signal Module AlarmExceptionを使用して回避策を見つけましたが、raw_input() から lirc.nextcode() に切り替えると、同じようにハングし (raw_input() にタイマーを置いても問題ありません)、アラームが機能しなくなります。右。リンクは次のとおりです。Python LIRCブロッキングシグナルの回避策が機能していません

4

1 に答える 1