common-lisp
電子工作
RaspberryPi
LTk

CommonLispでRaspberryPi電子工作 ~GUIでLチカ~

More than 1 year has passed since last update.

はじめに

今回は、Ltkで作成したGUIからLEDを操作してLチカを行いたいと思います。

パッケージ作成

cffiとltkをQuicklispでロードし、パッケージ定義。

packages.lisp
;; cffiとltkをQuicklispでロード
(ql:quickload "cffi")
(ql:quickload "ltk")

;; パッケージ定義
(defpackage :cl-ltk
  (:use :common-lisp
    :ltk
    :cffi))

APIラッパー作成

こちらは前に作ったのと同じもの

libwiringPi.lisp
(define-foreign-library libwiringPi
  (:unix "libwiringPi.so"))

(use-foreign-library libwiringPi)

;; Initialization of the wiringPi
(defcfun "wiringPiSetupGpio" :int)

;; Set the mode of the GPIO pin
(defcfun "pinMode" :void (pin :int) (mode :int))

;; GPIO pin output control
(defcfun "digitalWrite" :void (pin :int) (value :int))

;; Waiting process
(defcfun "delay" :void (howlong :uint))

;; Set the state when nothing is connected to the terminal
(defcfun "pullUpDnControl" :void (pin :int) (pud :int))

;; Read the status of the GPIO pin
(defcfun "digitalRead" :int (pin :int))

プログラム本体

LED点灯用ボタンとLED消灯用ボタンを作って、その2つのボタンでLEDを制御するプログラムです。

button-blink.lisp
(load "packages.lisp" :external-format :utf-8)

(in-package :cl-ltk)

;; ラッパーAPIをロード
(load "libwiringPi.lisp" :external-format :utf-8)

;; GPIO11(23ピン)を「+pin+」の名前で定義
(defconstant +pin+ 11)

(defun main ()
  (wiringPiSetupGpio)  ; GPIOを初期化
  (pinMode +pin+ 1)    ; GPIO11を出力モード(1)に設定
  (with-ltk ()
    (wm-title *tk* "Button Blink")
    (bind *tk* "<Alt-q>"
          (lambda (event)
            (setq *exit-mainloop* t)))
    ;; ここから処理
    (let ((btn1 (make-instance 'button                     ; LED点灯用ボタン
                               :master nil                 ; トップレベルウィンドウ
                               :width 60                   ; 幅60ピクセル
                               :text "Turn on LED"))       ; ボタンに表示する文字列
          (btn2 (make-instance 'button                     ; LED消灯用ボタン
                               :master nil                 ; トップレベルウィンドウ
                               :width 60                   ; 幅60ピクセル
                               :text "Turn off LED")))     ; ボタンに表示する文字列
          (setf (command btn1) (lambda ()                  ; "Turn on LED"ボタンを押下した時の処理
                                 (digitalWrite +pin+ 1)))  ; GPIOを3.3VにしてLEDを点灯
          (setf (command btn2) (lambda ()                  ; "Turn off LED"ボタンを押下した時の処理
                                 (digitalWrite +pin+ 0)))  ; GPIOを0VにしてLEDを消灯
          (pack (list btn1 btn2)))))                       ; ウィジェットをまとめて配置

;; 実行!
(main)

回路図

回路図も前にやったLチカと同じものを使用

blink.png

実行

SBCLを起動して、以下のコマンドで実行

(load "button-blink.lisp" :external-format :utf-8)

以下実行中の様子

button-blink.png

以下実際のLEDの様子

LED点灯

LED消灯

ちゃんとLtkで作成したGUIアプリケーションからLEDを操作することができました。

最後に

今回は今までやってきた電子工作とGUIアプリケーションを合わせたものを作ってみました。
GUIアプリケーションと電子工作を組み合わせることで色々と面白いことができそうです。