Raspberry Pi 備忘録 / Mbedもあるよ!

Raspberry Pi であれこれやった事の記録

TJBot

ケース

Watson Maker Kits

形状データをダウンロードできる。

とりあえず、プリントしてみよう。

3Dプリンター不調で頓挫・・・しましたが、調整し直してプリントしました。 f:id:pongsuke:20180223130002j:plain パーツ

f:id:pongsuke:20180223132841j:plain 組んで

f:id:pongsuke:20180223132850j:plain 組んで

f:id:pongsuke:20180223132859j:plain こうなる

ケルトンだと、ターミネーターみたいで、なんか怖い。
特に目が!

カメラ

カメラの向き

www.youtube.com

youtube を見る限り、そして、実際にはめ込んでみたぴったり感からして、どうやら上下逆向きに(ケーブルを上向きに)設置するようだ。

逆向きに刺そうとすると、どうしてもリボンケーブルのコネクタが鑑賞して刺さらないのだ。

なので、撮影の際などには、-vf, --vflip : Set vertical flip オプションを付ける。

カメラの動作確認

$ raspistill -w 480 -h 360 -n -vf -o mod.jpg

f:id:pongsuke:20180223181149j:plain

サーボモーター(腕)

とりあえず動かしてみよう。

以前書いたコードをそのまま使ってみた。

SG92.py

#!/usr/bin/python
# coding: utf-8 

import RPi.GPIO as GPIO
import time
import signal
import sys 

gp_out = 21

def exit_handler(signal, frame):
        print("\nExit")
        servo.ChangeDutyCycle(2.5)
        time.sleep(0.5)
        servo.stop()
        GPIO.cleanup()
        sys.exit(0)

signal.signal(signal.SIGINT, exit_handler)

GPIO.setmode(GPIO.BCM)


GPIO.setup(gp_out, GPIO.OUT)
# pwm = GPIO.PWM([チャンネル], [周波数(Hz)])
servo = GPIO.PWM(gp_out, 50) 

servo.start(0.0)

val = [2.5,3.6875,4.875,6.0625,7.25,8.4375,9.625,10.8125,12]

servo.ChangeDutyCycle(val[0])
time.sleep(0.5)
servo.ChangeDutyCycle(val[8])
time.sleep(0.5)
servo.ChangeDutyCycle(val[0])
time.sleep(0.5)

while True:
        for i, dc in enumerate(val):
                servo.ChangeDutyCycle(dc)
                print("Angle:" + str(i*22.5)+"  dc = %.4f" % dc) 
                time.sleep(0.5)
        for i, dc in enumerate( reversed(val) ):
                servo.ChangeDutyCycle(dc)
                print("Angle:" + str(180 - i*22.5)+"  dc = %.4f" % dc) 
                time.sleep(0.5)

フルカラーLED

フルカラーLEDを触るのが今回が初めてです。

手元にあるのは カソードコモン のフルカラーLEDです。

f:id:pongsuke:20180228103909p:plain

左から、緑、青、共通カソード、赤 ですね。

挿して、520Ωの抵抗を付けました。

f:id:pongsuke:20180228111311j:plain

f:id:pongsuke:20180228111318j:plain

グラデーションさせるテスト

https://making.mrlittlebig.com/raspberry-pi-2-フルカラーledをグラデーション-5e4916fda419

こちらのコードを、中断できるように改変させていただきました。

#!/usr/bin/python
# coding: utf-8
import RPi.GPIO as GPIO
import time
import signal
import sys

def exit_handler(signal, frame):
        print("\nExit")
        red.stop()
        green.stop()
        blue.stop()
        time.sleep(0.5)
        GPIO.cleanup()
        sys.exit(0)

signal.signal(signal.SIGINT, exit_handler)

Rpin = 13
Bpin = 19
Gpin = 26

GPIO.setmode(GPIO.BCM)
GPIO.setup(Rpin,GPIO.OUT)
GPIO.setup(Bpin,GPIO.OUT)
GPIO.setup(Gpin,GPIO.OUT)

red = GPIO.PWM(Rpin, 50)
green = GPIO.PWM(Gpin, 50)
blue = GPIO.PWM(Bpin, 50)

red.start(0)
green.start(0)
blue.start(0)

