Edited at

Python+RaspberryPiで2つのLEDを非同期で点滅

LED1を1秒ごと、LED2を1.2秒ごとに点滅したい。


方法1 自前でカウンタ

import time

import wiringpi as w
count = 0
w.wiringPiSetup()
w.pinMode(0,1)
w.pinMode(1,1)

while 1:
count = count + 1
if ( 0 == ( count % 20 ) ):
w.digitalWrite(0,1)
if ( 0 == ( count % 24 ) ):
w.digitalWrite(0,0)
if ( 0 == ( count % 20 ) ):
w.digitalWrite(1,1)
if ( 0 == ( count % 24 ) ):
w.digitalWrite(1,0)
time.sleep(0.1)


方法2 マルチスレッド

import threading

import time
import wiringpi as w
led1Stat=0
led2Stat=0
w.wiringPiSetup()
w.pinMode(0,1)
w.pinMode(1,1)

def LED1():
global led1Stat
if (0 == led1Stat):
led1Stat = 1
else :
led1Stat = 0
w.digitalWrite(0,led1Stat)
t=threading.Timer(1,LED1)
t.start()
def LED2():
global led2Stat
if (0 == led2Stat):
led2Stat = 1
else :
led2Stat = 0
w.digitalWrite(0,led2Stat)
t=threading.Timer(1.2,LED2)
t.start()

t1=threading.Thread(target=LED1)
t2=threading.Thread(target=LED2)
t1.start()
t2.start()


方法3 OSのタイマーシグナルを利用する

OSからのシグナルなので少し違うが、マイコンのタイマー割り込みみたいに考えることができ。

@miminashi さんが 「Python3で一定間隔で処理を行う」として、 signal.setitimer を使う方法を紹介している

https://qiita.com/miminashi/items/50a4f0906ab8f18b105d

しかしながら複数のシグナルをセットする方法がわからなかったので、断念!


方法4 Tornado ライブラリを使う

TornadoはPythonで書かれた非同期通信フレームワーク。Webサーバなどに使うことができる。

ここを参考に

https://stackoverflow.com/questions/14186925/tornado-on-raspberry-pi-to-use-websockets-as-well-as-monitor-serial-port-arduino

import datetime

import wiringpi as w

from tornado import gen, options
from tornado.ioloop import IOLoop
from tornado.locks import Condition

condition = Condition()
led1Stat=0
led2Stat=0
w.wiringPiSetup()
w.pinMode(0,1)
w.pinMode(1,1)

@gen.coroutine
def LED1():
global led1Stat
while 1:
yield condition.wait(timeout=datetime.timedelta(seconds=1))
if (0 == led1Stat):
led1Stat = 1
else :
led1Stat = 0
w.digitalWrite(0,led1Stat)
# print("1",led1Stat)

@gen.coroutine
def LED2():
global led2Stat
while 1:
yield condition.wait(timeout=datetime.timedelta(seconds=1.2))
if (0 == led2Stat):
led2Stat = 1
else :
led2Stat = 0
w.digitalWrite(0,led2Stat)
# print("2",led2Stat)

@gen.coroutine
def runner():
yield [LED1(), LED2()]

options.parse_command_line()
IOLoop.current().run_sync(runner)