3duilab が 2022年01月28日19時23分56秒 に編集
初版
タイトルの変更
高速非接触スイッチ_ドットマトリクスLEDでカウント
タグの変更
非接触センサー
スイッチ
電子工作
Python
メイン画像の変更
記事種類の変更
製作品
本文の変更
# 概要 非接触空間センサーを使った世界でも珍しい高速スイッチの実験です。非接触スイッチは感染症対策の他、**接点が無く壊れ難い**ので実用的です。また、ドットマトリクスLEDを使った数値表示についても詳しく解説します。 双方向ハンドセンサー https://interactive-hand-sensor.com/root/ # 動画 @[youtube](https://youtu.be/s7OKTZ3vwos) ※数値のちらつきはビデオのサンプリングが原因です。通常はほとんど見えません。 # 配線図 ![キャプションを入力できます](https://camo.elchika.com/2cd580231057a44a4b307c9e448c2665471243eb/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f31383164613832352d646330322d343939302d626461342d3362323431386663646437372f66383063623734352d333363322d343039332d393865312d626133303836333766363239/) # フローチャート ![キャプションを入力できます](https://camo.elchika.com/3b47669b0adff369876af295d45ba3737b73588d/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f31383164613832352d646330322d343939302d626461342d3362323431386663646437372f32346564343931372d663261652d346134642d616161372d336430636362633462653364/) # ドットマトリクスLEDの数値表示 ![キャプションを入力できます](https://camo.elchika.com/0fde7d029f8e1b87c756c9177c375ef4bb2178c2/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f31383164613832352d646330322d343939302d626461342d3362323431386663646437372f62653761613465612d373736392d343762642d626362372d376538613238626163303539/) ## ドットマトリクスLEDで画像を表示する Raspberry Pi PicoのMicroPythonでは図のように表示する8ビット数を長さ8の画像リストに保存します。次に行を変化させながら1行ずつ表示関数を実行します。この関数はSPIで2バイトの行、列データをシフトレジスタに送信し1行書き込みます。タイマー割り込みでこれを連続的にコールし、処理を自動化しています。 ## ドットマトリクスLEDで数値を変化させる 数値の場合は図のように4個の8ビット数で管理すると便利です。画像リストを変更し保存すると上記タイマー割り込みで00〜99の数値が表示できます。規模が小さいので関数オブジェクト(クロージャ)を使ってまとめています。 # コード ```Python:非接触高速スイッチ from machine import PWM from Sensor_CLED import * from led8x8LedNum import * def makePwm(gpio, freq, duty16): pwm = PWM(gpio) pwm.freq(freq) pwm.duty_u16(duty16) def makeIndi(): val = True def closure(timer): nonlocal val CLed.setIndi(val) val = not val return closure class LedCount(): led3 = [GPIOOUT(22),GPIOOUT(26),GPIOOUT(27)] #led3/4/5 SW_CRI = 2000 CNT_MAX = 100 lled = [] def __init__(self, led): self.led = led self.isOn = False self.swCnt = 0 self.cnt = 0 def onOff(self, isOn): self.led(isOn) if self.cnt > 0: self.cnt += 1 if isOn != self.isOn: self.isOn = isOn if isOn: self.swCnt += 1 self.cnt = 1 if self.cnt > self.CNT_MAX: self.swCnt = self.cnt = 0 self.isOn = False return self.swCnt @classmethod def init(cls): for l in cls.led3: cls.lled.append(LedCount(l)) @classmethod def detect(cls, ad8): swCnt = [0,0,0] for i in range(3): isOn = ad8[3+i] > cls.SW_CRI swCnt[i] = cls.lled[i].onOff(isOn) return max(swCnt) # ***************** main ******************** if __name__ == '__main__': try: # makePwm(pwmCled_gpio, 50, 1<<15) tim2 = Timer() # ドットマトリクスLED画像表示タイマー tim2.init(freq=400, mode=Timer.PERIODIC, callback=makeWrtPic(led8)) # *********************************** # cled = CLed() Sensor.init() # print('******************* START ********************') # cled.turnOn(5) # time.sleep(1) # cled.turnOn(0) LedCount.init() lmax = 0 # last max value led_n99, led_clr = LedNum() # led_n99: 数値リスト化関数 led_n99(0) while True: Sensor.setAd() # cled.turnOn(0) # CLED(センサーのカラーLED) turn off adt = Sensor.getAd() # AD tuple(センサーの距離データ8個) cMax = LedCount.detect(adt) if cMax != lmax: led_n99(cMax) lmax = cMax except KeyboardInterrupt: print("\nCtl+C") # cled.turnOn(0) led_clr() ``` ```Python:ドットマトリクスLED数値表示ライブラリ from impQ import * from machine import Timer import time oe8 = getPinOut('OE_I8x8') fix8 = getPinOut('FIX_8x8') spi = getPinOut('SPI') # 6,7,8,9pin # ********************************* LedNum ********************************** led8 = [0 for _ in range(8)] def LedNum(): c0 = (0b01111100,0b10000010,0b10000010,0b01111100) # 0 c1 = (0b00000000,0b11111110,0b00000100,0b00000000) # 1 c2 = (0b10001100,0b10010010,0b10100010,0b11000100) # 2 c3 = (0b01101100,0b10010010,0b10010010,0b01000100) # 3 c4 = (0b11111110,0b00100100,0b00101000,0b00110000) # 4 c5 = (0b01100010,0b10010010,0b10010010,0b01011110) # 5 c6 = (0b01100100,0b10010010,0b10010010,0b01111100) # 6 c7 = (0b00001110,0b00110010,0b11000010,0b00000010) # 7 c8 = (0b01101100,0b10010010,0b10010010,0b01101100) # 8 c9 = (0b01111100,0b10010010,0b10010010,0b01001100) # 9 nLst = [c0,c1,c2,c3,c4,c5,c6,c7,c8,c9] def led8_n99(n): # max 99 global led8 if n > 99: n = 99 for k in range(2): ch = n % 10 if k == 0 else n // 10 for i in range(4): led8[k * 4 + i] = nLst[ch][i] def led8_clr(): # led clear global led8 for i in range(8): led8[i] = 0 return led8_n99, led8_clr # ********************************** wrtPic ************************************** def makeWrtPic(led): row = 0 def closure(dummy): # write picture nonlocal row oe8(True) spi.write( bytearray([led[row], ~(1 << row)]) ) # col, row fix8(True) fix8(False) oe8(False) row = 0 if row == 7 else row + 1 return closure # ********************************** main ************************************** if __name__ == '__main__': try: led_n99, led_clr = LedNum() wrtPic = makeWrtPic(led8) tim = Timer() tim.init(freq=400, mode=Timer.PERIODIC, callback=wrtPic) lst = [1,23,45,67,89] for n in lst: led_n99(n) time.sleep(3) led_clr() while True: pass except KeyboardInterrupt: print("\nCtl+C") led_clr ``` # 終わりに 非接触スイッチは自動販売機などの感染症対策だけを考えていましたが、思いついてこの実験をしました。高速スイッチの他、接点が無く機械的に壊れにくいので実用的だと思います。 非接触空間センサーを使った非接触スイッチは世界でも珍しい特徴を持ち、AIカメラより速い処理がマイコンでも実現できます。新しい技術なのでコロナで不景気の今、使って欲しいと思いますが企業とコンタクトが取れません。興味のある方はwebsiteの「お問い合わせ」メニューからご連絡下さい。特許は取らず、回路図とソフトウェアは公開しています。センサー基板は発売中です https://www.switch-science.com/catalog/6495/ 外国との競争に勝つには新しい物を考え創るしかありません。非接触空間センサーは魔法をヒントに発明したSFプロトタイピングです。これからも魔法のような斬新な装置を研究しご紹介したいと思います。