blue.ChangeDutyCycle(100)

COUNT = 100
T = 0.04
I = 0
time.sleep(0.5)
for _ in xrange(0, COUNT):
        red.ChangeDutyCycle(I)
        blue.ChangeDutyCycle(100 - I)
        time.sleep(T)
        I+=1
I = 0
for _ in xrange(0, COUNT):
        red.ChangeDutyCycle(100-I)
        green.ChangeDutyCycle(I)
        I+=1
        time.sleep(T)
I = 0
for _ in xrange(0, COUNT):
        green.ChangeDutyCycle(100 - I)
        blue.ChangeDutyCycle(I)
        I+=1
        time.sleep(T)

time.sleep(0.5)
red.stop()
green.stop()
blue.stop()

GPIO.cleanup()

拡散キャップをかぶせました。

マイク

$ lsusb

$ lsusb 
Bus 001 Device 004: ID 8086:0808 Intel Corp. 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Intel Corp とのだけ認識されているけど、大丈夫かな?

$ arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 1: Device [USB PnP Sound Device], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

録音テスト

$ arecord -D plughw:1,0 -d 5 test.wav
録音中 WAVE 'test.wav' : Unsigned 8 bit, レート 8000 Hz, モノラル

kiyo@raspberrypi:~ $ aplay -D plughw:0,0 test.wav 
再生中 WAVE 'test.wav' : Unsigned 8 bit, レート 8000 Hz, モノラル

なお、スピーカーが片方しかない状態(アナログout の2局のうち片方しか配線して居ない状態)なので、モノラルで進めています。

FLiR Dev Kit を試す その4

画像を表示するだけなら今のままでも良いのですが、温度の算出をしたいので、Output frame に触れましょう。

触れたあとに、加工して、最後には画像にしたい、、、ので、Python + Opencv がお手軽ではないかと思っていたところ、素敵なサンプルコードを発見しました。

Python から キャプチャするコード

GitHub - groupgets/pylepton: Quick and dirty pure python library for interfacing with FLIR lepton

サンプルコード

import numpy as np
import cv2
from pylepton import Lepton

with Lepton() as l:
  a,_ = l.capture()
cv2.normalize(a, a, 0, 65535, cv2.NORM_MINMAX) # extend contrast
np.right_shift(a, 8, a) # fit data into 8 bits
cv2.imwrite("output.jpg", np.uint8(a)) # write it!

Lepton() で何が手に入って、Lepton.capture() で何が返ってくるのかを見ましょう。

  def capture(self, data_buffer = None, log_time = False, debug_print = False, retry_reset = True):
    """Capture a frame of data.
    Captures 80x60 uint16 array of non-normalized (raw 12-bit) data. Returns that frame and a frame_id (which
    is currently just the sum of all pixels). The Lepton will return multiple, identical frames at a rate of up
    to ~27 Hz, with unique frames at only ~9 Hz, so the frame_id can help you from doing additional work
    processing duplicate frames.
    Args:
      data_buffer (numpy.ndarray): Optional. If specified, should be ``(60,80,1)`` with `dtype`=``numpy.uint16``.
    Returns:
      tuple consisting of (data_buffer, frame_id)
    """

読みやすく改変

001.py

#!/usr/bin/env python
# -*- coding: utf-8 -*
import sys
import copy
import numpy as np
import cv2
from pylepton import Lepton

