CommonLisp에서 RaspberryPi 전자 공작 ~I2C 온도 센서~
11260 단어 전자 공작RaspberryPicommon-lisp
소개
이번에는 I2C에서 ADT7410을 사용한 온도 센서 모듈을 제어하고 싶습니다.
회로도
이번에는 먼저 RaspberryPi와 ADT7410을 먼저 연결해 버립니다.

기기 주소 확인
그런 다음 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
패키징
cffi를 Quicklisp로로드하고 패키지 정의.
평소입니다.
packages.lisp;; cffiをQuicklispでロード
(ql:quickload "cffi")
;; cl-cffiパッケージを定義
(defpackage :cl-cffi
(:use :common-lisp :cffi))
API 래퍼 작성
이번에 추가할 함수는 다음 중 하나뿐입니다.
· wiringPiI2CReadReg16
표시된 디바이스 레지스터에서 16비트 값을 읽습니다.
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))
;; It reads the 16-bit value from the indicated device register.
(defcfun "wiringPiI2CReadReg16" :int (fd :int) (reg :int))
I2C ADT7410 프로그램 본체
ADT7410에서 온도 데이터를 가져와 콘솔에 표시하는 프로그램입니다.
해상도 16 비트의 고정밀도로 온도를 얻기 위해 레지스터 0x03에 "0x80"을 쓰고 있습니다.
또, 온도 데이터를 취득하면 빅 엔디안이 되어 버리고 있으므로, 바이트 스왑 해 리틀 엔디안으로 할 필요가 있습니다.
【온도 계산에 대해】
・해상도 13비트의 경우
4~16비트째까지가 유효한 데이터이므로 취득 데이터를 8로 나누어 하위 3비트를 버린 다음 온도 분해능값인 0.0625를 곱합니다.
계산식:(취득 데이터/8) × 0.0625
・해상도 16비트의 경우
모든 데이터를 사용할 수 있으므로 그대로 온도 분해능치인 0.0078이라고 합니다.
계산식: 취득 데이터 × 0.0078
adt7410.lisp;; Load packages
(load "packages.lisp" :external-format :utf-8)
(in-package :cl-cffi)
;; Load wrapper API
(load "libwiringPi.lisp" :external-format :utf-8)
;; I2C device address (0x48)
(defconstant +i2c-addr+ #X48)
;; バイトスワップ関数
(defun byte-swap (num-value)
(let (str-value temp-msb temp-lsb)
;; 数値を文字列へ変換
(setq str-value (write-to-string num-value :base 16))
;; 上位2桁(MSB)を取得
(setq temp-msb (subseq str-value 0 2))
;; 下位2桁(LSB)を取得
(setq temp-lsb (subseq str-value 2))
;; スワップして結合
(setq str-value (concatenate 'string temp-lsb temp-msb))
;; 文字列を数値へ変換
(parse-integer str-value :radix 16)))
;; メイン関数
(defun main ()
(let (fd base-data actual-data result)
;; i2cの初期設定
(setq fd (wiringPiI2CSetup +i2c-addr+))
;; 温度を16ビットのデータで取得するようレジスタ「0x03」に設定
(wiringPiI2CWriteReg8 fd #X03 #X80)
;; ADT7410からデータを取得
(setq base-data (wiringPiI2CReadReg16 fd #X00))
;; バイトスワップ
(setq actual-data (byte-swap base-data))
;; 温度計算
(setq result (* actual-data 0.0078))
;; 結果を標準出力
(format t "~d~%" result)))
;; 実行!
(main)
실행
다음 명령으로 실행합니다.
sbcl --load adt7410.lisp
이하 실행중인 모습


측정: 28.421875°C
알람 온도계: 28.7°C
꽤 가까운 결과가 나오네요.
마지막으로
마침내 센서에서 데이터를 검색하는 곳까지 왔습니다.
역시 센서는 어렵네요.
우선, 이번 제일 힘들었던 것은 바이트 스왑 처리입니다・・・.
Reference
이 문제에 관하여(CommonLisp에서 RaspberryPi 전자 공작 ~I2C 온도 센서~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/fireflower0/items/09e32276cb00cace23fa
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이번에는 먼저 RaspberryPi와 ADT7410을 먼저 연결해 버립니다.

기기 주소 확인
그런 다음 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
패키징
cffi를 Quicklisp로로드하고 패키지 정의.
평소입니다.
packages.lisp;; cffiをQuicklispでロード
(ql:quickload "cffi")
;; cl-cffiパッケージを定義
(defpackage :cl-cffi
(:use :common-lisp :cffi))
API 래퍼 작성
이번에 추가할 함수는 다음 중 하나뿐입니다.
· wiringPiI2CReadReg16
표시된 디바이스 레지스터에서 16비트 값을 읽습니다.
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))
;; It reads the 16-bit value from the indicated device register.
(defcfun "wiringPiI2CReadReg16" :int (fd :int) (reg :int))
I2C ADT7410 프로그램 본체
ADT7410에서 온도 데이터를 가져와 콘솔에 표시하는 프로그램입니다.
해상도 16 비트의 고정밀도로 온도를 얻기 위해 레지스터 0x03에 "0x80"을 쓰고 있습니다.
또, 온도 데이터를 취득하면 빅 엔디안이 되어 버리고 있으므로, 바이트 스왑 해 리틀 엔디안으로 할 필요가 있습니다.
【온도 계산에 대해】
・해상도 13비트의 경우
4~16비트째까지가 유효한 데이터이므로 취득 데이터를 8로 나누어 하위 3비트를 버린 다음 온도 분해능값인 0.0625를 곱합니다.
계산식:(취득 데이터/8) × 0.0625
・해상도 16비트의 경우
모든 데이터를 사용할 수 있으므로 그대로 온도 분해능치인 0.0078이라고 합니다.
계산식: 취득 데이터 × 0.0078
adt7410.lisp;; Load packages
(load "packages.lisp" :external-format :utf-8)
(in-package :cl-cffi)
;; Load wrapper API
(load "libwiringPi.lisp" :external-format :utf-8)
;; I2C device address (0x48)
(defconstant +i2c-addr+ #X48)
;; バイトスワップ関数
(defun byte-swap (num-value)
(let (str-value temp-msb temp-lsb)
;; 数値を文字列へ変換
(setq str-value (write-to-string num-value :base 16))
;; 上位2桁(MSB)を取得
(setq temp-msb (subseq str-value 0 2))
;; 下位2桁(LSB)を取得
(setq temp-lsb (subseq str-value 2))
;; スワップして結合
(setq str-value (concatenate 'string temp-lsb temp-msb))
;; 文字列を数値へ変換
(parse-integer str-value :radix 16)))
;; メイン関数
(defun main ()
(let (fd base-data actual-data result)
;; i2cの初期設定
(setq fd (wiringPiI2CSetup +i2c-addr+))
;; 温度を16ビットのデータで取得するようレジスタ「0x03」に設定
(wiringPiI2CWriteReg8 fd #X03 #X80)
;; ADT7410からデータを取得
(setq base-data (wiringPiI2CReadReg16 fd #X00))
;; バイトスワップ
(setq actual-data (byte-swap base-data))
;; 温度計算
(setq result (* actual-data 0.0078))
;; 結果を標準出力
(format t "~d~%" result)))
;; 実行!
(main)
실행
다음 명령으로 실행합니다.
sbcl --load adt7410.lisp
이하 실행중인 모습


측정: 28.421875°C
알람 온도계: 28.7°C
꽤 가까운 결과가 나오네요.
마지막으로
마침내 센서에서 데이터를 검색하는 곳까지 왔습니다.
역시 센서는 어렵네요.
우선, 이번 제일 힘들었던 것은 바이트 스왑 처리입니다・・・.
Reference
이 문제에 관하여(CommonLisp에서 RaspberryPi 전자 공작 ~I2C 온도 센서~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/fireflower0/items/09e32276cb00cace23fa
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
cffi를 Quicklisp로로드하고 패키지 정의.
평소입니다.
packages.lisp
;; cffiをQuicklispでロード
(ql:quickload "cffi")
;; cl-cffiパッケージを定義
(defpackage :cl-cffi
(:use :common-lisp :cffi))
API 래퍼 작성
이번에 추가할 함수는 다음 중 하나뿐입니다.
· wiringPiI2CReadReg16
표시된 디바이스 레지스터에서 16비트 값을 읽습니다.
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))
;; It reads the 16-bit value from the indicated device register.
(defcfun "wiringPiI2CReadReg16" :int (fd :int) (reg :int))
I2C ADT7410 프로그램 본체
ADT7410에서 온도 데이터를 가져와 콘솔에 표시하는 프로그램입니다.
해상도 16 비트의 고정밀도로 온도를 얻기 위해 레지스터 0x03에 "0x80"을 쓰고 있습니다.
또, 온도 데이터를 취득하면 빅 엔디안이 되어 버리고 있으므로, 바이트 스왑 해 리틀 엔디안으로 할 필요가 있습니다.
【온도 계산에 대해】
・해상도 13비트의 경우
4~16비트째까지가 유효한 데이터이므로 취득 데이터를 8로 나누어 하위 3비트를 버린 다음 온도 분해능값인 0.0625를 곱합니다.
계산식:(취득 데이터/8) × 0.0625
・해상도 16비트의 경우
모든 데이터를 사용할 수 있으므로 그대로 온도 분해능치인 0.0078이라고 합니다.
계산식: 취득 데이터 × 0.0078
adt7410.lisp;; Load packages
(load "packages.lisp" :external-format :utf-8)
(in-package :cl-cffi)
;; Load wrapper API
(load "libwiringPi.lisp" :external-format :utf-8)
;; I2C device address (0x48)
(defconstant +i2c-addr+ #X48)
;; バイトスワップ関数
(defun byte-swap (num-value)
(let (str-value temp-msb temp-lsb)
;; 数値を文字列へ変換
(setq str-value (write-to-string num-value :base 16))
;; 上位2桁(MSB)を取得
(setq temp-msb (subseq str-value 0 2))
;; 下位2桁(LSB)を取得
(setq temp-lsb (subseq str-value 2))
;; スワップして結合
(setq str-value (concatenate 'string temp-lsb temp-msb))
;; 文字列を数値へ変換
(parse-integer str-value :radix 16)))
;; メイン関数
(defun main ()
(let (fd base-data actual-data result)
;; i2cの初期設定
(setq fd (wiringPiI2CSetup +i2c-addr+))
;; 温度を16ビットのデータで取得するようレジスタ「0x03」に設定
(wiringPiI2CWriteReg8 fd #X03 #X80)
;; ADT7410からデータを取得
(setq base-data (wiringPiI2CReadReg16 fd #X00))
;; バイトスワップ
(setq actual-data (byte-swap base-data))
;; 温度計算
(setq result (* actual-data 0.0078))
;; 結果を標準出力
(format t "~d~%" result)))
;; 実行!
(main)
실행
다음 명령으로 실행합니다.
sbcl --load adt7410.lisp
이하 실행중인 모습


측정: 28.421875°C
알람 온도계: 28.7°C
꽤 가까운 결과가 나오네요.
마지막으로
마침내 센서에서 데이터를 검색하는 곳까지 왔습니다.
역시 센서는 어렵네요.
우선, 이번 제일 힘들었던 것은 바이트 스왑 처리입니다・・・.
Reference
이 문제에 관하여(CommonLisp에서 RaspberryPi 전자 공작 ~I2C 온도 센서~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/fireflower0/items/09e32276cb00cace23fa
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
(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))
;; It reads the 16-bit value from the indicated device register.
(defcfun "wiringPiI2CReadReg16" :int (fd :int) (reg :int))
ADT7410에서 온도 데이터를 가져와 콘솔에 표시하는 프로그램입니다.
해상도 16 비트의 고정밀도로 온도를 얻기 위해 레지스터 0x03에 "0x80"을 쓰고 있습니다.
또, 온도 데이터를 취득하면 빅 엔디안이 되어 버리고 있으므로, 바이트 스왑 해 리틀 엔디안으로 할 필요가 있습니다.
【온도 계산에 대해】
・해상도 13비트의 경우
4~16비트째까지가 유효한 데이터이므로 취득 데이터를 8로 나누어 하위 3비트를 버린 다음 온도 분해능값인 0.0625를 곱합니다.
계산식:(취득 데이터/8) × 0.0625
・해상도 16비트의 경우
모든 데이터를 사용할 수 있으므로 그대로 온도 분해능치인 0.0078이라고 합니다.
계산식: 취득 데이터 × 0.0078
adt7410.lisp
;; Load packages
(load "packages.lisp" :external-format :utf-8)
(in-package :cl-cffi)
;; Load wrapper API
(load "libwiringPi.lisp" :external-format :utf-8)
;; I2C device address (0x48)
(defconstant +i2c-addr+ #X48)
;; バイトスワップ関数
(defun byte-swap (num-value)
(let (str-value temp-msb temp-lsb)
;; 数値を文字列へ変換
(setq str-value (write-to-string num-value :base 16))
;; 上位2桁(MSB)を取得
(setq temp-msb (subseq str-value 0 2))
;; 下位2桁(LSB)を取得
(setq temp-lsb (subseq str-value 2))
;; スワップして結合
(setq str-value (concatenate 'string temp-lsb temp-msb))
;; 文字列を数値へ変換
(parse-integer str-value :radix 16)))
;; メイン関数
(defun main ()
(let (fd base-data actual-data result)
;; i2cの初期設定
(setq fd (wiringPiI2CSetup +i2c-addr+))
;; 温度を16ビットのデータで取得するようレジスタ「0x03」に設定
(wiringPiI2CWriteReg8 fd #X03 #X80)
;; ADT7410からデータを取得
(setq base-data (wiringPiI2CReadReg16 fd #X00))
;; バイトスワップ
(setq actual-data (byte-swap base-data))
;; 温度計算
(setq result (* actual-data 0.0078))
;; 結果を標準出力
(format t "~d~%" result)))
;; 実行!
(main)
실행
다음 명령으로 실행합니다.
sbcl --load adt7410.lisp
이하 실행중인 모습


측정: 28.421875°C
알람 온도계: 28.7°C
꽤 가까운 결과가 나오네요.
마지막으로
마침내 센서에서 데이터를 검색하는 곳까지 왔습니다.
역시 센서는 어렵네요.
우선, 이번 제일 힘들었던 것은 바이트 스왑 처리입니다・・・.
Reference
이 문제에 관하여(CommonLisp에서 RaspberryPi 전자 공작 ~I2C 온도 센서~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/fireflower0/items/09e32276cb00cace23fa
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
sbcl --load adt7410.lisp
마침내 센서에서 데이터를 검색하는 곳까지 왔습니다.
역시 센서는 어렵네요.
우선, 이번 제일 힘들었던 것은 바이트 스왑 처리입니다・・・.
Reference
이 문제에 관하여(CommonLisp에서 RaspberryPi 전자 공작 ~I2C 온도 센서~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/fireflower0/items/09e32276cb00cace23fa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)