3duilabのアイコン画像

透明OLEDと非接触センシング

3duilab 2021年07月09日に作成  (2021年07月09日に更新)

透明OLEDと非接触センシング

フォトリフレクタ方式の非接触空間センサーを透明なOLEDディスプレイの下からセンシングすると未来デバイスのような雰囲気で面白いのではないかと思っていました。

ツイッターで見たOLED画像をヒントにネットで検索すると購入できたので早速実験してみました。

デモ動画

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

ハードウェア

配線図
※UART: Serial (TX, RX, GND)

非接触センサー

コントローラ:Raspberry pi pico
website:https://interactive-hand-sensor.com/root/

OLEDディスプレイ

コントローラ:arduino mega
website:https://www.sparkfun.com/products/15079

動作

  1. 非接触センサーの位置と値をuartで送信
  2. OLEDディスプレイは受信した位置※の数値を表示
  3. OLEDディスプレイの数値を一定時間後に消す
    ※位置は2箇所(0,1)だけ

全体図

ソフトウェア

非接触センサー(Raapberry_pi_pico)

from machine import PWM, UART from Sensor_CLED import * uart = UART(0, baudrate=57600, tx=Pin(16), rx=Pin(17)) def makePwm(gpio, freq, duty16): pwm = PWM(gpio) pwm.freq(freq) pwm.duty_u16(duty16) makePwm(pwmCled_gpio, 50, 1<<15) # set pwm def makeIndi(): val = True def closure(dummy): nonlocal val CLed.setIndi(val) val = not val return closure indi = makeIndi() tim = Timer() tim.init(freq=3, mode=Timer.PERIODIC, callback=indi) def makeEla(): val = True def closure(): nonlocal val rev = val val = False return rev def setVal(dummy): nonlocal val val = True return closure, setVal ela, elaSet = makeEla() # elapsed time tim1 = Timer() tim1.init(freq=5, mode=Timer.PERIODIC, callback=elaSet) def getUartLst(lst): CRI_UART = 18 MAX_SIZE = 511 ma = max(lst) if (ma < CRI_UART): return None idx = lst.index(ma) if ma > MAX_SIZE: # ma:9bit ma = MAX_SIZE ch0 = 0x80 | ((idx) << 4) # 1@@@ __$$ @:sel, $:b0(2bit) ch0 |= (ma >> 7) ch1 = ma & 0x7f # 0&&& &&&& &:b1(7bit) # print(ma, hex(ch0), hex(ch1)) return [ch0, ch1] # ***************** main ******************** if __name__ == '__main__': cled = CLed() Sensor.init() # *** initialize Sensor *** print('******************* START ********************') cled.turnOn(5) time.sleep(1) cled.turnOn(0) while True: Sensor.setAd() #cled.turnOn() if ela(): lst = Sensor.getAdLst() uLst = getUartLst(lst) if uLst is not None: uart.write(bytearray(uLst))

OLEDディスプレイ(arduino_mega)