def main():
        with Lepton() as l:
                data_buffer, frame_id = l.capture()

        print("---data_buffer---")
        print(data_buffer[59:, 75:])
        print(data_buffer.shape)
        print(type(data_buffer))
        data_1d = data_buffer.ravel()
        print( 'MAX:%d, MIN:%d' % (np.max(data_1d), np.min(data_1d) ))

        # 変数のコピー
        data_8bit       = copy.deepcopy(data_buffer)
        data_normalized = copy.deepcopy(data_buffer)

        # data_normalized を正規化
        cv2.normalize(data_buffer, data_normalized, 0, 65535, cv2.NORM_MINMAX) # extend contrast
        # fit to 8 bit
        np.right_shift(data_8bit, 8, data_8bit)
        np.right_shift(data_normalized, 8, data_normalized)

        print("----data_8bit----")
        print(data_8bit[59:, 75:])
        print(data_8bit.shape)
        data_1d = data_8bit.ravel()
        print( 'MAX:%d, MIN:%d' % (np.max(data_1d), np.min(data_1d) ))

        print("---data_normalized---")
        print(data_normalized[59:, 75:])
        print(data_normalized.shape)
        data_1d = data_normalized.ravel()
        print( 'MAX:%d, MIN:%d' % (np.max(data_1d), np.min(data_1d) ))

        image_original  = np.uint8(data_8bit)
        image_gray              = np.uint8(data_normalized)
        image_rgb               = cv2.cvtColor(image_gray, cv2.COLOR_GRAY2BGR)
        image_org_rgb   = cv2.cvtColor(image_original, cv2.COLOR_GRAY2BGR)

        image_rgb[:, :, 0:2] = 0
        image_org_rgb[:, :, 0:2] = 0

        print("---image_rgb---")
        print(image_rgb[59:, 75:])
        print(image_rgb.shape)

        print("---image_org_rgb---")
        print(image_org_rgb[59:, 75:])
        print(image_org_rgb.shape)

        # リサイズ
        image_original  = cv2.resize(image_original, None, fx=4, fy=4)
        image_gray              = cv2.resize(image_gray, None, fx=4, fy=4)
        image_rgb               = cv2.resize(image_rgb, None, fx=4, fy=4)
        image_org_rgb   = cv2.resize(image_org_rgb, None, fx=4, fy=4)

        cv2.imshow("Leption original", image_original)
        cv2.imshow("Leption normalize", image_gray)
        cv2.imshow("Leption RGB", image_rgb)
        cv2.imshow("Leption org RGB", image_org_rgb)

        cv2.waitKey(0)
        cv2.destroyAllWindows()

if __name__ == '__main__':
        main()

やってみる。

$ ./001.py 
---data_buffer---
[[[7915]
  [7916]
  [7919]
  [7908]
  [7904]]]
(60, 80, 1)
<type 'numpy.ndarray'>
MAX:8327, MIN:7671
----data_8bit----
[[[30]
  [30]
  [30]
  [30]
  [30]]]
(60, 80, 1)
MAX:32, MIN:29
---data_normalized---
[[[95]
  [95]
  [96]
  [92]
  [90]]]
(60, 80, 1)
MAX:255, MIN:0
---image_rgb---
[[[ 0  0 95]
  [ 0  0 95]
  [ 0  0 96]
  [ 0  0 92]
  [ 0  0 90]]]
(60, 80, 3)
---image_org_rgb---
[[[ 0  0 30]
  [ 0  0 30]
  [ 0  0 30]
  [ 0  0 30]
  [ 0  0 30]]]
(60, 80, 3)

f:id:pongsuke:20171208152356p:plain

f:id:pongsuke:20171208152401p:plain

f:id:pongsuke:20171208152410p:plain

f:id:pongsuke:20171208152415p:plain

たとえば、 output frame は 7904 でした。

0.026 * ( 7903 - 8192 ) + カメラの温度 = -7.488度 + カメラの温度

ってことかな?

正規化しないと、最小値が29で、最大値が32 なので、画像とはなりえない。ほぼ一色。
どこかのフォーラムにも書いてあったけど、範囲を決めて(摂氏 -20 ~ +100度など?)、その範囲外は 0 と 255 とみなして、120度の中範囲で 255 を使用したほうが良いかもしれない。
-20度 と +100度 における正規化 かな?

そうすれば、画像として見られたものに成って、かつ、出番の多そうな温度も拾える、、、かな?

やってみないとわからない。

-10度 +80度 を入れてみる

やってみた

強引ですが、output buffer を書き換えて、常に -10 と +80 が登場するようにして、それを 0~255 で正規化してみました。

左上の白と右上の黒が、それです。

#!/usr/bin/env python
# -*- coding: utf-8 -*
import sys
import copy
import numpy as np
import cv2
from pylepton import Lepton

