EV3を買いました(レコードプレイヤータイマー)
EV3を買いました。
以下の記事の内容を試す際に注意したほうが良いと思った箇所と、
記事の内容を参考に作成したレコードプレイヤータイマーのプログラムを紹介します。
レコードプレイヤータイマーなんて言っても、
「指定した時間が経過したらレコードプレイヤーの再生ボタンを押してくれる」
というだけですが。
参考にした記事で気をつけた方が良い所
5-2.ソースからのビルド
update_sdcard.shを正常に行うために、make programsの前に以下の修正が必要
("Test"を"SUBDIRS_DISABLED"から"SUBDIRS"へ移動)
*** Makefile.orig 2014-12-27 19:47:56.223963572 +0900 --- Makefile 2014-12-27 19:48:13.560049537 +0900 *************** *** 1,6 **** SUBDIRS = Bluetooth Brick+Datalog Brick+Info Brick+Program IR+Control \ ! Motor+Control Port+View Sleep Volume WiFi ui c_ui ! SUBDIRS_DISABLED = TEST SelfTest tst Debug Demo Test # Make is not friend with spaces, so we have to be creative to handle them. space = $(subst +,\ ,$1) --- 1,6 ---- SUBDIRS = Bluetooth Brick+Datalog Brick+Info Brick+Program IR+Control \ ! Motor+Control Port+View Sleep Volume WiFi ui c_ui Test ! SUBDIRS_DISABLED = TEST SelfTest tst Debug Demo # Make is not friend with spaces, so we have to be creative to handle them. space = $(subst +,\ ,$1)
7.SDカードからの起動
- format_sdcard.shとupdate_sdcard.shはスクリプト内でsudoを使っているので、実行時にsudoは不要
- 特にupdate_sdcard.shは「~/」を使っているのでrootで実行すると問題がある
レコードプレイヤータイマー
ほとんど「9-3 モーター制御」のとおりですが、
指定した時間が経過するとレコードプレイヤーのボタンを押してくれるアプリを作ってみました。
なお、EV3本体の組み立て型は、基本セット同封の組み立て説明書とほとんど同じです。
PortBに左車輪のモーター、PortCに右車輪のモーターが接続されています。
変更点は、前進するとボタンを押してくれるように、カブトムシみたくツノをつけた所だけです。
ソースコード
「.c」と「Makefile」の配置は記事のサンプルと同じで、
それぞれ以下のとおりです。
- move.c
#include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <signal.h> #define CH1 0x01 #define CH2 0x02 #define CH3 0x04 #define CH4 0x08 /* EV3のバイトコードの定義からの抜粋です(from bytecode.h) */ typedef enum { opPROGRAM_STOP = 0x02, // 0010 opPROGRAM_START = 0x03, // 0011 opOUTPUT_GET_TYPE = 0xA0, // 00000 opOUTPUT_SET_TYPE = 0xA1, // 00001 opOUTPUT_RESET = 0xA2, // 00010 opOUTPUT_STOP = 0xA3, // 00011 opOUTPUT_POWER = 0xA4, // 00100 opOUTPUT_SPEED = 0xA5, // 00101 opOUTPUT_START = 0xA6, // 00110 opOUTPUT_POLARITY = 0xA7, // 00111 opOUTPUT_READ = 0xA8, // 01000 opOUTPUT_TEST = 0xA9, // 01001 opOUTPUT_READY = 0xAA, // 01010 opOUTPUT_POSITION = 0xAB, // 01011 opOUTPUT_STEP_POWER = 0xAC, // 01100 opOUTPUT_TIME_POWER = 0xAD, // 01101 opOUTPUT_STEP_SPEED = 0xAE, // 01110 opOUTPUT_TIME_SPEED = 0xAF, // 01111 opOUTPUT_STEP_SYNC = 0xB0, // 10000 opOUTPUT_TIME_SYNC = 0xB1, // 10001 opOUTPUT_CLR_COUNT = 0xB2, // 10010 opOUTPUT_GET_COUNT = 0xB3, // 10011 opOUTPUT_PRG_STOP = 0xB4, // 10100 } OP; int pwmfp; int Stop(unsigned char ch) { unsigned char Buf[4]; int ret; Buf[0] = opOUTPUT_STOP; Buf[1] = ch; ret = write(pwmfp,Buf,2); return ret; } int PrgStart(void) { unsigned char Buf[4]; int ret; Buf[0] = opPROGRAM_START; ret = write(pwmfp,Buf,1); return ret; } int PrgStop(void) { unsigned char Buf[4]; int ret; Buf[0] = opPROGRAM_STOP; ret = write(pwmfp,Buf,1); return ret; } int Start(void) { unsigned char Buf[4]; int ret; Buf[0] = opOUTPUT_START; Buf[1] = CH1 | CH2 | CH3 | CH4; ret = write(pwmfp,Buf,2); return ret; } int Power(unsigned char ch, unsigned char power) { unsigned char Buf[4]; int ret; Buf[0] = opOUTPUT_POWER; Buf[1] = ch; /* 複数のCHを指定する時は CH1 | CH2 といった形式で */ Buf[2] = power; ret = write(pwmfp,Buf,3); return ret; } int Reset(unsigned char ch) { unsigned char Buf[4]; int ret; Buf[0] = opOUTPUT_RESET; Buf[1] = ch; ret = write(pwmfp,Buf,2); return ret; } int main(int argc, char *argv[]) { unsigned char power; unsigned int seconds; pwmfp = open("/dev/lms_pwm",O_RDWR); if (pwmfp < 0) { printf("Cannot open dev/lms_pwm\n"); exit(-1); } if (argc != 3) { printf("Usage: %s POWER SECONDS\n", argv[0]); exit(-1); } power = (unsigned char)atoi(argv[1]); seconds = (unsigned int)atoi(argv[2]); PrgStop(); PrgStart(); Reset(CH1|CH2|CH3|CH4); Start(); printf("power:%d , seconds:%d\n", (int)power, seconds); Power(CH2, power); Power(CH3, power); sleep(seconds); Power(CH2, 0); Power(CH3, 0); Stop(CH2); Stop(CH3); PrgStop(); return 1; }
SOURCES = move.c SUBDIRS = move TARGET = move CONF = Linux ARCH = AM1808 include ../../open_first/rules.mk
実行方法
ビルド、d_pwm.koをinsmodする所まではサンプルと同じです。
実行時に引数で以下の2つを指定します
$ ./move POWER SECONDS
- POWER: -100 〜 100 (負値は後退)
- SECONDS: 前進/後退 時間
以下のようなシェルスクリプトで、
「指定した時間経過後に再生」をさせることができます。
- record_timer.sh
#!/bin/sh sleep_min() { echo "sleep_min $1" sleep $(($1 * 60)) } sleep_hour() { echo "sleep_hour $1" sleep_min $(($1 * 60)) } if [ $# -ne 2 ]; then echo "Usage $0 HOUR MINUTES" exit 1 fi sleep_hour $1 sleep_min $2 ./move 10 1 ./move -3 1
- 買ったままの状態だと「cron」も「atコマンド」も使えないので、sleepコマンドを使っています
「record_timer.sh」の引数は以下のとおりです。
$ ./record_timer.sh HOURS MINUTES
以下のように実行します。
$ nohup ./record_timer.sh 6 30 &
- 6時間30分後に再生
- ログアウト後も継続されるよう「nohup」で実行