著者:米田 聡
シェルスクリプトマガジンでは、小型コンピュータボード「Raspberry Pi」(ラズパイ)向けのセンサー搭載拡張ボード「ラズパイセンサーボード」を制作しました。第5回では、このボードを使った電子回路制御を取り上げます。具体的には、明るさ・近隣センサーに近づく物体の検出です。
シェルスクリプトマガジン Vol.58は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import smbus import time import RPi.GPIO as GPIO from threading import BoundedSemaphore class VCNL4020(): _ALS_OD = 0b00010000 # オンデマンド明るさ計測スタート _PROX_OD = 0b00001000 # オンデマンド近接計測スタート _ALS_EN = 0b00000100 # 明るさ繰り返し計測有効 _PROX_EN = 0b00000010 # 近接繰り返し計測有効 _SELFTIMED_EN = 0b00000001 # 内蔵タイマー有効 _CONT_CONV = 0b10000000 # Continue Conversion有効 _AMBIENT_RATE = 0b00010000 # 明るさの計測レート(default:2sample/s) _AUTO_OFFSET = 0b00001000 # 自動オフセットモード有効 _AVERAGING = 0b00000101 # 平均化(default:32conv) _COMMAND_REG = 0x80 # コマンドレジスタ _PID_REG = 0x81 # プロダクトIDレジスタ _PROX_RATE_REG = 0x82 # 近接測定レートジスタ _IR_CURRENT_REG = 0x83 # 近接測定用赤外線LED電流設定レジスタ(default=20mA) _AMBIENT_PARAM_REG = 0x84 # 明るさセンサーパラメータレジスタ _AMBIENT_MSB = 0x85 # 明るさ上位バイト _AMBIENT_LSB = 0x86 # 明るさ下位バイト _PROX_MSB = 0x87 # 近接上位バイト _PROX_LSB = 0x88 # 近接下位バイト _INT_CONTROL_REG = 0x89 # 割り込み制御レジスタ _LOW_TH_MSB = 0x8A # Lowしきい値(MSB) _LOW_TH_LSB = 0x8B # Lowしきい値(LSB) _HIGH_TH_MSB = 0x8C # Highしきい値(MSB) _HIGH_TH_LSB = 0x8D # Highしきい値(LSB) _INT_STATUS_REG = 0x8E # 割り込みステータス _INT_NO = 0x06 # int = GPIO6 # コールバック __callbackfunc = None def __init__(self, i2c_addr = 0x13, busno = 1): self.addr = i2c_addr self.i2c = smbus.SMBus(busno) self._write_reg(self._COMMAND_REG, self._ALS_OD |\ self._PROX_OD |\ self._ALS_EN |\ self._PROX_EN |\ self._SELFTIMED_EN ) self._write_reg(self._IR_CURRENT_REG, 2 ) # 20mA self._write_reg(self._AMBIENT_PARAM_REG, self._CONT_CONV |\ self._AMBIENT_RATE |\ self._AUTO_OFFSET |\ self._AVERAGING ) self.semaphore = BoundedSemaphore() # GPIO設定 GPIO.setmode(GPIO.BCM) GPIO.setup(self._INT_NO, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.add_event_detect(self._INT_NO, GPIO.FALLING, callback=self.__interruptfunc) time.sleep(0.6) # 初回測定まで待つ def _write_reg(self, reg, value): self.i2c.write_byte_data(self.addr, reg, value) def _read_reg(self, reg): return self.i2c.read_byte_data(self.addr, reg) # 高値用レジスタ設定 def set_high_threshold(self, value): self.semaphore.acquire() h = (value & 0xFF00) >> 8 l = value & 0x00FF self._write_reg(self._HIGH_TH_MSB, h) self._write_reg(self._HIGH_TH_LSB, l) self.semaphore.release() # 低値用レジスタ設定 def set_low_threshold(self, value): self.semaphore.acquire() h = (value & 0xFF00) >> 8 l = value & 0x00FF self._write_reg(self._LOW_TH_MSB, h) self._write_reg(self._LOW_TH_LSB, l) self.semaphore.release() # 割り込み有効化 def enable_interrupt(self, callbackfunc=None, prox=True, samples=1): self.semaphore.acquire() self.__callbackfunc = callbackfunc value = self._read_reg(self._INT_CONTROL_REG) if callbackfunc is not None: if prox: value |= 0b00000010 else: value |= 0b00000011 else: value &= 0b11111100 # samples samples &= 0b00000111 samples = samples << 5 value &= 0b00011111 value |= samples self._write_reg( self._INT_CONTROL_REG, value) self.semaphore.release() # 割り込み関数 def __interruptfunc(self, ch): if ch != self._INT_NO: return if self.__callbackfunc is not None: self.__callbackfunc(self.luminance, self.proximity) @property def luminance(self): self.semaphore.acquire() d = self.i2c.read_i2c_block_data(self.addr, self._AMBIENT_MSB, 2) self.semaphore.release() return (d[0] * 256 + d[1]) / 4 @property def proximity(self): self.semaphore.acquire() d = self.i2c.read_i2c_block_data(self.addr, self._PROX_MSB, 2) self.semaphore.release() return (d[0] * 256 + d[1]) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#!/usr/bin/env python3 import time from VCNL4020 import VCNL4020 sensor = VCNL4020() # コールバック関数 def callback(lux, prox): print('センサーに何かが接近しています') print('現在の明るさ:'+str(lux) ) print('近接センサー:'+str(prox) ) # 割り込み再設定 sensor.enable_interrupt(callback) # しきい値高を設定 sensor.set_high_threshold(2500) # しきい値低を設定 sensor.set_low_threshold(0) # 割り込み有効化 sensor.enable_interrupt(callback) try: while True: time.sleep(1) except KeyboardInterrupt: term = True |