def main():
        with Lepton() as l:
                data_buffer, frame_id = l.capture()

        print("---data_buffer---")
        print(data_buffer[59:, 75:])
        print(data_buffer.shape)
        print(type(data_buffer))
        data_1d = data_buffer.ravel()
        print( 'MAX:%d, MIN:%d' % (np.max(data_1d), np.min(data_1d) ))

        # 変数のコピー
        data_8bit       = copy.deepcopy(data_buffer)
        data_normalized = copy.deepcopy(data_buffer)

        # -10 +80 で上書き:基準値は 8192
        data_8bit[0,0,0]        = 7807 # -10度
        data_8bit[59,79,0]      = 11268 # +80度

        # 正規化
        cv2.normalize(data_8bit, data_8bit, 0, 255, cv2.NORM_MINMAX) # extend contrast
        cv2.normalize(data_normalized, data_normalized, 0, 255, cv2.NORM_MINMAX) # extend contrast

        print("----data_8bit----")
        print(data_8bit[59:, 75:])
        print(data_8bit.shape)
        data_1d = data_8bit.ravel()
        print( 'MAX:%d, MIN:%d' % (np.max(data_1d), np.min(data_1d) ))

        print("---data_normalized---")
        print(data_normalized[59:, 75:])
        print(data_normalized.shape)
        data_1d = data_normalized.ravel()
        print( 'MAX:%d, MIN:%d' % (np.max(data_1d), np.min(data_1d) ))

        image_original  = np.uint8(data_8bit)
        image_gray              = np.uint8(data_normalized)
        image_bgr               = cv2.cvtColor(image_gray, cv2.COLOR_GRAY2BGR)
        image_org_bgr   = cv2.cvtColor(image_original, cv2.COLOR_GRAY2BGR)

        image_bgr[:, :, 0:2] = 0
        image_org_bgr[:, :, 0:2] = 0

        print("---image_bgr---")
        print(image_bgr[59:, 75:])
        print(image_bgr.shape)

        print("---image_org_bgr---")
        print(image_org_bgr[59:, 75:])
        print(image_org_bgr.shape)

        # リサイズ
        image_original  = cv2.resize(image_original, None, fx=4, fy=4)
        image_gray              = cv2.resize(image_gray, None, fx=4, fy=4)
        image_bgr               = cv2.resize(image_bgr, None, fx=4, fy=4)
        image_org_bgr   = cv2.resize(image_org_bgr, None, fx=4, fy=4)

        cv2.imshow("Leption original", image_original)
        cv2.imshow("Leption normalize", image_gray)
        cv2.imshow("Leption RGB", image_bgr)
        cv2.imshow("Leption org RGB", image_org_bgr)
        # 保存
        cv2.imwrite("001.image_original.png", image_original)
        cv2.imwrite("001.image_gray.png", image_gray)
        cv2.imwrite("001.image_bgr.png", image_bgr)
        cv2.imwrite("001.image_org_bgr.png", image_org_bgr)

        cv2.waitKey(0)
        cv2.destroyAllWindows()

if __name__ == '__main__':
        main()

最初から 255 で正規化しました。

f:id:pongsuke:20171208161207p:plain

f:id:pongsuke:20171208161212p:plain

この2つの画像では、真っ赤(右下)なら、カメラより+80度高く、真っ黒(左上)なら、カメラより10度低い事になります。

映像としては、面白みが無い。

熱湯が入ったカップを持って、撮影してみました。

室温は20度なので、おそらくカメラも20度前後。
お湯は電気ポットから出したばかりです。

f:id:pongsuke:20171208162047p:plain

f:id:pongsuke:20171208162042p:plain

Output buffer の最大値は 9664 だった。おそらくこれはコップ。

0.026 * (9664 - 8192) = 38.272

室温の20を足すと、 だいたい60度?

こうなってきたら、もうちょっと正確に温度を用意して、キャリブレーション(傾きを算出)してみたくもなる。

でも、正確に温度のわかっている物体って、どこにあるのだろか。

修正

cv2.COLOR_GRAY2RGB を指定しても、出力が BGR に成っていたので、 cv2.COLOR_GRAY2BGR に直しました。

FLiR Dev Kit を試す その3

FLiR Dev Kit を試す その3

まず、メモを残します。

I2C でセンサーから温度を取得する。

LEP_GetSysFpaTemperatureKelvin の返り値が何なのかわからない・・・。

FPA Temp In Kelvin x 100 とあるので、カメラの温度(Kelvin)の100倍の値っぽいのだが、、、。

FFC

