CSVで指定した時間に動作を実行するPythonプログラム

こちらで構想したように、 NintendoSwitchのコントローラーをハックして操作できるようにしたい。
そのためには、指定時間に、コントローラーに対応するGPIOを切り替える動作を行う必要がある。
そこで今回、表題の通り、CSVで指定した時間に動作を実行するPythonプログラムを作成した。

・CSVファイルについて

下画像のように、時間とGPIOの値を指定するCSVファイルをExcelから1クリックで作成するマクロを組んだ。
[A8]から[W空白]までの範囲をCSV形式で保存する。
例えば、1.5秒経過後に[↑]ボタンを押したければ、[B18]を1にすれば良い。
Excelファイルの保存先はこちら

・Pythonプログラムについて

CSVファイルのA列に動作させたい時間を、B~W列にGPIOの動作を記載している。
今回はプログラム開始時刻から、A列の指定時間経過時刻にB~W列をprintするプログラムを作成した。
動作環境はRaspberryPiのThonny。CSVファイルは「/home/pi/Desktop/」に「Test_ctrl.csv」として保存。
Pythonファイルの保存先はこちら

import time
import datetime
import sched
import RPi.GPIO as GPIO
import csv

“スケジューラ設定”
s = sched.scheduler(time.time, time.sleep)

“csvファイル読み込み”
csv_file = open(r”/home/pi/Desktop/Test_ctrl.csv”,”r”)
f = csv.reader(csv_file, delimiter=”,”, doublequote=True,
lineterminator=”\r\n”, quotechar='”‘, skipinitialspace=True)

_now = datetime.datetime.now()
print(‘PrgStart:’,_now) #プログラム開始時刻
print(‘===ProgramStart========================’)

“実行プロセス”
def processing(AO_1,AO_2,AO_3,AO_4,
      AO_5,AO_6,AO_7,AO_8,
      AO_9,AO_10,AO_11,AO_12,
      AO_13,AO_14,AO_15,AO_16,
      AO_17,AO_18,AO_19,AO_20,
      AO_21,AO_22):
  _act_start =datetime.datetime.now()
  print(‘ActStart:’,_act_start) #実行開始時刻
  ”ここに実行プログラムを記載=============================”
  print(AO_1,AO_2,AO_3,AO_4,
    AO_5,AO_6,AO_7,AO_8,
    AO_9,AO_10,AO_11,AO_12,
    AO_13,AO_14,AO_15,AO_16,
    AO_17,AO_18,AO_19,AO_20,
    AO_21,AO_22)
  ”====================================================”
  _act_end =datetime.datetime.now()
  print(‘ActEnd :’,_act_end) #実行完了時刻
  print(‘————————————‘)

“csvを1行ずつ取り込み動作実行”
for row in f:
  print(row) #rowはList row[**]で必要な項目を取得
  elps_time = float(row[0]) #経過時間
  _act_time =_now + datetime.timedelta(seconds= elps_time)
  print(‘ActTime :’,_act_time) #実行したい時刻
  _act_us = _act_time.microsecond
  _utc_time = float(time.mktime(_act_time.timetuple())) + (_act_us * 0.000001)

  #指定時刻にプロセスを実行
  s.enterabs(_utc_time, 1, processing, argument=(
      int(row[1]),int(row[2]),int(row[3]),int(row[4]),
      int(row[5]),int(row[6]),int(row[7]),int(row[8]),
      int(row[9]),int(row[10]),int(row[11]),int(row[12]),
      int(row[13]),int(row[14]),int(row[15]),int(row[16]),
      int(row[17]),int(row[18]),int(row[19]),int(row[20]),
      int(row[21]),int(row[22]),))
  s.run()

・実行結果

0.05秒ごとの動作ではほぼ遅延無し。(ただし、0.01秒では遅延が徐々に大きくなった。また、実際にGPIOのON/OFF動作を行うと遅延が大きくなる可能性はある。)
低周期での動作ではほぼ遅延を無視できるので、動作させたいタイミングのみCSVに記入する形をとれば問題ないと考える。

Python 3.7.3 (/usr/bin/python3)
               %Run python_timeschedule_test190911.py         
 PrgStart: 2019-09-11 20:48:39.629454
 ===ProgramStart========================
 ['1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:40.629454
 ActStart: 2019-09-11 20:48:40.630642
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:40.642231
 
 ['1.05', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:40.679454
 ActStart: 2019-09-11 20:48:40.679674
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:40.690647
 
 ['1.1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:40.729454
 ActStart: 2019-09-11 20:48:40.729658
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:40.741150
 
 ・
 ・
 ・
 略
 ・
 ・
 ・
 ['4.85', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:44.479454
 ActStart: 2019-09-11 20:48:44.664123
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:44.689259
 
 ['4.9', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:44.529454
 ActStart: 2019-09-11 20:48:44.692964
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:44.704072
 
 ['4.95', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:44.579454
 ActStart: 2019-09-11 20:48:44.816997
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:44.823212
 
 ['5', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2048', '2048', '2048', '2048']
 ActTime : 2019-09-11 20:48:44.629454
 ActStart: 2019-09-11 20:48:44.830685
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2048 2048 2048 2048
 ActEnd  : 2019-09-11 20:48:44.836790
 

・RaspberryPi画面(VNCリモートデスクトップ使用)

これが使えるようになれば、LEDイルミネーションとかロボットとかも自由に動かすことができます。

次回以降はGPIOも実際に使ってみたいですね。
あとexe化も。