基本動作例3: EPICS-ArduinoによるLチカ (ON/OFF) 制御¶
検証目標¶
ハードウェア(Arduino)の出力状態を遠隔制御する検証.
前提条件¶
IOCは "RaspberryPi" 、OPIは手元PCのmacOS、制御機器は "Arduino Uno" .
Arduino-RaspberryPi間はUSB接続、RaspberryPi-mac間はLANケーブルで接続する.
Arduinoの2番端子-GND端子間に 1KΩ抵抗x2個、LEDを直列に接続する.2番端子の出力によってLEDを点灯させる.
制御モジュールとして、 "StremDevice" を使用し、その他、 asyn , "pyEpics" を適宜使用する.
作業ディレクトリ: ${HOME}/epics/app/lightupLED/ ( ${HOME}=/home/epics/ )
Arduinoプログラム1:(Lチカ:ON/OFF制御)の転送¶
シリアル制御(USB)から、ASCII文字を受け取り、文字に応じて以下の動作をする. + 文字が "H" ( ASCII:72 (10進数) ) であった場合LEDを 点灯 させる. + 文字が "L" ( ASCII:76 (10進数) ) であった場合LEDを 消灯 させる.
Arduino プログラムは以下である.
下記プログラムは、Arduino IDE を使用してArduinoへ転送しておく.(手元PCからでも勿論、可)
// program to control LED's luminocity by PWM.
// parameters
int pin_LED = 2;
int powerFactor = 0.0;
int serial_bps = 19200;
int ASCII_H = 72;
int ASCII_L = 76;
void setup() {
// put your setup code here, to run once:
pinMode( pin_LED, OUTPUT );
Serial.begin( serial_bps );
}
void loop() {
// put your main code here, to run repeatedly:
if ( Serial.available() > 0){
char cRecv = Serial.read();
if ( cRecv == ASCII_H ){
digitalWrite( pin_LED, HIGH );
}
else if ( cRecv == ASCII_L ){
digitalWrite( pin_LED, LOW );
}
}
}
pythonからの制御テストコードは以下である.
# -*- coding: utf-8 -*-
import serial
com_num = "/dev/cu.usbmodem142201"
baud_rate = 19200
def main():
ser = serial.Serial( com_num, baud_rate, timeout=1)
while True:
print( " input control command, ( 'H':on, 'L':off, 'E':quit ) >>>", end="" )
str_cmd = input()
byte_cmd = bytes( str_cmd, encoding="ascii" )
if ( str_cmd == "E" ): break
ser.write( byte_cmd )
ser.close()
if __name__ == '__main__':
main()
IOC構築¶
IOC構築 / テスト の手順¶
アプリ名は、参考URL(下記)に従い、lightupLEDとする.
また、.dbやレコード名などは、全てlightupLEDへ統一する.
IOC-App 構築の手順は、以下である.
ベースアプリ の作成.
configure/RELEASE に共有するモジュールのインストールパスを追記.
"lightupLEDApp" 内の データベース情報、及び、コンパイル用のMakefileへ追記する.
StreamDevice 用の プロトコル を、 protocols/lightupLED.proto として作成する.
IOC初期化スクリプト( iocBoot/ioclightupLED/st.cmd ) を編集し、実行可能とする.
make 、及び、st.cmdの実行、camonitorにより、経時変化を観察する.
以下、上記手順について詳述する.
1. ベースアプリの作成¶
makeBaseApp.plを用いたベースアプリの作成
$ mkdir -p ~/epics/app/lightupLED $ cd ~/epics/app/lightupLED $ makeBaseApp.pl -t ioc lightupLED $ makeBaseApp.pl -i -t ioc lightupLED
2. 共通コンパイル設定事項の編集 ( configure/RELEASE )¶
configure/RELEASEに、共通のコンパイル設定(モジュールの場所等、)を例えば以下のように記載する.
ASYN = /home/epics/epics/support/asyn STREAM = /home/epics/epics/support/StreamDevice
3. データベースファイルとコンパイルの準備¶
データベース及び使用するモジュールの情報を記載し、${HOME}/epics/app/lightupLED/lightupLEDApp/Db/lightupLED.dbを作成する.
record( stringout, "epics:lightupLED" ) { field( DESC, "var to light up LEDs" ) field( DTYP, "stream" ) field( OUT , "@lightupLED.proto putval PS1" ) }
データベースのコンパイル対象として、上記の"lightupLED.db"を追加.
@ lightupLEDApp/Db/Makefile DB += lightupLED.db
その他モジュールを利用する場合は、IOCの通信コードのコンパイルに使用するモジュール情報を、 "lightupLEDApp/src/Makefile" に記載し、コンパイルできるようにする.
@ lightupLEDApp/src/Makefile lightupLED_DBD += stream.dbd lightupLED_DBD += asyn.dbd lightupLED_DBD += drvAsynSerialPort.dbd lightupLED_LIBS += stream lightupLED_LIBS += asyn
4. StreamDeviceの設定ファイル ( "protocol" )の作成¶
ディレクトリ "protocols"を作成し、StreamDeviceの入出力情報を記載する.
$ mkdir $HOME/epics/app/lightupLED/protocols
Terminator = CR LF; putval{ out "%s"; }
5. IOC 初期化スクリプト "st.cmd" の編集¶
IOC初期化スクリプト ( iocBoot/ioclightupLED/st.cmd ) に、以下の情報を記載する.
#!../../bin/linux-arm/lightupLED #- You may have to change lightupLED to something else #- everywhere it appears in this file < envPaths # -- n.k. -- # epicsEnvSet("STREAM_PROTOCOL_PATH", ".:../../protocols") cd "${TOP}" ## Register all support components dbLoadDatabase "dbd/lightupLED.dbd" lightupLED_registerRecordDeviceDriver pdbbase ## Load record instances #dbLoadRecords("db/xxx.db","user=epics") # -- n.k. -- # dbLoadRecords( "db/lightupLED.db" ) drvAsynSerialPortConfigure ("PS1","/dev/ttyACM0") asynSetOption( "PS1", 0, "baud", "19200" ) cd "${TOP}/iocBoot/${IOC}" iocInit ## Start any sequence programs #seq sncxxx,"user=epics"
Warning
(隘路事項) dbLoadRecord, dbLoadDatabaseの順番が逆になったりすると、うまく動作しない.しかも、".db"ファイルの1行目がおかしいというエラーメッセージがでるので、ミスリーディングである.st.cmd前後の状態も確認すべきである.
スクリプトに実行権限を与えておく.
$ chmod u+x $HOME/epics/app/lightupLED/iocBoot/ioclightupLED/st.cmd
6. make 及び、初期化スクリプト "st.cmd" の実行¶
ベースディレクトリにて make する.
$ cd $HOME/epics/app/lightupLED/ $ make distclean $ make
初期化スクリプトを実行する.
$ cd $HOME/epics/app/lightupLED/iocBoot/ioclightupLED/ $ sudo ./st.cmd
ADCの動作状況の確認¶
ローカルからのcamonitor¶
別コンソールを立ち上げて、以下コマンドを実行
epics@raspberrypi: ~ $ caput epics:lightupLED "H" ( H も可 )
OPI(手元macOS)からのCA¶
pyEpicsからCA.
$ python3 >>> import epics >>> epics.caput( "epics:lightupLED", "H" )
OPIからIOCを介して、 "Lチカ" を実施することができた.
参考URL¶
Arduino-EPICS サンプル ( KEK-EPICS Users JP, https://cerldev.kek.jp/trac/EpicsUsersJP/wiki/epics/arduino/simpleRead )
Github:inigoalonso/setup-epics-serial-arduino ( arduino-EPICS https://gist.github.com/inigoalonso/99d9076c672661a4b821 )
StreamDevice -protocol Files- ( https://paulscherrerinstitute.github.io/StreamDevice/protocol.html )