フラットフィールド補正モード とは、なんぞや・・・

lepton3 の 国内販売

Lepton, Lepton 3.0, FLIR | コーンズ テクノロジーオンラインショップ

FAQ も有って、全くの無知なので、読むだけで何かしら得られる。

よくあるご質問 | サイトタイトル

データシートいわく

データシートいわく、4種の温度に関係した数字がありそうだ。

4.5.5 SYS AUX Temperature Kelvin
This command returns the Lepton Camera’s AUX Temperature in Kelvin. This value is from a thermistor located on the Lepton housing.

LEP_RESULT LEP_GetSysAuxTemperatureKelvin(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr, LEP_SYS_AUX_TEMPERATURE_KELVIN_T_PTR auxTemperaturePtr);

4.5.6 SYS FPA Temperature Kelvin
This command returns the Lepton Camera’s FPA Temperature in Kelvin.

LEP_RESULT LEP_GetSysFpaTemperatureKelvin(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr, LEP_SYS_FPA_TEMPERATURE_KELVIN_T_PTR fpaTemperaturePtr)

そもそも、FPA とは、なんだろうか?

フォーカルプレーンアレイ (Focal Plane Arrays; FPA)

SDK の DOC いわく

How to install FLIR Lepton Thermal Camera and applications on Raspberry Pi - Appropedia: The sustainability wiki

カメラ内部温度

internal temperature of the camera. という表現が出て来る。
カメラ内部の温度かな?

そして、The output frame for the internal temperature is 8192 とある。

カメラの内部温度 = 8192 なので、2の13乗 ですね。

output frame 0 = 0 kelvin なら話は早いんだけど、どうやらそうではなさそう?原点は通らないのかな。

最高温度と最低温度

Lepton Thread.h をよめば、取得方法がわかるよ! とか書いてある。

・・・単純に全てのフレームバッファの最小値・最大値を保存してた。それだけだった。

value = frameBuffer[i];
if(value > maxValue) {
    maxValue = value;
}
if(value < minValue) {
    minValue = value;
}

そして、画像のために、最小値:0 ~ 最大値:255 で、正規化している。
RGG とかにしやすいからかな。

rawデータを取得すると、 pgm フォーマットで、数字がダイレクトに入っている。

MAX Output frame = 最高温度
MIN Output frame = 最低温度

温度の算出

1.センサー自体の温度が手に入り、その温度の Frame を 8192 とする。

2.Experimental な温度と、Frame を手に入れる。

3.その2点で、線形回帰する

のかな?

その、角度ですが、0.0217 だとか、0.026 だとか書いている人がいる。

大体そうだとしたら、

温度 = 0.026 * ( OutputFrame - 8192 ) + カメラの温度

になるのかな???

とあるピクセルの OutputFrame 20000 だとしたら、

0.026 * ( 20000 - 8192 ) + カメラの温度 = 307 度 + カメラの温度 かな。

画像のために正規化する前の 生の OutputFrame を見てみないとわからない。

FLiR Dev Kit を試す その2

続きです。

基本的に、下記の記事に従います。

FLIR Lepton Hookup Guide - learn.sparkfun.com

カメラデバイスの組み込み

f:id:pongsuke:20171206180805j:plain

カメラモジュールを、breakout board に、突起の向きに注意しながら刺す。

ワイヤリング

f:id:pongsuke:20171206181132p:plain

Rpi3 と breakout board が、どちらもオスなので、
メス・メスのジャンパー・ケーブルが必要になりますが、あまり持っていないと思います。

私は、QIコネクタとハウジングを持っていたので作りましたが、みんなどうするんだろう。
速攻でハンダ付けするのでしょうか。

本体の設定

SPI, I2C を 有効にする

raspi-config から2つを有効にする。

プログラムの準備

GitHub - groupgets/LeptonModule: Code for getting started with the FLIR Lepton breakout board

からファイルを取得します。

ガイドにzipでダウンロードしたら?的に書いてあるので、従いました。

解凍する。

$ unzip LeptonModule-master.zip

コンパイル

$ cd cd LeptonModule-master/software/raspberrypi_libs/leptonSDKEmb32PUB/
$ make

$ cd ../../raspberrypi_video/
$ qmake && make

動作確認

