ラズパイ仕様のISLisp

  • 0
    いいね
  • 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)