#include <WiseChipHUD.h> WiseChipHUD myHUD; const int SHOW_MS = 100; const int sw = 52; // #include "Timer.h" // Timer t; void setup() { Serial.begin(57600); // opens serial port, sets data rate to 9600 bps Serial.println("hello"); myHUD.begin(); clearOLED(); pinMode(sw, INPUT_PULLUP); } void display() { countUp(); showAll(); delay(2000); clearOLED(); } byte sel, b0, b1; // unsigned long lastChange; void loop() { if(!digitalRead(sw)) { display(); sel = 0xff; // sel is not set } if (Serial.available()>0) { char chr = Serial.read(); if (chr & 0x80) { // 1@@@ __$$ @:sel, $:b0(2bit) sel = (chr >> 4) & 0x07; b0 = chr & 0x03; } else if(sel != 0xff){ // 0___ ____ b1(7bit) b1 = chr & 0x7f; oledOnOff(); } } clearChk(); // t.update(); // Must be called from 'loop } int get0_199() { // int a0 = ((b0 << 7) | b1); int rev = int(((b0 << 7) | b1) * 0.389) + 1; // int rev = int( int((b0 << 7) & b1) * 0.78 + 1); // 255->199(max) Serial.write(b0); Serial.write(b1); Serial.print(rev); return rev; } const int STAMP_SIZE = 2; unsigned long stamp[STAMP_SIZE] = {0}; void (*clearFP[STAMP_SIZE])() = {clear0, clear1}; void oledOnOff() { // Serial.write(sel); // Serial.write(b0); // Serial.write(b1); if (sel == 0) { // /************************* Compass Group *************************/ // myHUD.compassCircle(9); // 0 = All Off; 1-8 = All Off Except Selected; 9 = All On; 10-17 = All On Except Selected // myHUD.compassArrows(9); // 0 = All Off; 1-8 = All Off Except Selected; 9 = All On; 10-17 = All On Except Selected myHUD.setHeading(get0_199()); // Max 199 stamp[0] = millis(); // t.after(SHOW_MS, clear0, (void*)0); } if (sel == 1) { // /************************* Radar Detector Group *************************/ // myHUD.radarDetector(8); // 0 = No Radar Gun Icon; 1 = Radar Gun Only; 2-8 = Distance Meter // myHUD.radarDistanceUnits(1); // 0 = Blank; 1 = "m" myHUD.setRadarDistance(get0_199(),0); // Max 999 stamp[1] = millis(); // t.after(SHOW_MS, clear1, (void*)0); } } void clearChk() { unsigned long nowTime = millis(); for (int i=0; i<STAMP_SIZE; i++) { if (nowTime - stamp[i] > SHOW_MS) (*clearFP[i])(); } } void clearOLED() { myHUD.clearAll(); // Clears all of the segments } void clear0() { // myHUD.compassCircle(0); // 0 = All Off; 1-8 = All Off Except Selected; 9 = All On; 10-17 = All On Except Selected // myHUD.compassArrows(0); // 0 = All Off; 1-8 = All Off Except Selected; 9 = All On; 10-17 = All On Except Selected // myHUD.setHeading(0); // Max 199 del_oled(0, 50); } void clear1() { // myHUD.radarDetector(0); // 0 = No Radar Gun Icon; 1 = Radar Gun Only; 2-8 = Distance Meter // myHUD.setRadarDistance(0,0); // Max 999 // myHUD.radarDistanceUnits(0); // 0 = Blank; 1 = "m" del_oled(50,90); } void del_oled(uint16_t i0, uint16_t i1) { for(uint16_t i = i0; i<i1; i++){ myHUD.AdjustIconLevel(i, 0x00); } } void showAll() { /************************* Compass Group *************************/ myHUD.compassCircle(9); // 0 = All Off; 1-8 = All Off Except Selected; 9 = All On; 10-17 = All On Except Selected myHUD.compassArrows(9); // 0 = All Off; 1-8 = All Off Except Selected; 9 = All On; 10-17 = All On Except Selected myHUD.setHeading(199); // Max 199 /************************* Radar Detector Group *************************/ myHUD.radarDetector(8); // 0 = No Radar Gun Icon; 1 = Radar Gun Only; 2-8 = Distance Meter myHUD.setRadarDistance(999,0); // Max 999 myHUD.radarDistanceUnits(1); // 0 = Blank; 1 = "m" /************************* Exit Group *************************/ myHUD.leftTunnel(1); // 0 = Blank; 1 = Tunnel; Also try leftRoad(); myHUD.middleTunnel(1); // 0 = Blank; 1 = Tunnel; Also try middleRoad(); myHUD.rightTunnel(1); // 0 = Blank; 1 = Tunnel; Also try rightRoad(); /************************* Navigation Group *************************/ myHUD.nav_Group(1); // 0 = Entire Nav Group Off; 1 = Entire Nav Group On myHUD.setTurnDistance(999,1); // Max 999 myHUD.turnDistanceUnits(2); // 0 = Blank; 1 = "m"; 2 = "km" /************************* Call Group *************************/ myHUD.setCallIcon(3); // 0 = Blank; 1 = Outline; 2 = Outline + Phone Icon; 3 = All Segments /************************* TPMS Group *************************/ myHUD.tirePressureAlert(3); // 0 = Blank; 1 = "TPMS"; 2 = "TIRE"; 3 = All Segments myHUD.setTirePressure(99,1); // Max 99 /************************* Speedometer Group *************************/ myHUD.setSpeedometer(199); // Max 199 myHUD.speedometerUnits(1); // 0 = Blank; 1 = "km/h" myHUD.setDestinationDistance(999,2); // Max 999 } void countUp() { for(int i = 0; i < 200; i += 5){ myHUD.setHeading(i); // Max 199 if (i > 33 * 1) myHUD.setRadarDistance(i,0); // Max 999 if (i > 33 * 2) myHUD.setDestinationDistance(i,2); // Max 999 if (i > 33 * 3) myHUD.setTurnDistance(i,1); // Max 999 if (i > 33 * 4) myHUD.setTirePressure(i-33 * 4,1); // Max 99 if (i > 33 * 5) myHUD.setSpeedometer(i); // Max 199 delay(80); } delay(500); clearOLED(); }

終わりに

OLEDディスプレイを通すと赤外線が減衰しセンサーの出力は1/3くらいになりますが検出できました。このディスプレイは車用のブレークアウトボードですがグラフィカルなディスプレイだともっと面白いと思いました。

子供たちのための未来志向開発をテーマにオリジナルの非接触スイッチや非接触制御という新しい分野を研究しています。
テクノロジーはwebsiteから公開しています。

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