$ sudo ./raspberrypi_video 
X Error: BadAccess (attempt to access private resource denied) 10
  Extension:    130 (MIT-SHM)
  Minor opcode: 1 (X_ShmAttach)
  Resource id:  0x191
X Error: BadShmSeg (invalid shared segment parameter) 128
  Extension:    130 (MIT-SHM)
  Minor opcode: 5 (X_ShmCreatePixmap)
  Resource id:  0x1a0000b
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x1a0000c
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x1a0000c

エラーが出てしまう。

sudo なしでやってみる。

$ ./raspberrypi_video

・・・ドキュメントにもある、エーラ状態が出た。

f:id:pongsuke:20171207115805p:plain

原因とその後

何をやっても動かないので、I2Cが動いていないのではないかと色々考えているうちに、3時間経過し、ふと気が付きました。

基盤の上下が逆だ!

久しぶりに触ったので、上下(どっちがPin1か)を間違えていました・・・。

んで、結果がこれ。

f:id:pongsuke:20171207135850p:plain

その後、何度か起動しようとしますが、エラー画面になる。
何が原因なのだろうか。

OSの電源を抜いてから起動すると、治ったりする。
reboot コマンドでは治らない)
なんだろうか。

Forum で話題になっているとおり、カメラモジュールのリセットが必要なのかもしれない。

SPIDEV について

各種ファイルで、 spidev が 0 なのか 1 なのかを指定する場所があったりしますが、

私の環境では、/dev/spidev0.0 でした。

久しぶりに Raspbianをインストールしてみる / VNC が改善!

色々変わったと思うので、備忘録を作り直します。

Raspberry pi 3 model b に、Raspbian を入れます。

VNCがちゃんと起動しました。

OSの準備まで

OS img の取得

Download Raspbian for Raspberry Pi

2017-12-06 の時点で RASPBIAN STRETCH WITH DESKTOP Version:November 2017 でした。

ダウンロードした zip を展開して、img ファイルを取得します。

micro sd カードのフォーマット

SD Memory Card Formatter でフォーマットします。

SDメモリカードフォーマッター for Windows Download - SD Association

インストール後のプログラム名は、 SD Card Fromatter です。
Start Menu から起動する場合は注意です。

img を焼く

Win32DiskImager で焼きます。

Win32 Disk Imager download | SourceForge.net

OS起動後

ファームウェアのアップデート

$ sudo rpi-update
$ reboot

パッケージリストの更新、 インストールされてるパッケージの更新

$ sudo apt-get update
$ sudo apt-get upgrade

raspi-config からの設定

  1. piにパスワードを設定する

  2. Boot Option から、起動時に CLI(コマンドライン)自動ログインなし にしておいた。

ログイン後、必要に応じて startx する。

  1. Localization Options
  2. Change locale Ja_JP.UTF-8 UTF-8
  3. Timezone Asia-tokyo
  4. Change Wi-fi Country - jp

SSH ON

$ sudo systemctl enable ssh
$ sudo systemctl start ssh

root パスワード設定と、新規ユーザー作成、グループ所属、sudoers 設定

危ないので、root のパスワードも変更します。

$ sudo su -
# passwd

また、username が判明しているだけでも嫌なので、pi は使わずに、新規に user を作ります。
その際、各種グループに所属させておかないと、音がならなかったりします。(昔はそうだった)

なお、useradd で作成すると、ログインシェルの設定ファイルなどが作成されないので、adduser が良さそうです。

$ sudo adduser USERNAME

$ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio
$ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio USERNAME

$ sudo visudo
(末尾に以下を追記)
USERNAME  ALL=NOPASSWD: ALL

IP を固定する

/etc/dhcpcd.conf を編集し、下記を追記します。

interface eth0
static ip_address=192.168.100.88/24
static routers=192.168.100.1
static domain_name_servers=192.168.100.1

音の設定

Control の確認
$ amixer controls
numid=3,iface=MIXER,name='PCM Playback Route'
numid=2,iface=MIXER,name='PCM Playback Switch'
numid=1,iface=MIXER,name='PCM Playback Volume'
numid=5,iface=PCM,name='IEC958 Playback Con Mask'
numid=4,iface=PCM,name='IEC958 Playback Default'
アナログに設定
$ amixer cset numid=3 1
usb で鳴らしてみる

