質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.01%

  • Python 2.7

    1098questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

パルス入力を積算カウントしたい。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 284

k.horigome

score 4

Python2.7

やりたいこと
下記のコードでラズパイ3のGPIO18に入力されたパルス信号を
積算して一定時間毎にCSVに出力したいです。
どのような方法があるかご教示ください。

```コード
import RPi.GPIO as GPIO

PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.IN)

print('start\n')
fp = open("cnt.txt","w")

try:
while True:
value = GPIO.input(PIN)
fp.write( str(value) + '\n' )
except(KeyboardInterrupt):
fp.close()
GPIO.cleanup()
print('end\n')

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

パルス検出について

  • 以前の入力値を保持しておき、現在の入力値と比較しパルスの立上り(または立下り)を検出します。
  • 検出時、積算値をインクリメントします。

ファイル出力について

  • ファイルは追記モードで開いておきます。
  • 前回の出力時刻を保持しておき、現在時刻と比較して指定時間が経過したら出力するようにします。

以下、概念コードです。

import time

# 略。GPIOの初期化など
#fp = open("cnt.txt","a") # 追記モードで開く

VALS = (GPIO_HIGH,GPIO_LOW) = (1,0)
prevVal = GPIO_LOW
pulse_cnt = 0

INTERVAL = 10 # ログ出力間隔 [sec]
prevTime = time.time()

try:
    while True:
        # GPIOなどから現在値を取得
        curVal = int(input('input(0or1):'))
        if curVal not in (VALS):
            break

        # パルスの立上り(LOW -> HIGH) を積算する
        if prevVal == GPIO_LOW and curVal == GPIO_HIGH:
            pulse_cnt = pulse_cnt + 1

        prevVal = curVal

        # 一定時間経過したら
        curTime = time.time()
        if (curTime - prevTime) > INTERVAL:

            # 積算したパルス数をログファイルなどに出力
            print('pulse_cnt',pulse_cnt)
            #fp.write( '%d\n' % pulse_cnt)

            prevTime = curTime
            pulse_cnt = 0

        time.sleep(0.1) # CPU負荷低減のため

except(KeyboardInterrupt):
    pass

#fp.close()
# 略。GPIOの後始末など

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/25 19:55 編集

    ご教示いただいたコードを元に下記のようにコードを修正して
    走らせたところ、
    input(0or1):のように入力待ちになり0または1を入力すると
    ('pulse_cnt', 1)とそのタイミングで入力されたパルス数?を返して
    cnt.txtにその値を記録しているようです。
    pi@raspberrypi:~ $ sudo python cnt.py
    input(0or1):1
    ('pulse_cnt', 1)
    input(0or1):1
    ('pulse_cnt', 0)
    input(0or1):21
    pi@raspberrypi:~ $

    積算できていないのですが、GPIOの設定や現在値取得に
    不備があるのでしょうか?
    ご教示いただくようお願いします。

    (コードをコピペしたらインデントが反映されませんでした。
     見にくくて申し訳ありません)
    以下、修正したログ----------------------------------------------------
    import time
    import RPi.GPIO as GPIO

    PIN = 18
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PIN, GPIO.IN)

    fp = open("cnt.txt","a")

    VALS = (GPIO_HIGH,GPIO_LOW) = (1,0)
    prevVal = GPIO_LOW
    pulse_cnt = 0

    INTERVAL = 1
    prevTime = time.time()

    try:
    while True:
    value = GPIO.input(PIN)

    curVal = int(input('input(0or1):'))
    if curVal not in (VALS):
    break

    if prevVal == GPIO_LOW and curVal == GPIO_HIGH:
    pulse_cnt = pulse_cnt + 1

    prevVal = curVal

    curTime = time.time()
    if (curTime - prevTime) > INTERVAL:

    print('pulse_cnt',pulse_cnt)
    fp.write( '%d\n' % pulse_cnt)


    prevTime = curTime
    pulse_cnt = 0

    time.sleep(0.1)


    except(KeyboardInterrupt):
    pass

    fp.close()
    GPIO.cleanup()
    print('end\n')

    ここまで------------------------------------------------------------------

    キャンセル

  • 2018/01/25 20:12

    私が回答に記載したのは処理の流れを理解するために作成した概念コードです。
    GPIOからの入力の代わりに手入力で動作するようにしています。

    まずは回答コードをそのまま動かしてみてください。
    0または1を入力していくと、10秒間隔でパルス数が表示されます。
    いろいろ動かしてみて、動作を理解されたうえで、ご自身のコードに組み込んでください。

    キャンセル

  • 2018/01/26 00:41 編集

    ご教示ありがとうございます。
    まず動作が理解できるよう頑張ります。

    キャンセル

  • 2018/01/28 19:02 編集

    下記のコードで10秒間隔でGPIO18からのパルス数をカウントすることが
    できました。動作の理解はまだ不十分ですがさらに学習していきます。
    ご教示ありがとうございました。

    # -*- encoding:utf-8 -*-

    import time
    import RPi.GPIO as GPIO



    PIN = 18

    GPIO.setmode(GPIO.BCM)

    GPIO.setup(PIN, GPIO.IN)



    fp = open("cnt.txt","a")



    VALS = (GPIO_HIGH,GPIO_LOW) = (1,0)

    prevVal = GPIO_LOW

    pulse_cnt = 0



    INTERVAL = 10

    prevTime = time.time()



    try:

    while True:



    curVal = GPIO.input(PIN)

    if curVal not in (VALS):

    break



    if prevVal == GPIO_LOW and curVal == GPIO_HIGH:

    pulse_cnt = pulse_cnt + 1


    prevVal = curVal



    curTime = time.time()

    if (curTime - prevTime) > INTERVAL:



    print('pulse_cnt',pulse_cnt)

    #fp.write( '%d\n' % pulse_cnt)



    prevTime = curTime

    pulse_cnt = 0



    time.sleep(0.1)




    except(KeyboardInterrupt):
    pass

    fp.close()
    GPIO.cleanup()
    print('end\n')

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 2.7

    1098questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。