ラズパイ仕様のISLisp

  • 1
    いいね
  • 0
    コメント

ArcSoft_画像17.PNG

はじめに

自作のISLisp処理系(EISL)にラズパイでWiringPIを操作する組込み関数を追加しました。LチカなどがLispからお手軽にできます。仕様の覚書です。

(注)ver0.65からはコンパイラにGCCのソースを埋め込めるようになりました。そこでこれらの関数は組み込みではなく、ライブラリになっています。(load "wiringpi.o")としてお使いください。

組み込み関数

EISL                                    C言語

(wiringpi-spi-setup ch speed)  <===>  wiringPiSPISetup (SPI_CH, SPI_SPEED)
(wiringpi-setup-gpio )  <===>  wiringPiSetupGpio()
(pin-mode n 'output)  <====> pinMode(n, OUTPUT)  or 'input -> INPUT 'pwm-output -> PWM-OUTPUT
(digital-write n v)  <===> digitalWrite(n, v);
(digital-write-byte v)  <===>  digitalWriteByte(value)
(digital-read pin)  <===> digitalRead(pin) 
(delay howlong) <===> void delay(unsigned int howLong)
(pull-up-dn-control pin pud)  <===> pullUpDnControl(pin,pud)
(pwm-set-mode 'pwm-mode-ms)  <===> pwmSetMode(PWM_MODE_MS); or 'pwm-mode-bal -> PWM_MODE_BAL
(pwm-set-clock n) <===>  pwmSetClock(n);
(pwm-set-range n) <===>  pwmSetRange(n);
(pwm-write pin value)  <===> pwmWrite(pin , value) 

Lチカ ISLispコード

wiringPiのセットアップをするにはroot権限が必要です。次のようにして起動してください。

sudo ./eisl

コード

(defglobal pin 5)
(defglobal flag nil)
(defun test ()
   (cond ((null flag) (wiringpi-setup-gpio)(setq flag t)))  
   (pin-mode pin 'output)
   (for ((i 0 (+ i 1)))
        ((> i 100) t)
        (digital-write pin 1)
        (delay 1000)
        (digital-write pin 0)
        (delay 1000)))

実行
プロンプトから次のように入力してください。

(test)

PWMによるサーボ制御

(defglobal flag nil)

(defun setup ()
  (cond ((null flag) (wiringpi-setup-gpio ) (setq flag t)))
  (pin-mode 18 'pwm-output)
  (pwm-set-mode 'pwm-mode-ms)
  (pwm-set-clock 400)
  (pwm-set-range 1024))

(defun test1 (n)
  (pwm-write 18 n))

実行

(setup)

(test 24)
(test 115)

PWMとサーボについては下記の記事が参考になりました。
http://qiita.com/locatw/items/f15fd9df40153bbb4d27

参考ページ
http://nya03n.hatenablog.com/entry/2015/07/05/114301

実行ファイル

以下のページにて無償提供しております。

なお、個人的な楽しみのための非商用利用に限っております。また、本ソフトウェアを使用したことによる損害には責任を負いません。自己責任でお願いします。
http://eisl.kan-be.com/library/easyislisp.html

簡易エディタ

ラズパイで実験をするのに、簡易なCUIエディタを装備しました。
http://qiita.com/sym_num/items/86c3ffed459ea4fde003

ソースコード

電子書籍の付録として販売しております。
https://www.amazon.co.jp/dp/B01IMUKOHS
linux版と同様に、単に makeとするだけでコンパイルが完了します。

コード

コンパイラにより下記のコードをコンパイルします。無償提供されているtarにwiringpi.lspとして収録されています。 ./eisl -c compiler.lsp のようにコンパイラとともにEISLを起動し、次のようにreplよりコンパイルします。

./ eisl - c compiler.lsp

(compile-file "wiringpi.lsp") 

(c-include "<wiringPi.h>")
(c-include "<wiringPiSPI.h>")
(c-option "-lwiringPi")


(defun wiringpi-setup-gpio ()
  (c-lang "Fmakeint(wiringPiSetupGpio());"))

(defun wiringpi-spi-setup-ch-speed (x y)
  (if (not (integerp x)) (error "wiringgpi-spi-setup-ch-spped: not integer" x))
  (if (not (integerp y)) (error "wiringgpi-spi-setup-ch-spped: not integer" y))
  (c-lang "Fmakeint(wiringPiSPISetup( (INT_MASK & X), (INT_MASK & Y)));"))

(defun pwm-set-mode (x)
  (cond ((eq x 'pwm-mode-ms)
         (c-lang "pwmSetMode(PWM_MODE_MS);"))
        ((eq x 'pwm-mode-bal)
         (c-lang "pwmSetMode(PWM_MODE_BAL);"))
        (t (error "pwm-set-mode: not integer" x)))
  t)


(defun pwm-set-range (x)
  (if (not (integerp x)) (error "pwm-set-range: not integer" x))
  (c-lang "pwmSetRange(INT_MASK & X);")
  t)

(defun pwm-set-clock (x)
  (if (not (integerp x)) (error "pwm-set-clock: not integer" x))
  (c-lang "pwmSetClock(INT_MASK & X);")
  t)


(defun pin-mode (x y)
  (cond ((eq y 'input)
         (c-lang "pinMode( (INT_MASK & X), INPUT);"))
        ((eq y 'output)
         (c-lang "pinMode( (INT_MASK & X), OUTPUT);"))
        ((eq y 'pwm-output)
         (c-lang "pinMode( (INT_MASK & X),PWM_OUTPUT);"))
        (t (error "pin-mode: illegal argument" y)))
   t)


(defun digital-write (x y)
  (if (not (integerp x)) (error "digital-write: not integer" x))
  (if (not (integerp y)) (error "digital-write: not integer" y))

  (c-lang "digitalWrite((INT_MASK & X),(INT_MASK & Y));")
  t)

(defun digital-write-byte (x)
  (if (not (integerp x)) (error "digital-write-byte: not integer" x))
  (c-lang "digitalWriteByte(INT_MASK & X);")
  t)


(defun pwm-write (x y)
  (if (not (integerp x)) (error "pwm-write: not integer" x))
  (if (not (integerp y)) (error "pwm-write: not integer" y))
  (c-lang "pwmWrite((INT_MASK & X),(INT_MASK & Y));")
  t)

(defun pull-up-dn-control (x y)
  (if (not (integerp x)) (error "pull-up-dn-control" x))
  (if (not (integerp y)) (error "pull-up-dn-control" y))
  (c-lang "pullUpDnControl((INT_MASK & X),(INT_MASK & Y));")
  t)

(defun digital-read (x)
  (if (not (integerp x)) (error "digital-read: not integer" x))
  (c-lang "Fmakeint(digitalRead(INT_MASK & X));"))

(defun delay (x)
  (if (not (integerp x)) (error "delay: not integer" x))
  (c-lang "delay(INT_MASK & X);")
  t)