バイスの確認をして、aplay, mpeg321 で試します。
omxplayer は、usbに音をだすことはできなかったはず。

$ lsusb
Bus 001 Device 004: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 005: ID 041e:323d Creative Technology, Ltd 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ aplay -D plughw:1,0 /usr/share/scratch/Media/Sounds/Vocals/Singer1.wav

$ sudo apt-get install mpg321
$ mpg321 -o alsa -a hw:1 some.mp3

$ sudo apt-get install mplayer
$ mplayer -ao alsa:device=plughw=1.0 example.mp3
omxplayer
$ omxplayer **.mp4

VNC の設定

raspi-config

  1. Interface options
  2. P3 VNC

から、有効にする。

それから、デスクトップの右上のVNCアイコンから、

VNC Options ->Troubleshooting -> Enable experimental direct capture mode

そして、再起動。

windowsvnc viewer で、IPを設定して接続すると、ログイン画面からちゃんと出てきました。

f:id:pongsuke:20171206172133p:plain

スクリーンショットを撮る

vnc viewer で、 Properties > Options > keys の Pass special keys directly to VNC Server を OFF にすれば、Print Screen のボタンが Windows サイドで動くみたいです。

f:id:pongsuke:20171206172412p:plain

f:id:pongsuke:20171206172430p:plain

FLiR Dev Kit を試す その1

FLiR Dev Kit を試します。

f:id:pongsuke:20171205130719j:plain

f:id:pongsuke:20171205130732j:plain

これなに?

FLiR とは、前方監視型赤外線(forward looking infra-red)の略称らしいです。

モノ

スイッチサイエンスから購入しました。

www.switch-science.com

電源電圧: 3~5V
センサ形式: LWIR(8 ~ 14 μm)
画角: 水平視野51度、対角63.5度
解像度: 80 × 60
最小感度: 50mK
インターフェース(映像): MIPIもしくはSPI
インターフェース(制御): I2C
素早い応答性 (< 0.5 sec)
省電力: 通常150mW、最大160mW未満

メーカのガイド

FLIR Lepton Hookup Guide - learn.sparkfun.com

参考コード

GitHub - groupgets/LeptonModule: Code for getting started with the FLIR Lepton breakout board

斜め読みメモ

動作が不安定でも、モジュールの物理的な抜き差しはしない。
CSの接続先を 40PIN → 38PIN に変えればOKらしい。(未確認)

NFCリーダーライター PaSoRi を試す

f:id:pongsuke:20170518112302j:plain

NFCリーダーライター PaSoRi を試します。

手元にあるのは RC-S370で、現在は生産が終了しているモデルですね。

認識

$ lsusb 
Bus 001 Device 004: ID 041e:323d Creative Technology, Ltd 
Bus 001 Device 005: ID 054c:02e1 Sony Corp. FeliCa S330 [PaSoRi]
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Sony Corp. FeliCa S330 [PaSoRi] と認識されています。

nfcpy

nfcpy を使います。

ドキュメントはこちら

Getting started — nfcpy 0.13.0 documentation

インストー

$ sudo pip install nfcpy

 ・・・

Successfully installed nfcpy ndeflib pydes libusb1
Cleaning up...

動作確認

$ python -m nfc
This is the 0.13.0 version of nfcpy run in Python 2.7.9
on Linux-4.9.28-v7+-armv7l-with-debian-8.0
I'm now searching your system for contactless devices
** found usb:054c:02e1 at usb:001:005 but access is denied
-- the device is owned by 'root' but you are 'kiyo'
-- also members of the 'root' group would be permitted
-- you could use 'sudo' but this is not recommended
-- better assign the device to the 'plugdev' group
   sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"02e1\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
   sudo udevadm control -R # then re-attach device
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
Sorry, but I couldn't find any contactless device

指示が出ているので従う。

$ sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"02e1\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
$ sudo udevadm control -R 

もう一度・・・

$ python -m nfc
This is the 0.13.0 version of nfcpy run in Python 2.7.9
on Linux-4.9.24-v7+-armv7l-with-debian-8.0
I'm now searching your system for contactless devices
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
Sorry, but I couldn't find any contactless device

おや?

RC-S380/P でやりなおす

