CommonLisp에서 RaspberryPi 전자 공작 ~I2C LCD 그 1~

소개



이번에는 I2C에서 액정 모듈【MI2CLCD-01】을 제어하고 싶습니다.
우선은 간단히 「Hello, world!」를 표시합니다.

회로도



이번에는 우선 먼저 RaspberryPi와 MI2CLCD-01을 먼저 연결해 버립니다.



기기 주소 확인



그런 다음 MI2CLCD-01의 디바이스 주소를 확인합니다.
장치 주소를 확인하려면 i2cdetect 명령을 사용합니다.
pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

위의 결과에서 장치 주소가 '0x3e'임을 알 수 있습니다.

패키징



cffi를 Quicklisp로로드하고 패키지 정의.
평소입니다.

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

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

API 래퍼 작성



이번에 추가할 함수는 다음 두 가지입니다.

· wiringPiI2CSetup
이렇게 하면 지정된 디바이스 ID로 I2C 시스템이 초기화됩니다.
ID는 장치의 I2C 번호이며, 이를 찾기 위해 i2cdetect 명령을 사용할 수 있습니다.
반환 값은 표준 Linux 파일 핸들이며 오류가 있으면 -1을 반환합니다.

· wiringPiI2CWriteReg8
8비트 데이터 값을 지정된 디바이스 레지스터에 씁니다.

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))

;; Initialization of the I2C systems.
(defcfun "wiringPiI2CSetup" :int (fd :int))

;; Writes 8-bit data to the instructed device register.
(defcfun "wiringPiI2CWriteReg8" :int (fd :int) (reg :int) (data :int))

I2C LCD 프로그램 본체



mi2clcd-01.lisp
;; Load packages
(load "packages.lisp" :external-format :utf-8)

(in-package :cl-cffi)

;; Load wrapper API
(load "libwiringPi.lisp" :external-format :utf-8)

;; i2cdetectコマンドで確認したI2Cデバイスアドレス (0x3e)
(defconstant +i2c-addr+ #X3E)

;; LCDのコントラスト (範囲:0x00~0x0F)
(defconstant +contrast+ #X0A)

(defun i2c-lcd ()
  ;; I2Cシステムの初期化
  (setq fd (wiringPiI2CSetup +i2c-addr+))

  ;; コントラストの計算
  (setq fcnt (logior (logand +contrast+ #X0F) #X70))

  ;; 各種初期化処理
  (wiringPiI2CWriteReg8 fd #X00 #X38) ; Function set : 8bit, 2 line
  (wiringPiI2CWriteReg8 fd #X00 #X39) ; Function set : 8bit, 2 line, IS=1
  (wiringPiI2CWriteReg8 fd #X00 #X14) ; Internal OSC freq
  (wiringPiI2CWriteReg8 fd #X00 fcnt) ; Contrast set
  (wiringPiI2CWriteReg8 fd #X00 #X5F) ; Power/ICON/Constract
  (wiringPiI2CWriteReg8 fd #X00 #X6A) ; Follower control
  (delay 300)                         ; Wait time (300 ms)
  (wiringPiI2CWriteReg8 fd #X00 #X38) ; Function set : 8 bit, 2 line, IS=0
  (wiringPiI2CWriteReg8 fd #X00 #X06) ; Entry mode set
  (wiringPiI2CWriteReg8 fd #X00 #X0C) ; Display on/off
  (wiringPiI2CWriteReg8 fd #X00 #X01) ; Clear display
  (delay 30)                          ; Wait time (0.3 ms)
  (wiringPiI2CWriteReg8 fd #X00 #X02) ; Return home
  (delay 30)                          ; Wait time (0.3 ms)

  (wiringPiI2CWriteReg8 fd #X00 #X80) ; 1段目にカーソルをセット

  ;; 1段目に「Hello,」を表示
  (loop :for char :across "Hello,"
    :do (wiringPiI2CWriteReg8 fd #X40 (char-code char)))

  (wiringPiI2CWriteReg8 fd #X00 #XC0) ; 2段目にカーソルをセット

  ;; 2段目に「world!」を表示
  (loop :for char :across "world!"
    :do (wiringPiI2CWriteReg8 fd #X40 (char-code char))))

;; 実行!
(i2c-lcd)

실행



SBCL을 시작하고 다음 명령으로 실행.
(load "mi2clcd-01.lisp" :external-format :utf-8)

이하 실행중인 모습



1단째에 「Hello,」, 2단째에 「world!」라고 표시되었습니다.

마지막으로



우선, 설정 방법만 알면 상당히 간단하게 할 수 있습니다.
I2C가 가능하게 되면 전자 공작으로 할 수 있는 것의 폭이 훨씬 넓어질 것 같네요.

좋은 웹페이지 즐겨찾기