3duilabのアイコン画像
3duilab 2022年01月28日作成 (2022年02月26日更新)
製作品 製作品 閲覧数 1679
3duilab 2022年01月28日作成 (2022年02月26日更新) 製作品 製作品 閲覧数 1679

高速非接触スイッチ_ドットマトリクスLEDでカウント

高速非接触スイッチ_ドットマトリクスLEDでカウント

概要

非接触空間センサーを使った世界でも珍しい高速スイッチの実験です。非接触スイッチは感染症対策の他、接点が無く壊れ難いので実用的です。また、ドットマトリクスLEDを使った数値表示についても詳しく解説します。
双方向ハンドセンサー https://interactive-hand-sensor.com/root/

動画

ここに動画が表示されます

※数値のちらつきはビデオのサンプリングが原因です。目視では数値がはっきり見えます。

配線図

キャプションを入力できます

フローチャート

キャプションを入力できます

ドットマトリクスLEDの数値表示

キャプションを入力できます

ドットマトリクスLEDで画像を表示する

Raspberry Pi PicoのMicroPythonでは図のように表示する8ビット数を長さ8の画像リストに保存します。次に行を変化させながら1行ずつ表示関数を実行します。この関数はSPIで2バイトの行、列データをシフトレジスタに送信し1行書き込みます。タイマー割り込みでこれを連続的にコールし、処理を自動化しています。

ドットマトリクスLEDで数値を変化させる

数値の場合は図のように4個の8ビット数で管理すると便利です。画像リストを変更し保存すると上記タイマー割り込みで00〜99の数値が表示できます。規模が小さいので関数オブジェクト(クロージャ)を使ってまとめています。

プログラム (Raspberry Pi Pico)

非接触高速スイッチ

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

ドットマトリクス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プロトタイピングです。これからも魔法のような斬新な装置を研究しご紹介したいと思います。

3duilabのアイコン画像
赤外線フォトリフレクタを利用した次世代の非接触空間センサー「双方向ハンドセンサー」を開発しています。電子回路と組込みソフトウェアのエンジニアです。事故で指先を失いました(冬山で凍傷になって)😁 動画まとめ https://imgur.com/user/3duilab/posts  website https://interactive-hand-sensor.com/root/
ログインしてコメントを投稿する