特に対応から外れているわけでも無いので、手元にあるPaSoRiが壊れていのかもしれない、、、ということで、新しい PaSoRi を買い直しました。

RC-S380/P を刺して、、、

This is the 0.13.0 version of nfcpy run in Python 2.7.9
on Linux-4.9.28-v7+-armv7l-with-debian-8.0
I'm now searching your system for contactless devices
** found SONY RC-S380/P NFC Port-100 v1.11 at usb:001:010
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs

よし。

やはり、手元の S370 は、古くて壊れていたのかな?

git のサンプルを動かす

スイカを乗せて・・・

$ git clone https://github.com/nfcpy/nfcpy.git
$ cd nfcpy
$ python examples/tagtool.py
[nfc.clf] searching for reader on path usb
[nfc.clf] using SONY RC-S380/P NFC Port-100 v1.11 at usb:001:010
** waiting for a tag **
Type3Tag 'FeliCa Standard (RC-S915)' ID=*** PMM=*** SYS=***

データを読み書きする

まず、メディア?を入手します。

アマゾンで買ったこれは、素直に動いてくれました。

www.amazon.co.jp

先に書くと、フォーマットをして、NDEF 対応にしないと NDEF のやり取りが来ません。

NDEFフォーマットに成功したメディア達
f:id:pongsuke:20170518154414j:plain

フォーマット

format.py

import nfc

def on_connect(tag):
        print("format:", tag.format())

clf = nfc.ContactlessFrontend('usb')
if clf:
        print("Clf: {}".format(clf))
        clf.connect(rdwr={
                'on-connect': on_connect
        })

clf.close()

実行

$ python format.py 
Clf: SONY RC-S380/P on usb:001:010
('format:', True)
データの読み取り

messageに入っているデータを読み込みます。

フォーマットしただけだと、空っぽです。

import nfc

def on_startup(targets):
        print("on_startup()")
        return targets

def on_connect(tag):
        print("Tag: {}".format(tag))
        print("Tag type: {}".format(tag.type))
        #print '\n'.join(tag.dump())
        if tag.ndef:
                print tag.ndef.message.pretty()
        #return True

def on_release(tag):
        print("on_release()")
        if tag.ndef:
                print(tag.ndef.message.pretty())

clf = nfc.ContactlessFrontend('usb')
if clf:
        print("Clf: {}".format(clf))
        clf.connect(rdwr={
                'on-startup': on_startup,
                'on-connect': on_connect,
                'on-release': on_release
        })

clf.close()

実行

$ python 001.py 
Clf: SONY RC-S380/P on usb:001:010
on_startup()
Tag: Type3Tag 'FeliCa Lite-S (RC-S966)' ID=_ID_ PMM=_PMM_ SYS=88B4
Tag type: Type3Tag
record 1
  type   = ''
  name   = ''
  data   = ''
書き込み

書き込んで、確認してみる。

import nfc

def on_startup(targets):
        print("on_startup()")
        return targets

def on_connect(tag):
        print("Tag: {}".format(tag))
        print("Tag type: {}".format(tag.type))
        #print '\n'.join(tag.dump())
        if tag.ndef:
                record = nfc.ndef.TextRecord("Hello World!")
                tag.ndef.message = nfc.ndef.Message(record)
                print tag.ndef.message.pretty()
        #return True

def on_release(tag):
        print("on_release()")
        if tag.ndef:
                print(tag.ndef.message.pretty())

clf = nfc.ContactlessFrontend('usb')
if clf:
        print("Clf: {}".format(clf))
        clf.connect(rdwr={
                'on-startup': on_startup,
                'on-connect': on_connect,
                'on-release': on_release
        })

clf.close()

実行

$ python 002.py 
Clf: SONY RC-S380/P on usb:001:010
on_startup()
Tag: Type3Tag 'FeliCa Lite-S (RC-S966)' ID=__ID__ PMM=__PMM__ SYS=88B4
Tag type: Type3Tag
record 1
  type   = 'urn:nfc:wkt:T'
  name   = ''
  data   = '\x02enHello World!'

今回は、いつ買ったわからない RC-370 が動かなかったけれども、買い直した RC-S380/P では動いた点、

フォーマットしないと NDEF でのやり取りができない点でつまずきました!