'LED'에 해당되는 글 19건

  1. 2020.10.26 Hardware | Transistor Tester 무선충전 upgrade
  2. 2020.07.19 Hardware | Petzl Tikka 2 Headlamp 수리기
  3. 2020.07.07 Hardware | 무선충전기를 만들어 보자 DIY 6
  4. 2020.04.21 Hardware | ESP32 NTP Server 이용한 시간 맞추기
  5. 2020.04.18 Hardware | ESP32 Deep sleep 알아보기
  6. 2020.04.16 Hardware | ESP32 Cryptographic HW 가속 확인해 보기 2
  7. 2020.04.11 Hardware | EPS32 PWM 기능 확인해 보기
  8. 2019.12.20 Hardware | LED 전등 수리기 - 1 7
  9. 2019.12.01 Hardware | TIL311 Hexadecimal LED display 가지고 놀아보기 - 1 2
  10. 2019.10.15 Hardware | 레트로 led 글자판 HPDL-1414 사용기 - 1

Hardware | Transistor Tester 무선충전 upgrade

|

알리에 처음 눈을 뜨기 시작하던 2017년쯤에 Transistor Tester 라는 것을 구입해서 납때해서 만들고, 잘 사용하고 있었습니다.

전자 부품 테스트 하기에는 이만한 것이 없죠.


* Hardware | Transistor Tester

https://chocoball.tistory.com/entry/Hardware-Transistor-Tester



이 테스터기에 사용되는 건전지가 9V 인데, 교체하게 되면 케이스 안에 수납되어 있는 형태라 반분해를 해야 해서 매우 귀찮습니다.

또한 새로 건전지를 구매해야 하기도 하구요.



3년 썼더니만, 올 것이 왔습니다.





1. 대세는 무선 충전


일전에 휴대폰용 무선 충전 DIY 할 때 봐 놨던 제품이 생각나, 이놈도 무선 충전으로 개조해 보기로 합니다.


* Hardware | 무선충전기를 만들어 보자 DIY

- https://chocoball.tistory.com/entry/Hardware-Wireless-Charger-DIY


동일한 날 다른 부품도 AliExpress 에서 주문 했더니만, 동시에 도착했습니다.



필요한 구성품은 다음과 같습니다.


- 무선 충전 코일 (receiver)

- 충전 5V input / 9V output 컨버터 모듈

- 3.7V 배터리




2. 무선충전 receiver 코일


자기장을 이용하여 전기를 만들어 주는 코일 입니다. 디자인이 심플하고 소형이어서 딱 사용하기 좋은 크기네요.


* DIY Qi Standard Wireless Charging Coil Receiver Module Circuit Board DIY Coil For Phone For Battery 5V 1A Fast Quick Charger

https://www.aliexpress.com/item/32995630744.html



특징은 웹사이트에서 가져왔습니다.


Features

1. Pure copper coil, high permeability, low loss, assuring fast charging.

2. Can charge the battery directly.

3. Charging current is around 5V 1A.

4. Can be directly connected to the phone's motherboard, the phone will display wireless charging.

5. Red is positive and gold is negative. The wire can be bent freely.


Specification

Material : PCB

Product Name : Wireless Charger Receiver Module

Input Power : 5V 1A or 9V 0.5A

Output : Power up to 5W

Charging Efficiency : 75%

Transmission distance : 2~8mm

Charger Applicable Form : Wireless Charger

Executive Standard : Qi Wireless Charging Standard

Product Certification : CE/FCC/ROSH

Board Size : 1.9 * 3.2cm / 0.7 * 1.3in

Copper Coil Size : 4.1 * 2.9cm / 1.6 * 1.4in

Cable Length : 5cm / 2.0in

Weight : approx. 6g


Note

Wireless charging = transmitter + receiver (both can be charged together)

1. There is a "charger" (i.e. coil patch) : If your phone has a built-in "receiver", or you have already purchased a "receiver" in another home, then you only need to buy a "transmitter" Charging.

2. There is a "generator" (i.e. the base) : If you have already purchased the "transmitter", then you can just recharge by purchasing the "receiver".


Package List

1 * Charger Receiver Module


도착샷.



소형인지라 코일과 breakout board 가 앙증맛게 생겼습니다.



PCB 도 말랑말랑한 재질이라 여러 환경에서 사용될 수 있도록 제작되었습니다.



뒷면입니다. iPhone / Android 에 무선 충전 모듈이 없는 스마트폰에 사용할 수 있게끔 만들어져 있습니다.





3. 컨버터 모듈


충전 코일 / 배터리 등을 연결하고 9V를 출력해주는 모듈 입니다.


* Charging Step Up Booster Module Dc 5v-12v To 9v/12v For 18650 Lithium Battery Ups Voltage Protection Converter Charge Discharge

https://www.aliexpress.com/item/4000123591565.html



크기가 그리 크지 않아, Transistor Tester 밑의 공간, 즉 9V 건전지가 위치한 공간에 무리 없이 들어갈 듯.



이 부품을 선택한 이유는 5V 계열로 충전하고 / 3.7V Lithium Ion 배터리를 충방전 / 9V 출력을 내주는 기능이 모두 들어있기 때문입니다.



12V output 버전도 있지만, 9V output 버전을 구매했습니다.


1. Description

It is a UPS uninterruptible power supply control board.


2. Features

1) Support charging and discharging at the same time

2) Large current

3) Small size

4) High efficiency

5) Support short circuit protection


3. Parameters

1) Product Name : UPS Voltage Converter Module 

2) Working Voltage : DC 5.0V~12.0V

3) Output Voltage : DC 9.0V

4) Output Power : 9W

5) Support Battery(No include!) : 3.7V Lithium or polymer battery 15Ah(Max)

6) Working Temperature range : -40℃~85℃

7) Working Humidity range : 0%~95%RH

8) Size : 50*20*6.3mm


4. Using Steps

1) Connect right input voltage at input terminal.

2) Check output voltage by voltmeter and ammeter.

3) Connect battery at B+ and B-.


5. Note

1) Its max output current is 1A and can not keep output 1A.

2) The positive and negative poles of the input power supply cannot be reversed Otherwise the module will be damaged.

3) Users can install a common anode Red-Blue LED by yourself as charging indicators. Blue light indicates whether there is a load at output. Keep Red is charging. There is no battery if Red flashing. Red OFF if charged.

4) Due to the large current, it is recommended to use a thicker wire. Wire cross-section greater than 1.5 square millimeters.

5) Please read use manual and description before use.


6. Application

1) Ordinary power supply

2) Battery charger

3) Mobile power

4) Power conversion

5) Infrared alarm

6) Network equipment such as switches

7) Router

8) Battery car modification


7. Package

1) 1pc UPS Voltage Converter Module


이놈도 다른 부품 도착할 때 같이 왔네요.



알리에서 전자 부품이 도착하는 평범한 모습.



깔끔한 PCB.



전압 control 및 안정용 IC chip 들이 보입니다.



입력부와 출력부 등에는 코일 부품으로 전압 제어용 인덕터와 IC 들이 달려 있습니다. 정전압 다이오드 등도 보이네요.



왼쪽 부분에 LED1 으로 표시된 곳이 상태 indicator 용 LED 가 위치하는 듯 합니다만, 3 pin LED 는 동봉되어 있지 않았습니다.

찾아보니, 3-pin LED 는 + 또는 - 를 공유하는 LED 2 개가 하나로 되어 있다고 하네요.


* LED pinouts – 2, 3, 4-pin and more

http://lednique.com/leds-with-more-than-two-pins/



0805 SMD LED 를 사용하면 될 듯 하군요. 마침 자가 arduino 만들어 보려고 구입해 놓은 0805 SMD LED 가 있으니 활용해 보면 되겠습니다.

SMD LED 실장시에는 극성을 조심해야 합니다.



밑의 사진처럼 Red / Green LED 를 이쁘게 잘 붙였습니다.





4. 배터리


3.7V Lithium Ion 배터리는, 방사능 측정기 DIY 때, battery upgrade 하고 남은 것을 활용합니다.

집안에서 3년동안이나 굴러다니고 있었는데, 잘 되었어요.


* Hardware | bGeigie Nano 의 battery 를 업그레이드 해보자

- https://chocoball.tistory.com/entry/Hardware-bGeigie-Nano-battery-upgrade



Lithium Ion / Polymer 배터리의 표기들이 3.7V / 4.2V 두 가지고 있는데, 이는 동일한 스펙이고 다른건 아니라 합니다.

3.7V 는 평소 voltage 이고, 4.2V 는 peak voltage 라고 하네요.


* Voltages | adafruit

https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages


For example, almost all lithium polymer batteries are 3.7V or 4.2V batteries. What this means is that the maximum voltage of the cell is 4.2v and that the "nominal" (average) voltage is 3.7V.


그 사이 한번도 충/방전을 안했는데도 3년동안 voltage 가 변하지 않았네요. 용량도 그대로 였습니다.





5. 연결


충전용 receiver coil 과 converter module 을 납땜하고 무선 충전 해 봅니다.

충전쪽으로 가는 전압은 약 4V.



출력은 9.19V 나와서 정상 동작 하네요.



이제 테스터기 본체를 분리하고, 9V 연결선을 제거.



Converter module 에서 본체로 가는 선은 조금 굵은 것을 사용하고자, 예전에 구입한 충전 connector 에서 적출한 선을 사용 했습니다.



배터리는 선이 짧아서 연장해주고 쇼트를 막기 위해 수축 튜브로 마무리.



전원 스위치 ON 하니, converter module 에 납땜한 녹색 0805 SMD LED 이 켜지면서 전원이 들어 옵니다.



전압도 문제 없습니다.



충전하면서 전원을 켜도 잘 작동 하네요.



충전과 출력이 동시에 되고 있다는 것을 알려주는 LED 가 이쁘게 잘 들어오니, 상태 확인이 쉽습니다.





6. 조립


기판 뒷면에 배터리와 PCB 가 들어가게 되는데, 쇼트 방지를 위해 쿠션을 제단하여 깔아 줍니다.



밑판에 캡톤 테이브로 코일과 회로를 고정해 줍니다.



Converter module 은 그 크기가 테스터기 아래부분의 뒷면에 맞춤형 처럼 들어 맞네요.



투명 아크릴 케이스이고, 캡톤 테이프가 노란색을 띄어서 그런지 멋지게 보입니다.



전원을 키면 사용중이라는 것을 LED indicator 로 쉽게 알 수 있습니다.



이번 프로젝트는 구상한 대로, 만족스러운 결과가 나와서 기분이 좋습니다.





7. 실사용


조립 후, 충전기 위에 올려 놓으면 충전 불이 들어오면서 문제 없이 충전 됩니다.

충전이 완료 되면 모든 불이 꺼집니다.



충전 중에 전원을 키면, 역시나 동시에 불이 켜지구요.



전체 샷은 이렇게 보여요.





8. 미세 전류


대기상태가 되면, Green LED 가 아주 조그맣게 깜빡입니다.



아마도 확인 전류인 듯 한데, 미세하게 깜빡이면서 소비되는 전류가 싫다면 LED 를 제거하면 되겠죠.

그래도 사용 중에 불이 들어오는 모습이 멋져 그냥 놔두기로.




FIN


And

Hardware | Petzl Tikka 2 Headlamp 수리기

|

후지산 등반에 사용하기 위해 구입한 헤드램프가 Petzl Tikka 2 입니다.

등반 기구의 명가 Petzl 이라는 브렌드를 처음 알게 된 계기였죠. 2012년에 구입하여, 그 해 10월에 사용했습니다.




1. 고장


그 후, 한국의 서해 바다에서 보름달 뜬 어느 여름날 저녁, 우렁잡이 때 신나게 사용 했더랬습니다.

워낙 잘 만들어진 덕에 갯벌에 스믈스믈 다니는 우렁들이 정말 잘 보였습니다.


단, 이 때 바닷물이 조금 들어갔는지, 다음에 사용하려 하니 불이 켜지지 않더군요.





2. 분해


자세히 살펴 보니, 침수로 인한 부식이 원인인 듯 했습니다.

분해해 봅니다. (2017년)



특이하게도 별나사군요.



마침, 예전에 구입해 놓은 별나사용 드라이버가 있어서 진가를 발휘합니다.



어이쿠야... 삭을 대로 삭았군요. 소금물에 부식되다 보니, 흰 가루들도 나옵니다.



별나사 두 개를 풀고, 케이스와 분리된 사진.



반사판과 건전지 연결 플레이트를 제거합니다.





3. 메인 기판


이제 기판을 분리할 차례 입니다.



요리조리 살펴 봅니다. 혹시 건전지로부터 기판으로 가는 부분 단선이 의심되어 납땜을 추가해 봅니다만, 실패.



자세히 들여다 봅니다. 생각보다 부식이 심하군요.



윗쪽 양쪽에 땜질 되어 있는 납을 제거하면 건전지 케이스로부터 기판이 분리 됩니다.



코팅도 벗겨지고 난리도 아닙니다. 뒷면도 만만치 않군요. 



드디어 분리가 완성되었습니다.





4. Petzl 에 문의


기판이 이렇게 된 이상, PCB 패턴이 나갔을 확율이 높아서, PCB 도면을 얻을 수 있지 않을까 생각해 봅니다.

Petzl 한국 지사에 메일로 문의 넣어 봅니다.



그렇겠죠. 기밀 문서라 줄 수 없다고 합니다. 충분히 이해하 갑니다.




5. 부식 패턴 수리


건전지를 넣으면, 완벽하게 켜지지는 않지만, 살짝 전기가 들어오는 부분이 보입니다. 아마도 어딘가 합선.

그리고 제일 왼쪽 LED 는 완전히 죽었군요.



일단 제일 왼쪽에 해당하는 LED4 를 제거해 보기로 합니다.



납 흡입기로 이쁘게 제거한 모습.



패턴 확인을 위해, 앞면을 고운 사포로 살짝 갈아 봅니다.



패턴 하나는 완전히 끊어졌군요. 그 옆자리의 LED3 까지 침식이 된 것 같습니다.



LED3 까지 제거하고 부식된 부분을 갈아보니, 확연히 들어나는 패턴 끊김. 빨간 선으로 표시해 봤습니다.



선 연결 상, LED3 / LED4 는 같은 극끼리 연결되면 문제 없으므로, 아래와 같이 뒷면에서 리드선으로 연결해 줍니다.



패턴을 연결하고 +/- 에 3.3V 를 연결하니, 4개 모두 켜집니다~!



이로써 수리가 완료되면 좋겠지만, LED 들이 켜진 것은 단순히 +/- 에 전기를 넣어서 그런 것이고, 정상 동작은 아닙니다.

정상 동작은 스위치를 누르면, 불 / 약한 불 / 깜빡이 / 소등 순으로 바뀌는 기능이 되살아 나는 것이 수리의 완료가 되겠죠.




6. 리드선 구매


수리 시, 여러 장면에서 필요한 리드선을 이참에 구입하기로 합니다. 정식 명칭은 Jumper Wire.


* PCB Jumper Wire

http://www.rusander.com/pcb-jumper-wire/pcb-jumper-wire/



이번 수리에 사용된 리드선은 아래와 같이 구매했습니다.


* IMC Hot P/N B-30-1000 30AWG 8-Wire Colored Insulation Wrapping Cable

https://www.aliexpress.com/item/32633773374.html



무난하게 도착.



이 정도 굵기를 AWG 30 이라고 하는 군요.



단색도 있지만, 여러가지 색이 섞인 제품으로 구매했습니다.





7. LED 교체


기존에 달린 LED는 단순한 백색등이라 재미가 없습니다. 



보통이 6000K 정도 하니, 백열 전구 효과가 나는 3000K 로 바꿔 주기로 합니다.



일단, 기존 LED 의 전압을 측정해 봅니다.

PCB 기판에 붙어 있는 상태로는 측정이 되질 않는군요.



하나를 분리하여 테스터로 측정해 봅니다. 2.68V 나오네요. 일반적으로



알리에서 Warm White 를 구매합니다.

이 헤드램프 수리를 위해서 LED 종류에 대한 조사도 오랜 동안 진행했습니다.


* Hardware | LED 구매하기

https://chocoball.tistory.com/entry/Hardware-LED-buy


최종적으로 아래 제품을 구입.


* Smart Electronics 100pcs/lot F5 Super Bright 5MM Round Warm White Transparent LED Light Lamp Emitting Diode High Quality
    - https://www.aliexpress.com/item/32597841882.html



기존에 달려 있는 LED 와 비교해 보면, 그 색감 차이를 알 수 있습니다.



헤드램프의 특성 상, 직진성이 더 강한 것을 구입하려 했으나, 기존의 둥근 모양이 가장 직진성이 좋다고 합니다.

이론적인 부분은 위에서 소개한, 저의 다른 글을 얽어 주세요.



LED 를 교체.



사진에서는 오른쪽 두 개를 교체했습니다. 내부 모양이 살짝 다르네요.





8. 스위치 교체


제대로 동작하지 않는 부분을 따라가다 보니, 스위치까지 오게 되었습니다.



살짝 힘을 주니, 그냥 바스라 지는군요. 윗 사진에서 보이 듯, 스위치 안쪽이 완전 삭아버렸습니다. 교체만이 답.



열을 가하면서 분리 했으나, 가운데 패턴이 같이 떨어져 나와 버렸네요.

그래도 괜찮습니다. 패텬을 따라가 보면 보이는 오른쪽 구멍과 연결하면 되니까요.



알리에서 폭풍 검색을 했으나 찾을 수 없었고, eBay 에서 비슷한 제품을 하나 찾았습니다.


* 10Pc 12V 0.5A Momentary Tactile Tact Push Button Switch 3*4*3mm 3 Pin SMD SMT
    - https://www.ebay.com/itm/372278396344



사양은 다음과 같습니다.



소개된 제품 사진상으로 보면 동일한데요. 제품이 도착해 봐야 알겠습니다.



eBay 는 판매자 관리를 해서 그런지, 배송 상황을 잘 파악 할 수 있습니다. 그래도 결국 중국 판매자군요.



문제 없이 도착.



깔끔한 제품이네요.



원래 있던 부품과 비교해 보니, 100% 동일 했습니다. 이렇게 맞추기 쉽지 않은데, 행운인 듯.



잘 납땜 해 줍니다.



그리고, LED 도 부착.





9. 유리섬유 리무버


이미 사포로 PCB를 갈아 냈지만, 사실 연필형 유리섬유 리무버로 긁어 내는게 좋다고 하네요. 구매해 봅니다.


* Practical Watch Rust Removal Brush Pen Glass Fiber / Brass / Steel Clean Scratch Polishing Tool Watch Parts Repair Tool New

https://www.aliexpress.com/item/4000410698491.html



더 비싸고 좋아 보이는 것이 있었지만, 제품의 특성을 모르는 지라, 싼 것을 구매 했습니다.



깔끔한 포장.



꼭지의 검은 플라스틱을 돌리면, 그림 그릴 때 썼던 크레파스 처럼 나옵니다.



사포 대신에 사용 했어야 하나, 이미 갈려진 상태 이므로, 이번 수리에는 사용 못해보고, 다른 PCB 기판에 사용해 봤습니다.



살살 갈리는 것이 나쁘지 않아 보입니다. 나중 수리에서 잘 사용해 봐야겠네요.




10. PCB 코팅


부식된 부분을 사포로 갈아 내면서 PCB 패턴이 노출되었습니다. 합선 등의 위험을 방지하고자 코팅을 해 줄 필요가 있지요.

솔더 마스크라고도 하네요.


* XEREDEX 10ML UV Solder Mask BGA PCB Paint Prevent Soldering Paste Flux Corrosive Curing Solder Protective Mask Inksale
    - https://www.aliexpress.com/item/32933615348.html



이번 수리를 위해, 참 여러가지 구입하게 됩니다. (싼맛에...)



갈려나간 윗 부분이나, 점퍼선으로 땜질된 부분에 바릅니다.



미세한 붓이 없으니, 나무 젓가락을 부러뜨리면 생기는 날카로운 끝 부분을 이용해서 칠했습니다.

UV 램프로 굳히게 될 때, LED 램프가 혹시나 손상될 까봐 테이핑 해 줬습니다.



집에 굴러다니는 UV 램프로 충분히 구워 줍니다. 그리 강한 UV 램프가 아닌지라, 한 1시간 이상 구운 듯.



이쁘게 마무리 되지는 않았지만, 나름 괜찮은 결과물.



노출되는 부분 없이 잘 코팅 되었습니다.





11. 결과


3여년에 걸쳐 작업한 결과는 실패... ㅠㅠ


건전지 케이스와 결합하고 납땜 후, 테스트 해보니 전혀 불이 들어오지 않더군요.

어쩌다가 딱 한번 정상 작동 했지만, 그 때 뿐이였고, 완전히 침묵.

수차례 다시 분해하여 단자마다 새롭게 납을 먹여 보거나, 세척을 구석구석 해 주었으나, 효과는 없었습니다.


LED 테스트 시, 조금 높은 저압을 사용하여 컨트롤 chip 이 망가진 것이 아닌가 합니다. 아니면 레귤레이터.

2017년부터 수리를 진행해 오다, 여기까지 왔습니다만, 한계인 듯 하여, 여기서 멈추기로 합니다.



수리 성공했을 때를 생각하여, 정말 깨끗하게 닦아 놓은 외피 케이스 들.



이제 그만 놓아주기로 합니다. 안녕.


FIN


And

Hardware | 무선충전기를 만들어 보자 DIY

|

무선 충전 코일을 예전부터 어떻게 활용해 볼까, 여러가지 시도를 하고 있습니다.

아이폰 8 플러스 사용하면서 생각해 보니, 무선 충전이 되었네요!

바로 만들어 보기로 합니다.




1. 무선 충전 코일


거의 3년 전에 무선 코일 세트를 하나 사 놨었습니다.


* dc 12V Wireless Charging Charger Module 5V 2A Power Supply Coil for DIY Cell Phone Transmitter Module + Receiver Module

https://www.aliexpress.com/item/32717511392.html



사양은 이렇다 합니다. 기록을 위해 남겨 놓습니다.


Instruction manual:

For current wireless charging various series of small electronic products, power supply design, it has small size, extremely easy to use, high efficiency, and low price is mainly applied to mobile electronics products such as : mobile phones, game consoles, fish tank, MP3, MP4, adult products, digital cameras, electric shavers, machine learning, medical supplies and other products of underwater applications. Thanks to contactless charging power supply, make the product completely sealed, waterproof and dust proof; increase product life, easier to use.


Modules main parameters:

- Input voltage: 9 ~ 12V

- Maximum load current: 1.2A


- Receives the maximum output voltage and current: 5V / 2A

(Charging the output resistance can be set to 12V / 700mA)


- Transmitting coil size: diameter 43mm, thickness 2.3mm

- Transmitter module size: 18mm * 8.5mm * 15mm

- Receiver Module size: 10mm * 25mm * 3mm

- Receiving coil size: diameter 43mm, thickness 1.2mm

- Receive the best distance: 3 ~ 6mm


9~12V 를 입력으로 받고, 5V 출력을 내어주는 코일 쌍 입니다.

한쪽 코일에 전원을 넣어 주면, 다른 쪽 코일에 전압과 전류가 인가됩니다.


대략 회로도는 다음과 같다고 하네요. 이 것도 참고로 올려 놓습니다.





2. 코일 외관


도착샷은 찍어 놨는데 너무 오래 전이라, 어디로 갔는지 없네요.

어뎁터와 연결하기 위해 female 3.5mm jack / USB-A 을 끝단에 납땜으로 붙이고, 수축 테이프로 마무리 했습니다.



사용된 chip 들을 보면, XKT-335XKT-412 두 개가 사용되었습니다.



코일쪽으로 전원을 보내주는 OUT 이라고 표시되어 있습니다.

코일을 통해서 전기를 받아주는 쪽은, 코일 연결된 부분은 IN 이라고 표시되어 있어서 혼동되지 않습니다.



제가 구입한 제품은 XKT-412 를 사용한 제품이고, 큰 커페시터가 5개가 실장되어 있으므로, 아래 회로가 더 맞아 보입니다.





3. 기능 확인


전원은 집에 굴러다니던 9V / 500mA 를 사용했습니다.



대기전압은 1.0mV 이 나오는 군요.



무선 충전 가능한 스마트폰을 올려 놓으면 문제 없이 충전이 되네요.

다만 7.7mV 정도로 정말 천천히 충전 됩니다.



뾰롱~!





4. 설치


사용하려는 iPhone 8 Plus 는, 무선충전 코일이 기기 정 가운데에 위치하고 있습니다.



회사에 있는 노트북 세워놓는 지지대에 아이폰 충전 회로 높에로 맞춰, 캡톤 테이프를 이용하여 붙여 놓습니다.



마침 스텐드 가운데 부분이 뚫려 있어, 그 쪽으로 연결선을 빼 놓습니다.



완성!



만족스럽습니다.



잘 사용하고 있었지만, 문제점이 있습니다.


- 상시 전원을 넣어 놓으면, 코일 부분이 조금 뜨거워진 상태로 유지 됩니다.

- 이는 기기 접근을 인식하여 전류를 흘리는 것이 아니라, 계속 전류를 흘려 보내서 그런 것 같습니다.

- 퇴근 후, 주말에 화재의 위험성이 있어서 업그래이드 결정.




5. 업그래이드 부품 구매


고르고 골라서 아래 제품으로 결정했습니다.


* 1 Set 3 Coils S8 Type-c Qi Wireless Fast Charging Charger Transmitter DIY PCBA Circuit Board Qi Wireless Charging Standard

https://www.aliexpress.com/item/32957404175.html




Specification:
- 100% brand new and high quality
- Input: DC9V 1.5 ~ 2A
- Output: 9V ± 0.1V
- Charging current: 1A to 2A
- Power: 10W
- Efficiency: 73%
- Port: type-c
- Operating frequency: 110- 205KHZ
- Standards: Qi wireless charging standard
- Transmission distance: 2mm ~ 10mm
- Standby power consumption: less than 50mW
- Certification: CE / FCC, compatible with QI certification standards
- Protection: Over-temperature/Over-current 
- Indicator: bright blue light(Charging), green light(fully charge) 
- Fine workmanship and stable performance.
- Long service life.

Package included:
- 1x S8 Type-c 3 Coils Wireless Charger DIY Circuit Board



6. 업그래이드 부품 도착


2주 정도 걸려서 도착.



역시 기기 접근을 인식하고, 그에 따른 전류 컨트롤 기능이 들어가 있으므로 회로가 복잡해 졌습니다.

분명 다른 기기 OEM 으로 들어가는 제품을 외관 껍질을 벗기고 브랜드 없는 제품으로 판매하는 형식이군요.



코일은 3개가 한 묶음으로 되어 있습니다. 다만, 정 가운데에 위치시키지 않으면 충전되지 않습니다.

예상하기로는 양쪽 두 개의 코일은 충전 boost 용이 아닌가 합니다.



회로부와 코일부를 플렉서블 케이블로 연결하여, 서로 유연하게 위치를 잡을 수 있게 되어 있습니다.



테스트 해보니 잘 되네요.



한가자 아쉬운 점은 Fast Charging 이라고 표현되어 있지만, USB PD 대응한 어뎁터를 이용하자 전혀 동작하지 않았습니다.

결과적으로는 Fast Charging 은 거짓 문구 입니다. 확인해본 어뎁터는 아래 제품 입니다.


* Hardware | HP 65W USB-C 슬림 여행용 전원 어댑터 구입기

https://chocoball.tistory.com/entry/Hardware-HP-65W-USBC-slim-travel-power-adapter-buy


일반적인 USB Charger 를 사용해야만 제대로 동작합니다. 그냥 Type-C 인터페이스와 intelligent charging 으로 만족.




7. 회사 사무실에 설치


기존 것을 걷어내고 새로 받은 PCBA 를 설치합니다. 정리 그까이꺼~.



플렉서블 케이블을 잘 구부려, 앞쪽에 붙여 놓은 코일과 연결해 놓습니다.



코일을 잘 고정합니다.




8. 완료


아래는 이전 버전의 사진이지만, 동일하게 동작하므로 여기서 같이 사용 했습니다.



업그래드 버전은 상태 LED 가 붙어 있어서, 충전이 활성화 되면 파란 불빛으로 알 수 있습니다.

마침 휴대폰에 씌워진 클리어 케이스 덕에, 대충 위치한 LED indicator 를 통해 빛이 전체로 잘 퍼집니다.



업그래이드 하면서 좋아진 점은 다음과 같습니다.


- 향후 일반적으로 사용될 Type-C 를 채용

- 충전시 LED indicator 로 상태 확인 가능

- 충전하지 않을 때, 전원 차단으로 코일이 뜨거워 지지 않아 안정성 확보

- 충전 속도 향상!




Update - 20201102


완중이 되면 녹색으로 색이 바뀌며, 더 이상 충전시키지 않는 모습도 올립니다.


And

Hardware | ESP32 NTP Server 이용한 시간 맞추기

|

지금까지 ESP32 에 관한 글은 아래를 참고해 주세요.


* Hardware | ESP32 Deep sleep 알아보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Deep-sleep

* Hardware | ESP32 Cryptographic HW 가속 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-HW-acceleration

* Hardware | EPS32 PWM 기능 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-EPS32-PWM

* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32


이 글을 마지막으로 ESP32 에 대해 대략적인 내용은 얼추 확인해 본 것 같습니다.

이후에는 WiFi 이용한 활용시에는 가능한 ESP32 를 사용해 보려 합니다.




1. NTP


본 포스트는 아래 글을 참조 하였습니다.


* Getting Date & Time From NTP Server With ESP32

- https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/



NTP 서버란 인터넷에서 시간을 동기화 시켜주는 서버를 말합니다.
인증, GPS 위치와 연관된 시간 정보, 동기화와 관련된 timestamp 등, 인터넷 서비스의 거의 모든 기능들이 동일한 "시간" 정보가 필요합니다.


동일한 시간 기준으로 동작해야 하는 서비스를 위해, 인터넷에서는 NTP 라는 서비스가 지원되고 있습니다.


* Network Time Protocol

- https://en.wikipedia.org/wiki/Network_Time_Protocol


이를태면, 정확한 시간 정보를 가져올 수 있는 서버들이 존재한다는 것이죠.




2. WiFi



"인터넷" 을 통해 시간 정보를 가져와야 하므로, WiFi 등의 인터넷 연결이 필수 입니다.

ESP32 는, WiFi 연결을 위해 "WiFi.h" 라이브러리를 지원합니다. 이를 통해 쉽게 WiFi 연결을 실현해 줍니다.

지금까지 Arduino + ESP8266 에서는 AT command 를 이용하여, 하나하나 명령어를 정의해야 했었는데, 그럴 수고를 덜어줍니다.


const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";


인터넷 접속을 위한 WiFI SSID 및 비번 정의를 하면 끝 입니다. 정말로 이걸로 끝입니다.




3. NTP


NTP 서버를 통해 시간을 가져오는 소스는 다음과 같습니다.


#include "WiFi.h"
#include "time.h"

const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

void printLocalTime() {
	struct tm timeinfo;
	if(!getLocalTime(&timeinfo)) {
		Serial.println("Failed to obtain time");
		return;
	}
	Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void setup() {
	Serial.begin(115200);
	
	// connect to WiFi
	Serial.printf("Connecting to %s ", ssid);
	WiFi.begin(ssid, password);
	while (WiFi.status() != WL_CONNECTED) {
		delay(500);
		Serial.print(".");
	}
	Serial.println(" CONNECTED");
	
	// init and get the time
	configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
	printLocalTime();
	
	// disconnect WiFi as it's no longer needed
	WiFi.disconnect(true);
	WiFi.mode(WIFI_OFF);
}

void loop() {
	delay(1000);
	printLocalTime();
}


위의 소스를 각 로컬 상황에 맞게 설정해줘야 합니다.


const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;


우선, NTP 서버는 "pool.ntp.org" 로 정의 합니다. 이 FQDN 을 통해 NTP 서버를 할당 받습니다.


"gmOffset_sec" 는 GMT 기준으로 얼마나 차이나는지를 확인합니다.

한국은 그리니치 천문대 기준 9시간 추가된 시간대인, "GMT+9" 이므로 "3600 * 9 = 32400" 만큼 더해주면 됩니다.


또한, "daylightOffset_sec" 은, 서머타임 적용 지역이면, 한시간인 3600 을 적용하면 됩니다.

우리나라는 서머타임 적용은 80년대에 일시적으로 적용하고, 그 이후 사용되지 않으므로 "0" 으로 정의합니다. (옛날 사람...)


위의 내용을 적용하고 실행하면 다음과 같이 됩니다.



한국 상황에 맞게, 요일까지 정확히 표시할 수 있는 것을 확인했습니다.



FIN

ESP32 의 WiFi 구현이 얼마나 간단한지를 확인해 보기 위해 NTP 서비스를 활용해 봤습니다.
앞으로는 ESP32 를 통하여 다양한 project 를 해봐야 겠네요.

끝.


And

Hardware | ESP32 Deep sleep 알아보기

|

ESP32 는 WiFi 및 Bluetooth 에 추가하여 Dual-core CPU 에 sensor 등, 작은 사이즈에 많은 기능을 내포하고 있습니다.

본격적인 IoT 생활을 위해 Arduino 보드에서 ESP32 로 넘어가는 중이라 ESP32 에 대해 공부하고 있습니다.


지금까지 작성된 ESP32 에 관한 글들은 아래 포스트들을 참고해 주세요.


* Hardware | ESP32 Cryptographic HW 가속 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-HW-acceleration

* Hardware | EPS32 PWM 기능 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-EPS32-PWM

* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32



1. Power Modes


ESP32 는 사용 전력량을 알맞게 활용할 수 있도록 5가지 Power 모드를 제공하고 있습니다. Off-Grid 에서의 활용에서는 필수겠죠.



아래 테이블은, 각 mode 들에 따른 ESP32 부위별 active / inactive 와 사용 전력 정보 입니다.


* Insight Into ESP32 Sleep Modes & Their Power Consumption
    - https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/


--------------------------------------------------------------------------------
| Power Mode  | Active                 | Inactive               | Power        |
|             |                        |                        | Consumption  |
|------------------------------------------------------------------------------|
| Active      | WiFi, Bluetooth, Radio |                        | 160 ~ 260 mA |
|             | ESP32 Core             |                        |              |
|             | ULP Co-processor       |                        |              |
|             | Peripherals, RTC       |                        |              |
|------------------------------------------------------------------------------|
| Modem Sleep | ESP32 Core             | WiFi, Bluetooth, Radio |   3 ~ 20 mA  |
|             | ULP Co-processor, RTC  | Peripherals            |              |
|------------------------------------------------------------------------------|
| Light Sleep | ULP Co-processor, RTC  | WiFi, Bluetooth, Radio |     0.8 mA   |
|             | ESP32 Core (Paused)    | Peripherals            |              |
|------------------------------------------------------------------------------|
| Deep Sleep  | ULP Co-processor, RTC  | WiFi, Bluetooth, Radio |     10 uA    |
|             |                        | ESP32 Core, Peripherals|              |
|------------------------------------------------------------------------------|
| Hibernation | RTC                    | ESP32 Core             |     2.5 uA   |
|             |                        | ULP Co-processor       |              |
|             |                        | WiFi, Bluetooth, Radio |              |
|             |                        | Peripherals            |              |
--------------------------------------------------------------------------------


사용하지 않는 부분을 죽이고 최대한 사용 전력을 아끼는 방법입니다.

사양서에는, 좀더 자세한 power mode 별 소비 전력이 안내되어 있습니다.



이번 포스트에서 집중적으로 확인해 볼 Deep sleep 에서는 CPU 를 사용하지 않고, 소전력으로 돌아가는 ULP processor 를 활용합니다.



참고고, ESP32 에서 사용되는 전력의 많은 부분은 역시 WiFi/Bluetooth 이군요.





2. RTC_IO / Touch


Deep sleep 시에 ESP32 를 깨우거나 입력을 받아들이는 pin 은 RTC_IO / Touch 핀들 입니다.

즉, 이 pin 들을 통하여 ULP co-processor 에 자극을 줘서 deep sleep 에서 깨어날 수 있도록 open 된 핀들이라고 할 수 있겠네요.

참고로 모든 Touch 핀들은 RTC_IO 핀들에 포함되어 있습니다.





3. 깨우기 - timer


마침 Examples 에 정갈하게 소스가 올라와 있으니, 이걸 이용해서 확인해 봅니다.

File > Examples > ESP32 > DeepSleep > TimerWakeup


원본 소스는 다음과 같습니다. 5초마다 깼다가 바로 잠드는 시퀀스로 짜여져 있습니다.

wakeup_reason 을 통해, timer 외에 touch 나 external pin 에 의한 확인도 가능하게 만들어져 있네요.


/*
Simple Deep Sleep with Timer Wake Up
=====================================
ESP32 offers a deep sleep mode for effective power
saving as power is an important factor for IoT
applications. In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

This code displays the most basic deep sleep with
a timer to wake it up and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli - cherukupallip@gmail.com
*/

#define uS_TO_S_FACTOR 1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");

  /*
  Next we decide what all peripherals to shut down/keep on
  By default, ESP32 will automatically power down the peripherals
  not needed by the wakeup source, but if you want to be a poweruser
  this is for you. Read in detail at the API docs
  http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html
  Left the line commented as an example of how to configure peripherals.
  The line below turns off all RTC peripherals in deep sleep.
  */
  //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");

  /*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}


Serial Monitor 를 통해, 5초마다 깨어나는 상황을 확인 할 수 있습니다.





4. 깨우기 - touch pin


터치센서를 통하여 잠에서 깨우는 소스 입니다. 이것도 마찬가지로 기본 제공되는 Example 을 이용하여 확인해 봤습니다.


File > Examples > ESP32 > DeepSleep > TouchWakeup

/*
Deep Sleep with Touch Wake Up
=====================================
This code displays how to use deep sleep with
a touch as a wake up source and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli - cherukupallip@gmail.com
*/

#define Threshold 40 /* Greater the value, more the sensitivity */

RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

/*
Method to print the touchpad by which ESP32
has been awaken from sleep
*/
void print_wakeup_touchpad(){
  touchPin = esp_sleep_get_touchpad_wakeup_status();

  switch(touchPin)
  {
    case 0  : Serial.println("Touch detected on GPIO 4"); break;
    case 1  : Serial.println("Touch detected on GPIO 0"); break;
    case 2  : Serial.println("Touch detected on GPIO 2"); break;
    case 3  : Serial.println("Touch detected on GPIO 15"); break;
    case 4  : Serial.println("Touch detected on GPIO 13"); break;
    case 5  : Serial.println("Touch detected on GPIO 12"); break;
    case 6  : Serial.println("Touch detected on GPIO 14"); break;
    case 7  : Serial.println("Touch detected on GPIO 27"); break;
    case 8  : Serial.println("Touch detected on GPIO 33"); break;
    case 9  : Serial.println("Touch detected on GPIO 32"); break;
    default : Serial.println("Wakeup not by touchpad"); break;
  }
}

void callback(){
  //placeholder callback function
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32 and touchpad too
  print_wakeup_reason();
  print_wakeup_touchpad();

  //Setup interrupt on Touch Pad 3 (GPIO15)
  touchAttachInterrupt(T3, callback, Threshold);

  //Configure Touchpad as wakeup source
  esp_sleep_enable_touchpad_wakeup();

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This will never be reached
}


GPIO15 번을 손으로 터치하면 깨어납니다.



Serial Monitor 에서도 touch pin 에서의 감지를 알려 줍니다.





5. 깨우기 - EXT(0) external wake ups


Pin 의 HIGH/LOW 입력을 통하여 깨우는 방법 입니다.


File > Examples > ESP32 > DeepSleep > ExternalWakeup


/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots

This code is under Public Domain License.

Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor

NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.

Author:
Pranav Cherukupalli -cherukupallip@gmail.com
*/

//#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
#define BUTTON_PIN_BITMASK 0x16 // 2^4 in hex

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
//  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_4,1); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}


원본 소스는 GPIO_33 번을 활용하게 되어 있으나, 핀 배열상 GPIO_4 로 바꾸도록 수정 해 봤습니다.

Linux 의 파일 시스템에서, 쓰기/읽기 정의에 사용되는 bit mask 방법을 사용하는 군요.


2^(pin 번호) 를 16진수로 표현하여 정의합니다. GPIO_4 이므로, 우선 2 의 4승 계산은 다음과 같습니다.


2^4 = 16



위의 결과를 16진수로 변경해야 합니다. 아래 사이트의 converter 를 이용하면 편합니다.


* Decimal to Hexadecimal converter
    - https://www.rapidtables.com/convert/number/decimal-to-hex.html



최종적으로 2^4 = 16 > 10 (Hexadecimal) 가 됩니다.


...

//#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
#define BUTTON_PIN_BITMASK 0x10 // 2^4 in hex

...

//  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_4,1); //1 = High, 0 = Low

...


BITMASK 값과 ext0GPIO_NUM_4 로 바꾸어 주면 정의가 완료 됩니다.
회로를 아래처럼 꾸며, 스위치를 누르면 깨어나는 방법입니다.


실제 사진은 다음과 같습니다.



정상 작동 되는군요.





6. 깨우기 - EXT(1) external wake ups


외부 입력을 통한 방법은 위의 EXT(0) 와 같으나, 이번에는 두 개의 스위치를 이용하는 방법 입니다.


/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots
 
This code is under Public Domain License.
 
Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor
 
NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.
 
Author:
Pranav Cherukupalli - cherukupallip@gmail.com
*/
 
#define BUTTON_PIN_BITMASK 0x8004 // GPIOs 2 and 15
 
RTC_DATA_ATTR int bootCount = 0;
 
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;
 
  wakeup_reason = esp_sleep_get_wakeup_cause();
 
  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}
 
/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
  int GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println((log(GPIO_reason))/log(2), 0);
}
   
void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor
 
  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
 
  //Print the wakeup reason for ESP32
  print_wakeup_reason();
 
  //Print the GPIO used to wake up
  print_GPIO_wake_up();
 
  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
  //esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_15,1); //1 = High, 0 = Low
 
  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
 
  //Go to sleep now
  Serial.println("Going to sleep now");
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}
 
void loop(){
  //This is not going to be called
}


여기서의 포인트는, 입력을 받는 복수의 GPIO 번호를 더해서 BITMASK 를 구하는 것 입니다.

사용된 GPIO 정보는 2번과 15번 입니다.


GPIO_2 + GPIO_15 > 2^2 + 2^15 = 32772



32772 의 16진수는 8004 입니다.



원본 소스에서 아래처럼 GPIO 의 BITMASK 변경과, 어떤 GPIO 가 눌렀는지의 표시, 그리고 EXT1 을 정의해 줍니다.


...

#define BUTTON_PIN_BITMASK 0x8004 // GPIOs 2 and 15
...

/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
  int GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println((log(GPIO_reason))/log(2), 0);
}
  
...

  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

...


회로는 다음과 같이 스위치를 연결 했습니다. EXT0 와 다른 것은 복수 (두 개) 의 스위치를 입력받게 하는 것 입니다.



Serial Monitor 의 결과는 다음과 같아요. 어느 GPIO 핀에서 입력 받았는지를 표시해 줍니다.





7. 전류 확인 - Deep sleep


실재로 전류 변화가 있는지 확인해 봤습니다.



음... 그리 많이 차이나지 않군요.

Examples 에서 제공되는 기본 소스는 Wake up 만 확인하는 소스이지, 계산을 시키거나 하는 것이 아니라서 그런 것 같습니다.





FIN


배터리를 가지고 동작하는 장비들은 필수로 가지고 있어야 할 Power mode 들, 특히 Deep sleep 에 대해 알아 봤습니다.

전력 소비가 가장 심한 WiFi/Bluetooth 부분을 어떻게 활용하면서 운용해야 하는지를 많이 고민해야 할 것 같네요.


- WiFi/Bluetooth 연결 정보는 연결 실패 exception 이나 스케줄에 따라 실시

- 가능한 정보는 memory 에 저장하여 꺼내 쓰는 방식으로

- 배터리 방전 threshold 값을 모니터링 하고, 일정 값 이하로 내려가면 지속적인 alert 발생

- WiFi/Bluetooth 에 사용되는 전류량을 컨트롤 하여, 근거리 통신 -> 중거리 -> 장거리 통신으로 연결하게끔 구성

- DTIM (Delivery Traffic Indication Message) beacon mechanism 등을 활용

- 등등...



And

Hardware | ESP32 Cryptographic HW 가속 확인해 보기

|

ESP32 에 관한 글들은 아래 링크들을 참고해 주세요.


* Hardware | EPS32 PWM 기능 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-EPS32-PWM

* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32



1. Cryptographic Hardware Acceleration


한 13여년 전에 웹 서비스 구축 시, HTTPS (SSL) 처리에 CPU 연산을 너무 많이 사용해서 골치가 아팠던 경험이 있습니다.

당시에는 NIC 에 붙어있는 Intel 칩에서 SSL 가속 처리를 못해줘, OS 에서 처리하다 보니 CPU 들이 죽어 나갔죠.


막 HW 가속기 (PCI daughter card 형식) 들이 등장하기도 했습니다만, 어디까지나 실험적인 제품들이었고, OS 와 HW 특성을 많이 타다 보니 PoC 단계에서도 그닥 실효를 거두지 못했었습니다.


암호 연산에 대해서는 요즘 NIC 나 CPU 자체적으로 전용 명령어 set을 가지고 지원하는 시대이다 보니, 예전같은 걱정은 말끔히 사라졌네요.


근래에 출시된 ESP32 에도, 이 암호 연산용 HW 가속 기능이 내장되어 있습니다!

다이어그램 상, SHA / RSA / AES / RNG 등이 있네요.



사양서에도 이 HW Accelerator 에 대한 안내가 되어 있습니다.



Cryptographic hardware acceleration

- AES, SHA-2, RSA, elliptic curve cryptography (ECC), random number generator (RNG)


이번 글은 위의 HW Accelerator 의 몇 가지 기능 중, ESP32 의 hardware AES 에 대해 알아보고자 합니다.




2. AES


미국 정부가 1990년 후반까지 사용하고 있던 DES 암호화 기법이, 약 30대 정도의 PC 를 가지고 뚫리면서, 새로운 암호화 기법을 찾게 됩니다. 공모 결과 AES 가 채택되면서 유명해진 암호화 기법이에요.


AES 는 "Advanced Encryption Standard" 의 약자로 cryptographic symmetric cipher algorithm 을 기반으로 encryption 과 decryption 양쪽에 사용될 수 있는 장점을 가지고 있습니다.

참고로 아래 두 가지의 parameter 를 필요로 합니다.


IV (Initial Vector)

맨 처음 block 을 XOR 처리를 할 때, 덮어 씌우는 data block 이 존재하지 않습니다. 이를 보충해 주기 위한 인위적인 블럭이 IV 입니다.


Encryption Key

암호화 / 복호화에 사용되는 고유의 키 입니다.



너무 자세한 설명에 들어가면, 저의 지식이 바닦 치는 것이 보이기에 여기서 그만 합니다.

인터넷에 관련된 문서 및 동영상들이 어마어마 하니, 자세히 공부해 보고 싶으신 분을 넓은 인터넷의 세계로...




3. Software AES - ESP32


HW 가속을 시험해 보기에 앞서, AES 를 소프트웨어적으루 구현해본 분이 계셔서 따라 해봤습니다.


* AES Encryption/Decryption using Arduino Uno
    - https://www.arduinolab.net/aes-encryptiondecryption-using-arduino-uno/


우선 필요한 것은, Spaniakos 라는 분이 만드신 AES 라이브러리를 설치해 줍니다. 아래 Github 에서 라이브러리를 다운 받습니다.


* AES for microcontrollers (Arduino & Raspberry pi)
    - https://github.com/spaniakos/AES



그리고, Arduino libraries 폴더에 심어 놓으면 됩니다.



기본 준비가 되었으니, ESP32 에서 AES-CBC 방식의 암호화/복호화를 실행 해봅니다.


/*------------------------------------------------------------------------------ 
Program:      aesEncDec 
 
Description:  Basic setup to test AES CBC encryption/decryption using different 
              key lengths.
 
Hardware:     Arduino Uno R3 
 
Software:     Developed using Arduino 1.8.2 IDE
 
Libraries:    
              - AES Encryption Library for Arduino and Raspberry Pi: 
                https://spaniakos.github.io/AES/index.html
 
References: 
              - Advanced Encryption Standard by Example: 
              http://www.adamberent.com/wp-content/uploads/2019/02/AESbyExample.pdf
              - AES Class Reference: https://spaniakos.github.io/AES/classAES.html
 
Date:         July 9, 2017
 
Author:       G. Gainaru, https://www.arduinolab.net
              (based on AES library documentation and examples)
------------------------------------------------------------------------------*/
#include "AES.h"

AES aes ;

unsigned int keyLength [3] = {128, 192, 256}; // key length: 128b, 192b or 256b

byte *key = (unsigned char*)"01234567890123456789012345678901"; // encryption key
byte plain[] = "https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-hardware-acceleration"; // plaintext to encrypt

unsigned long long int myIv = 36753562; // CBC initialization vector; real iv = iv x2 ex: 01234567 = 0123456701234567

void setup () {
	Serial.begin(115200);
}

void loop () {
	for (int i=0; i < 3; i++) {
		Serial.print("- key length [b]: ");
		Serial.println(keyLength [i]);
		aesTest (keyLength[i]);
		delay(2000);
	}
}

void aesTest (int bits) {
	aes.iv_inc();
	
	byte iv [N_BLOCK];
	int plainPaddedLength = sizeof(plain) + (N_BLOCK - ((sizeof(plain)-1) % 16)); // length of padded plaintext [B]
	byte cipher [plainPaddedLength]; // ciphertext (encrypted plaintext)
	byte check [plainPaddedLength]; // decrypted plaintext
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- encryption time [us]: ");
	unsigned long ms = micros ();
	aes.do_aes_encrypt(plain, sizeof(plain), cipher, key, bits, iv);
	Serial.println(micros() - ms);
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- decryption time [us]: ");
	ms = micros ();
	aes.do_aes_decrypt(cipher,aes.get_size(),check,key,bits,iv); 
	Serial.println(micros() - ms);
	
	Serial.print("- plain:   ");
	aes.printArray(plain,(bool)true); //print plain with no padding
	
	Serial.print("- cipher:  ");
	aes.printArray(cipher,(bool)false); //print cipher with padding
	
	Serial.print("- check:   ");
	aes.printArray(check,(bool)true); //print decrypted plain with no padding
	
	Serial.print("- iv:      ");
	aes.printArray(iv,16); //print iv
	printf("\n-----------------------------------------------------------------------------------\n");
}


암호화를 걸 평문은, 이 포스트의 URL 을 사용했습니다. :-)



암호화/복호화 잘 됩니다. 속도도 좋네요.




4. Software AES - ATmega328


비교 대상으로 궁금하여, ATmega328 을 탑재한 Arduino nano 로 동일한 계산을 시켜보기로 합니다.

다만, "AES.h" 라이브러리를 include 한다고 제대로 실행되진 않는군요.


	aes.printArray(plain,(bool)true); //print plain with no padding


이유는, ATmega328 의 라이브러리에는 위의 printArray 에서 사용하는 printf_P 함수가 없기 때문입니다. (AES.cpp 에서 정의됨)

ESP32 의 FreeRTOS 에는 C 라이브러리 기본 탑재로 문제 없이 동작하지만, Arduino nano 에서는 동작하지 않습니다.


그리하여, 이를 대신할 function 을 만들어 봤는데, 징그럽게도 동작하지 않더군요.

수많은 삽질을 통해, 배열을 다른 함수의 인자로 전달하려면 배열의 pointer 와 그 배열의 크기를 명시해야 하는 것을 알게 되었습니다.

결국 아래처럼 변경하여 Arduino nano 에서도 동작을 성공 시켰습니다.


...

	showArray(iv, array_size_iv, 1);

...

void showArray (byte *result, int array_length, int hex_conv) {
	for (int i=0; i < array_length; i++) {
		if (hex_conv) {
			Serial.print(result[i], HEX);
		} else {
			Serial.print((char)result[i]);
		}
	}
	Serial.println();
}


최종 소스는 다음과 같습니다.


#include "AES.h"

AES aes ;

unsigned int keyLength [3] = {128, 192, 256}; // key length: 128b, 192b or 256b

byte *key = (unsigned char*)"01234567890123456789012345678901"; // encryption key
byte plain[] = "https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-hardware-acceleration"; // plaintext to encrypt

unsigned long long int myIv = 36753562; // CBC initialization vector; real iv = iv x2 ex: 01234567 = 0123456701234567

void setup () {
	Serial.begin(115200);
}

void loop () {
	for (int i=0; i < 3; i++) {
		Serial.print("- key length [b]: ");
		Serial.println(keyLength [i]);
		aesTest (keyLength[i]);
		delay(2000);
	}
}

void aesTest (int bits) {
	aes.iv_inc();
	
	byte iv [N_BLOCK];
	int plainPaddedLength = sizeof(plain) + (N_BLOCK - ((sizeof(plain)-1) % 16)); // length of padded plaintext [B]
	byte cipher [plainPaddedLength]; // ciphertext (encrypted plaintext)
	byte check [plainPaddedLength]; // decrypted plaintext
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- encryption time [us]: ");
	unsigned long ms = micros ();
	aes.do_aes_encrypt(plain, sizeof(plain), cipher, key, bits, iv);
	Serial.println(micros() - ms);
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- decryption time [us]: ");
	ms = micros ();
	aes.do_aes_decrypt(cipher,aes.get_size(),check,key,bits,iv);
	Serial.println(micros() - ms);
	
	Serial.print("- plain:   ");
	//aes.printArray(plain,(bool)true); //print plain with no padding
	int array_size_p = sizeof(plain);
	showArray(plain, array_size_p, 0);
	
	Serial.print("- cipher:  ");
	//aes.printArray(cipher,(bool)false); //print cipher with padding
	int array_size_ci = sizeof(cipher);
	showArray(cipher, array_size_ci, 0);
	
	Serial.print("- check:   ");
	//aes.printArray(check,(bool)true); //print decrypted plain with no padding
	int array_size_ch = sizeof(check);
	showArray(check, array_size_ch, 0);
	
	Serial.print("- iv:      ");
	//aes.printArray(iv,16); //print iv
	int array_size_iv = sizeof(iv);
	showArray(iv, array_size_iv, 1);
	Serial.println("-----------------------------------------------------------------------------------");
}

void showArray (byte *result, int array_length, int hex_conv) {
	for (int i=0; i < array_length; i++) {
		if (hex_conv) {
			Serial.print(result[i], HEX);
		} else {
			Serial.print((char)result[i]);
		}
	}
	Serial.println();
}


아래는 Arduino nano 에서 실행시킨 결과 입니다.

ESP32 에서 Software 로 돌린 AES 결과와 비교시, 걸린 시간 빼곤 완벽히 동일합니다.



ESP32 vs. ATmega328 의 CPU 차에 의한 software AES 계산은 encryption = 27 배, decryption = 20 배 정도 차이 났습니다.


----------------------------------------------
| bits | ESP32 | ATmega328 | diff. (multiply)|
|--------------------------------------------|
| 128  |  159  |   4396    |       27.6      |
|      |  267  |   5388    |       20.1      |
|--------------------------------------------|
| 192  |  189  |   5156    |       27.2      | 
|      |  321  |   6392    |       19.9      |
|--------------------------------------------|
| 256  |  220  |   5964    |       27.1      |
|      |  376  |   7432    |       19.7      |
----------------------------------------------


ESP32 를 찬양하라!





5. Hardware AES - library


마지막으로 ESP32 의 HW AES 를 걸어볼 차례 입니다.

HW accelerator 의 Native library 는 아래 글에서 설명이 잘 되어 있습니다.


* AES-CBC encryption or decryption operation
    - https://tls.mbed.org/api/aes_8h.html#a321834eafbf0dacb36dac343bfd6b35d


요는 mbedtls 함수를 이용하면, HW accelerator 를 사용할 수 있게 되는군요. 키 포인트는 "mbedtls_aes_crypt_cbc" 함수가 되겠습니다.

int mbedtls_aes_crypt_cbc ( mbedtls_aes_context *	ctx,
							int						mode,
							size_t					length,
							unsigned char			iv[16],
							const unsigned char *	input,
							unsigned char *			output
)


각 변수들의 정의 입니다.


---------------------------------------------------------------------------------------------------
| Parameters | Meaning                                                                            |
---------------------------------------------------------------------------------------------------
|    ctx     | The AES context to use for encryption or decryption.                               |
|            | It must be initialized and bound to a key.                                         |
---------------------------------------------------------------------------------------------------
|    mode    | The AES operation: MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT.                     |
---------------------------------------------------------------------------------------------------
|   length   | The length of the input data in Bytes.                                             |
|            | This must be a multiple of the block size (16 Bytes).                              |
---------------------------------------------------------------------------------------------------
|    iv      | Initialization vector (updated after use).                                         |
|            | It must be a readable and writeable buffer of 16 Bytes.                            |
---------------------------------------------------------------------------------------------------
|   input    | The buffer holding the input data. It must be readable and of size length Bytes.   |
---------------------------------------------------------------------------------------------------
|   output   | The buffer holding the output data. It must be writeable and of size length Bytes. |
---------------------------------------------------------------------------------------------------


아래는 실재 구현에 도움이 될 만한 사이트들 입니다. 예제들이 설명되어 있어요.


* ESP32 Arduino: Encryption using AES-128 in ECB mode
    - https://techtutorialsx.com/2018/04/18/esp32-arduino-encryption-using-aes-128-in-ecb-mode/

* ESP32 Arduino Tutorial: Encryption AES128 in ECB mode
    - https://everythingesp.com/esp32-arduino-tutorial-encryption-aes128-in-ecb-mode/

* How to encrypt data with AES-CBC mode
    - https://tls.mbed.org/kb/how-to/encrypt-with-aes-cbc

재미 있는 것은, "mbedtls/aes.h" 의 library 도 동작하지만,

#include "mbedtls/aes.h"


"hwcrypto/aes.h" 라이브러리도 동일한 parameter 와 동작을 보여줍니다. 함수명에 mbedtls 가 붙느냐, esp가 붙느냐의 차이 뿐.


#include "hwcrypto/aes.h"


위의 두 가지 library 는 따로 설치하지 않아도 되는걸 보면, native library 이면서 서로가 copy 버전이 아닐까 하네요.




6. Hardware AES - 확인


위의 Software AES 를 Hardware AES 용으로 변환하면 되겠지만, 아직 지식이 짧은 관계로 아래 소스를 가지고 확인해 봤습니다.

* Example of using hardware AES 256 Crypto in CBC mode on the ESP32 using ESP-IDF
* cnlohr/esp32_aes_example.c

    - https://gist.github.com/cnlohr/96128ef4126bcc878b1b5a7586c624ef

#include "string.h"
#include "stdio.h"
#include "hwcrypto/aes.h"

/*
For Encryption time: 1802.40us (9.09 MB/s) at 16kB blocks.
*/

static inline int32_t _getCycleCount(void) {
	int32_t ccount;
	asm volatile("rsr %0,ccount":"=a" (ccount));
	return ccount;
}

char plaintext[16384];
char encrypted[16384];

void encodetest() {
	uint8_t key[32];
	uint8_t iv[16];
	
	//If you have cryptographically random data in the start of your payload, you do not need
	//an IV. If you start a plaintext payload, you will need an IV.
	memset( iv, 0, sizeof( iv ) );
	
	//Right now, I am using a key of all zeroes. This should change. You should fill the key
	//out with actual data.
	memset( key, 0, sizeof( key ) );
	
	memset( plaintext, 0, sizeof( plaintext ) );
	strcpy( plaintext, "https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-hardware-acceleration" );
	
	//Just FYI - you must be encrypting/decrypting data that is in BLOCKSIZE chunks!!!
	
	esp_aes_context ctx;
	esp_aes_init( &ctx );
	esp_aes_setkey( &ctx, key, 256 );
	int32_t start = _getCycleCount();
	esp_aes_crypt_cbc( &ctx, ESP_AES_ENCRYPT, sizeof(plaintext), iv, (uint8_t*)plaintext, (uint8_t*)encrypted );
	int32_t end = _getCycleCount();
	
	float enctime = (end-start)/240.0;
	Serial.printf( "Encryption time: %.2fus (%f MB/s)\n", enctime, (sizeof(plaintext)*1.0)/enctime );
	//See encrypted payload, and wipe out plaintext.
	
	memset( plaintext, 0, sizeof( plaintext ) );
	
	int i;
	for( i = 0; i < 128; i++ ) {
		Serial.printf( "%02x[%c]%c", encrypted[i], (encrypted[i]>31)?encrypted[i]:' ', ((i&0xf)!=0xf)?' ':'\n' );
	}
	Serial.printf( "\n" );
	
	//Must reset IV.
	//XXX TODO: Research further: I found out if you don't reset the IV, the first block will fail
	//but subsequent blocks will pass. Is there some strange cryptoalgebra going on that permits this?
	Serial.printf( "IV: %02x %02x\n", iv[0], iv[1] );
	memset( iv, 0, sizeof( iv ) );
	
	//Use the ESP32 to decrypt the CBC block.
	Serial.print("- decryption time [us]: ");
	unsigned long ms = micros ();
	esp_aes_crypt_cbc( &ctx, ESP_AES_DECRYPT, sizeof(encrypted), iv, (uint8_t*)encrypted, (uint8_t*)plaintext );
	Serial.println(micros() - ms);
	
	//Verify output
	for( i = 0; i < 128; i++ ) {
		Serial.printf( "%02x[%c]%c", plaintext[i], (plaintext[i]>31)?plaintext[i]:' ', ((i&0xf)!=0xf)?' ':'\n' );
	}
	Serial.printf( "\n" );
	
	esp_aes_free( &ctx );
}

void setup() {
	// put your setup code here, to run once:
	Serial.begin(115200);
	encodetest();
}

void loop() {
	// put your main code here, to run repeatedly:
}


결과는 다음과 같습니다.

위의 Software AES 와 비슷하게 결과를 내도록 소스를 만들면 확연히 비교할 수 있겠으나, 공부를 더 해야 함.


다만, 최종적인 처리 속도는 결코 아래 결과에서 변하지 않는다는 것을 여러 삽질을 통해 발견했으니 이걸로 만족.



Hardware AES 를 서포트하는 전용 명령어 set 이 최적화가 되지 않아, 이런 결과가 나온 것인지 모르겠네요.

지금으로써는 전용 accelerator 를 사용하지 않고, Software AES 를 구현하는 것이 더 속도적인 이득이 있는 듯 보입니다.


단, 여러가지 일을 동시에 처리해야 할 경우, 암호화/복호화 처리 부분만 따로 분리하여 HW accelerator 를 이용한다면, CPU 부하를 분산시켜 효율적인 활용은 가능할 것 같네요.




FIN


혹시, 위의 Hardware AES 결과가 잘못된 방법으로 검증된 것이라면 댓글로 알려주세요.


esp32_technical_reference_manual_en.pdf



Clock 사이클을 바탕으로 이론적인 계산을 해보면 68ns 레벨이라고, 아래 블로그에서 봤는데, 실측과는 많이 다르군요.


* Pwn the ESP32 crypto-core
    - https://limitedresults.com/2019/08/pwn-the-esp32-crypto-core/


Doing simple math, the HW AES-128 encryption process is 68.75ns (@160MHz).


그렇다고 합니다.


And

Hardware | EPS32 PWM 기능 확인해 보기

|

ESP32 에 관한 포스트는 아래를 참고해 주세요.


* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32




1. PWM


ESP32 에는 PWM (Pulse Width Modulation) 기능이 들어가 있습니다.

LED 의 dimming (밝기) 조절이나, LCD panel 의 색조절 등에 사용되는 기법입니다.


일전에 8x8 LED matrix 를 다양한 색을 표현하기 위해, PWM 을 구현해 주는 전용 보드를 사용해서 확인해 본 적이 있습니다.


* Hardware | 8x8 LED matrix 와 Colorduino 이용해 보기
    - https://chocoball.tistory.com/entry/Hardware-8x8-LED-matrix-Colorduino


이반적인 Arduino 에는 이 기능이 기본 내장이 아닌지라, PWM 을 구현하려면 대응 보드를 사용해야 하는 번거로움이 존재합니다.

그치만, ESP32 는 기본 내장이에요!



PWM 을 통한 활용은 LED 뿐 만 아니라, step motor 난 piezo speaker 등에서도 활용할 수 있습니다.



기본 동작은 높은 주파수를 통해, on/off 를 해주는 시간 (duty) 를 변경하면서 조절하는 방법입니다.

당연히 duty 가 길면 길수록 밝기가 세다거나, 지속적인 동작을 보여주는 원리 입니다.

LED, Step motor, 그리고 Piezo 스피커를 작동시키는 동작원리와 완벽히 같습니다.




2. 코딩


지금까지 몇 번 봐왔던 원리인지라, 바로 코딩에 들어가 봅니다. 참조한 사이트는 아래 입니다.


* ESP32 PWM Example
    - https://circuits4you.com/2018/12/31/esp32-pwm-example/


PWM 을 구현하기 위한 명령어는 라이브러리에 준비되어 있으니, 그냥 사용해 줍니다.


* ledcSetup(PWM_Channel_Number, Frequency, resolution)

- Pass three arguments as an input to this function, channel number, frequency and the resolution of PWM channel at inside the setup function only.


* ledcAttachPin(GPIO_PIN , CHANNEL)

- Two arguments. One is the GPIO pin on which we want to get the OUTPUT of signal and second argument is the channel which we produce the signal.


* ledcWrite(CHANNEL, DUTY_CYCLE)

- ledcWrite function is used to generate the signal with a duty cycle value.


ledcSetupledcAttachPin 은 setup() 에서, 실제 구동은 loop() 에서 ledcWrite 를 사용합니다. digitalWrite 와 비슷하죠.

최종적으로 ESP32 보드에 실장되어 있는 LED 를 가지고 PWM 을 확인한 코드가 아래 입니다.


// Generates PWM on Internal LED Pin GPIO 2 of ESP32
#define LED 2 //On Board LED

int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 10; // Resolution 8, 10, 12, 15

void setup() {
	Serial.begin(115200);
	pinMode(LED, OUTPUT);
	
	// configure LED PWM functionalitites
	ledcSetup(ledChannel, freq, resolution);
	
	// attach the channel to the GPIO2 to be controlled
	ledcAttachPin(LED, ledChannel);
}

void loop() {
	// PWM Value varries from 0 to 1023
	Serial.println("10 % PWM");
	ledcWrite(ledChannel, 102);
	delay(2000);
	
	Serial.println("20 % PWM");
	ledcWrite(ledChannel,205);
	delay(2000);
	
	Serial.println("40 % PWM");
	ledcWrite(ledChannel,410);
	delay(2000);
	
	Serial.println("70 % PWM");
	ledcWrite(ledChannel,714);
	delay(2000);
	
	Serial.println("100 % PWM");
	ledcWrite(ledChannel,1024);
	delay(2000);
	
	// Continuous Fading
	Serial.println("Fadding Started");
	while(1) {
		// set the brightness of pin 2:
		ledcWrite(ledChannel, brightness);
		
		// change the brightness for next time through the loop:
		brightness = brightness + fadeAmount;
		
		// reverse the direction of the fading at the ends of the fade:
		if (brightness <= 0 || brightness >= 1023) {
			fadeAmount = -fadeAmount;
		}
		
		// wait for 30 milliseconds to see the dimming effect
		delay(10);
	}
}




3. LED_BUILTIN


위의 코드를 실행하면 Serial Monitor 에서는 다음과 같이 표시됩니다.


소스에서도 알 수 있듯이, 10% > 20% > 40% > 70% > 100% 으로 LED 를 키고, 그 다음부터는 5/1024 씩 증감하면서 dimming 을 표현해 줍니다.

실제 동작 동영상은 다음과 같습니다.




4. 오실로스코프 확인


여기서 끝내면 심심하니, 실제 파형을 확인해 보려 합니다. 참고한 사이트는 다음과 같습니다.


* ESP32 PWM with Arduino IDE (Analog Output)
    - https://randomnerdtutorials.com/esp32-pwm-arduino-ide/


소스 코드는 다음과 같습니다.


// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16
const int ledPin2 = 17; // 17 corresponds to GPIO17
const int ledPin3 = 5;  // 5 corresponds to GPIO5

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
 
void setup() {
	// configure LED PWM functionalitites
	ledcSetup(ledChannel, freq, resolution);
	
	// attach the channel to the GPIO to be controlled
	ledcAttachPin(ledPin, ledChannel);
	ledcAttachPin(ledPin2, ledChannel);
	ledcAttachPin(ledPin3, ledChannel);
}

void loop() {
	// increase the LED brightness
	for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
		// changing the LED brightness with PWM
		ledcWrite(ledChannel, dutyCycle);
		delay(15);
	}
	
	// decrease the LED brightness
	for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
		// changing the LED brightness with PWM
		ledcWrite(ledChannel, dutyCycle);
		delay(15);
	}
}


3개의 LED 에 PWM 을 거는 소스 입니다.

2개 pin 에는 실제로 LED 를 연결해서 dimming 을 확인하고, 나머지 하나의 pin 에는 오실로스코프를 연결하여 파형을 확인해 봅니다.



이론과 실험이 만나는 동영상 입니다.



당연히 이렇게 될 것이라 알지만, 너무 이쁘게 그래프가 나와서 조금 놀랬습니다. Frequency 와 Duty 값이 정확하게 측정되는 군요.

ESP32 의 PWM 기능은 완벽하군요.




5. Piezo 연결


원리는 같으나, 눈으로 보면 다르게 느껴지는 Piezo 스피커도 확인해 보았습니다. 아래 링크를 참조하였습니다.


* ESP32 Arduino: Controlling a buzzer with PWM
    - https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/


PWM 동작하는 GPIO 하나 잡아서 연결하면 됩니다.



저는 piezo 를 D4 = GPIO4 에 연결했습니다.


int freq = 2000;
int channel = 0;
int resolution = 8;
  
void setup() {
	Serial.begin(115200);
	ledcSetup(channel, freq, resolution);
	ledcAttachPin(4, channel);
}
  
void loop() {
	ledcWriteTone(channel, 2000);
	for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle = dutyCycle + 10) {
		Serial.println(dutyCycle);
		ledcWrite(channel, dutyCycle);
		delay(1000);
	}
	
	ledcWrite(channel, 125);
	for (int freq = 255; freq < 10000; freq = freq + 250){
		Serial.println(freq);
		ledcWriteTone(channel, freq);
		delay(1000);
	}
}


처음에는 2000Hz 에서 duty 사이클을 10씩 증가하는 소리이고,

그 다음은 duty 를 125로 고정한 다음, 주파수만 바꿔가면서 소리를 내는 소스 입니다.





FIN


지금까지 ESP32 의 내부 기능들을 확인해 봤습니다.

확인하지 않고 남아있는 기능들이 Deep Sleep 과 Hardware Acceleration (Cryptographic) 정도가 남았네요.


And

Hardware | LED 전등 수리기 - 1

|

LED 전등에 대한 로망을 간직한 채 살고 있습니다.

얼마 전에 쓰레기장에서 수거한 버려진 LED 로 거실등을 하나 교환 했었더랬죠.


* Hardware | LED 전등 교환기

https://chocoball.tistory.com/entry/Hardware-LED-light-replace




1. 득템


어느 일요일 저녁, 쓰레기 버리로 수거장에 갔을 때 눈에 띄는 녀석 발견!



겉이 멀쩡해 보입니다.



LED 칩 계열에서 람보르기니라는 LG Innotek 이 사용된 패널!!!



2017 년산으로 그렇게 오래 된것 같지는 않네요. 출력은 50W.




2. 안정기


형광등에서는 형광등을 구동시키는 장치를 안정기라고 합니다.

LED 에서는 드라이버 또는 SMPS (Switch-Mode Power Supply) 라고 부릅니다.


LED 는 반영구적이라고 하지만, 이 SMPS 불량으로 인하여, 형광등보다 짧은 수명을 가지게 되는 경우가 허다 합니다.



수거한 LED 패널을 붙어있던 안정기로 전원을 넣어 보니 반응이 없네요.



내부를 까 봤더니, 탄 흔적이...



눈으로 확인되는 그을음 흔적으로는 퓨즈가 나갔습니다.



용량은 맞지 않지만, 다른 LED 패널에 사용된 SMPS 가 있어서 LED 패널을 확인해 보니, 잘 켜집니다.



그렇지만, 와트 수도 맞지 않는 SMPS 이다 보니, 전자파음이 꽤 들립니다.

소리도 소리이거니와, LED 칩 수명에도 좋지 않으므로, 이걸 계속 사용할 수는 없습니다.




3. 퓨즈 수리


눈으로 확인된 고장 부위가 퓨즈 이므로, 퓨즈를 교환하면 살아날 것 같아요.

버리려고 했던 다른 안정기에서 정상 퓨즈를 적출합니다.



어찌어찌 우겨넣고 연결해 줍니다. 쇼트를 방지하기 위해 퓨즈 전체를 수축 튜브로 감쌓아 줬습니다.



스위치 온! 펑~~!!!



퓨즈가 터저버렸네요...

급하게 작업하다 보니, 세척액이 남아있던 상태로 전기를 넣은 것이 원이인 듯 합니다. (잘하자...ㅠㅠ)




4. 퓨즈 구매


적출할 수 있는 퓨즈가 없어서, 이참에 구매하기로 합니다.


* Gold 1808 125V 250V AC 0451 SMD Fast blow Fuse 0.5A 0.75A 1A 2A 3A 4A 5A 6.3A 8A 10A 12A 15A 500MA 750MA 0451 ultra-rapid fuses

https://www.aliexpress.com/item/32872911147.html



기존 용량과 동일한, 2A 로 구매합니다.

예전같이 유리관이 아니라, 세라믹 케이스 안에 심을 넣은 형태도 있군요.



잊어먹고 있으니 도착했습니다.



이렇게 생겼습니다.



구매시 고민되었던 문구, Slow blow / Fast Acting.


전자 부품 보호에 민감한 경우는 "Fast Blow" 를 사용하고,

초기 전원이 일정 피크 이상 들어가야 동작하는 기기 - 모터 등 - 에는 "Slow Blow" 를 사용한다고 합니다.

흠... 모터에 Fast Blow 를 사용하면 사용할 때마다 매번 터지겠군요. 용도에 맞는 퓨즈가 있다는 사실을 처음 알았습니다.


* Slow Blow vs Fast Acting Fuse

https://electronics.stackexchange.com/questions/25055/slow-blow-vs-fast-acting-fuse




5. 바리스터


향후를 위해 SMD 버전으로 구입한 Fuse 에 다리를 만들어 줍니다.



기판에 잘 납땜해 주구요.



파워 온! ... 감감 무소식... ㅠㅠ



혹시 다른게 문제가 있나 다시 꼼꼼히 살펴 봅니다.

보호 플라스틱에 터진 괘적을 보면, 퓨즈 뿐만 아니라 바리스터 라는 부품도 함께 터진 것을 발견 했습니다.



요놈이군요. 과전류에 대한 회로 보로용으로 "바리스터 - Varistor" 라는 부품이 있다는 것을 처음 알았습니다.

그냥 모양만 다른 콘덴서인 줄...


지식IN 에서 찾아 봤습니다.


* 이 부품이 무었인가요?

https://kin.naver.com/qna/detail.nhn?d1id=11&dirId=1118&docId=64982136


ZNR 47V짜립니다.

470 숫자의 의미는 앞의 2자리는 숫자 그대로 4와 7이고

마지막 1자리 0은 곱하기를 하는 것으로

47 X 0= 47V가 전압이고

가령 471 이라면 470V 짜리가 됩니다.

밑의 숫자는 직경을 나타내는 것인데

3 인지 9인지 분간이 안 되는데요

자로 직경을 재 보면 됩니다.

ZNR은 제너다이오드 2개를 맞붙여놓은 것과 같은 역활을 하는 것으로

해당전압 이상이 걸리게 되면 컷트시겨 버리는 거죠.

ZNR에서 전압이 큰 것은 두께도 두껍고 

직경은 전류에 관련 된 것으로 직경이 크면 허용전류도 큰데

확실한 전류용량은 같은 직경이더라도 제조사마다 조금씩 다르므로 데이타북을 봐야 됩니다.


* 바리스터(Varistor)의 적정 용량을 알려주세요.

https://kin.naver.com/qna/detail.nhn?d1id=11&dirId=1118&docId=68730959


2.전압 및 크기(용량) 선정방법.


1)AC 220V일때는 391(390V)~471(470V)사용

**AC 220V일때의 최대치(피크치)는 311V임을 감안한것임


2)크기(용량)은 크램핑 빈도수에 의해서 결정되며 수식이 제법 복잡합니다.

가)AC 220V Line용 일때는 471을 사용할경우 10D(파이)이상을 사용하는데 보통 14D를 많이 사용합니다.

나)릴레이 접점보호용은 부하전압의 종류(AC/DC),부하의종류(저항성/유도성),부하전류량에 따라

121~471을 많이사용 합니다.**구체적인 설계기술이 필요합니다.


폭발한 바리스터의 제원은, "FNR 07K471" 군요.

FNR 은 회사 이름이고, 07 부분은 크기(파이) 이며, 471 부분이 견디는 전압인 듯 합니다.



크기(파이) 에 따라 Capacitance 가 커집니다.


FNR_Varistor.pdf





6. 바리스터 구입


연말 휴가 기간 내에 수리하고 싶어, 알리가 아닌 국내 업체에 주문을 넣습니다.


* (10개 묶음) 딥 바리스터 Varistor (10파이, 470V)

https://smartstore.naver.com/ntrex/products/2232991688



하루만에 도착.



조금 과한 포장.



요로코롬 생겼습니다. 빤닥빤닥 하니 보기 좋네요.

전압을 직빵으로 맞는 부품이다 보니, 리드선 굵기도 굵습니다.



트렌지스터 테스터기로 찍어보니, 그냥 캐패시터 처럼 인식하네요.



적출한 놈과 한샷.

구입한 버전은 10파이 짜리 입니다. 원래 붙어 있던 7파이와의 크기가 다르죠?



제너 다이오드를 맞붙여 놓은 바리스터는, 허용하는 전류가 문제지, capacitance 는 별 문제가 안될 것이라 생각 했습니다.




7. 조립


퓨즈와 바리스터를 교체하고, 혹시 모를 쇼트 방지를 위해 캡톤 테이프로 기판 밑부분을 감쌓아 줍니다.



저는, 캡톤 테이프 성애자가 되었습니다.



철재 케이스에 넣어 주구요.



스위치 온! 펑~~!!! ...



야이 XX !!! 안해... 불꽃이 멋지게 일더니만, 요로코롬 되었습니다.




8. 그냥 사자...


수리는 무슨놈의 수리 인가요... ㅠㅠ

SMPS 부품 번호가 "BSV-P50GE" 입니다. 인터넷에서 검색하니, 아래 사이트에서 판매하고 있었습니다.


* (주)보승전기


원래는 "Global Energy Saver" 에서 "(주)보승전기" 로 사명이 바뀐 것 같습니다.


배송비 포함하여 8,000 원에 구입. 주문 후, 다음날 바로 도착 했습니다.



외관은 하나만 빼고 동일 하군요. 회사 이름이 Global 에서 BOSEUNG 으로 바뀐 것 뿐.



스펙은 완전히 동일합니다.

궂이 동일한 제품을 구입한 이유는, 부품 실장 상태를 보니 생략한 것 없이 충실하게 회로를 만든것 같아서 입니다.



커넥터에 들어갈 전선은 쉽게 빼고 넣을 수 있도록 납을 조금 먹여 줬습니다.



LED 페널에 연결 하고, 대망의 스위치 온!!!



켜졌습니다~~~!!!

펑~! 의 트라우마로 인하여, 또 터질 것만 같았지만, 다행히 잘 켜졌습니다. 고주파음도 없고 좋은 제품인 것 같습니다.





9. 다리 붙이기


기존 형광등을 제거하고 LED 를 붙이는 방법은 자석을 붙이면 됩니다.

이 방법은 이미 저번에 소개했어요. 예전에 주문해 놨던 부품들을 다시 꺼내 옵니다.



네오디뮴 자석을 이렇코롬 붙이구요.



LED 패널에 닿는 부분은 와셔로 보호해 줍니다.



LED 패널에 5개씩 다리를 붙였습니다.



이제 준비는 끝났습니다.




10. 교체


기존 형광등 부품들을 모두 제거합니다.



형광등이 세 개나 들어간 자리 입니다.



깔끔하게 모두 제거하고, 이번에 구입한 SMPS 를 장착합니다.

어떤 안정기나 SMPS 가 장착될 수 있도록 배려된 배전판이네요.



SMPS 도 연결하고, LED 패널도 붙이고, 전원을 다 연결 했습니다.



이 깔끔함에 LED 빠돌이가 되었습니다.

그리고, SMPS 만 괜찮으면 반 영구적으로 사용할 수 있다는 LED 만의 장점이 매력적이죠. 지구에 좋은 겁니다.



다행이 터지지 않고 잘 켜졌습니다!!!



기존 전등 유리를 끼워주고 마무리 합니다.

아~ 오래 결렸다.


And

Hardware | TIL311 Hexadecimal LED display 가지고 놀아보기 - 1

|

저는 시각적인 자극에 많이 민감합니다.

그러다 보니, 숫자 표시나 그래프 표시에 관심을 가지고 있죠.


Arduino / Sensor 취미활동을 하면서, 이 "표시" 부품들이 장바구니에 계속 쌓여가고만 있습니다.

오늘은 새로 구입한 TIL311, 또는 DIS1417 소자를 가지로 놀아보기로 합니다.




1. 구매


TIL311 은, 다른 레트로 소자들 보다는 비교적 저렴한 LED display 입니다.

비싼건 개당 8만원 하는 것 들도 있지요. 레트로 소자들 중에서는 현재 수요가 없어 생산 중단한 모델들이 비쌉니다.

이를테면 아래와 같은 부품이죠.


HCMS-2353‎



인터넷에 올라와 있는 구동 모양을 보면 엄~청 이쁜데, 요즘은 OLED 나 LED 로 대체되어 생산이 거의 없거나 조금입니다.

희소가치로 비쌉니다.


당장 고가이면서 희귀한 부품을 구입해 놀아 볼 수 없으니, 적당한 소자를 찾다가 TIL311 이라는 것을 알게 되었습니다.

개당 대략 5천원 정도... 점심 한번 안먹는다고 생각하고 구매 버튼을 눌렀습니다. 2개... ㅠㅠ


* New Promotion TIL311 Encapsulation DIP11 HEXADECIMAL DISPLAY WITH LOGIC Wholesale

https://www.aliexpress.com/item/33009753875.html







2. 도착


비싼 몸값이라 그런지, 우체국 택배로 왔습니다.



중국에서 넘어오는 소자들이 fake 가 많고, 질이 떨어지는 대체품이 오는 경우도 있기에 걱정 했습니다만, 기대했던 만큼의 퀄리티.



한국에서 생산되었다고 하네요. 한국 사이트에서는 도무지 찾을 수 없었지만. (거의가 해외 배송)



소자 안을 자세히 보면, 조그마한 LED 들과 controller chip 이 같이 있습니다.

전체적으로 레진으로 둘러 쌓여 있구요.





3. 사양


Texas Instruments 사가 생산했다 합니다.


32951.pdf

til311_datasheet.pdf

til311-e4-519224.pdf


논리 diagram 은 다음과 같습니다.

입력 받는 4개의 data line 을 통해서 decode 한 후, 정해진 숫자를 표시해 줍니다.

그래서 조그마한 칩이 밑부분에 자리잡고 있습니다.



잘 보면, 숫자 표시부분의 밑, 왼쪽 오른쪽에 점이 하나씩 있습니다.

이것도 따로 표시 가능합니다. 그래서 전류를 많이 먹습니다. (효율 안좋음)



전류가 많이 필요한지라, LED 용 V input 과, 로직 칩용 V input 이 따로 존재합니다.

그리고, 컨트롤은 Data line 에서 high / low 로 단순하게 컨트롤 할 수 있는, 단순한 구조 입니다.


표시 가능한 character 들은 다음과 같습니다. 딱 16진수 숫자만...





4. Arduino 연결 및 소스 - 1


Arduino 와의 연결에 대해서는 아래 사이트를 참고 하였습니다.


* raphaelcasimir/til311_test.ino

https://gist.github.com/raphaelcasimir/611cd8d9eff86a0bf996bd5277a12c94


연결 구성은 다음과 같습니다.


----------------------------------------------
|      FUNCTION      | TIL311 | Arduino Nano |
----------------------------------------------
| LED/LOGIC SUPPLY   | 1, 14  |      5V      |
| GROUND             |   7    |      GND     |
| LATCH STROBE INPUT |   5    |      D3      |
| BLANKING           |   8    |      D4      |
| LEFT D.P. CATHODE  |   4    |      D5      |
| RIGHT D.P. CATHODE |   10   |      D6      |
| LATCH DATA INPUT A |   3    |      D7      |
| LATCH DATA INPUT B |   2    |      D8      |
| LATCH DATA INPUT C |   13   |      D9      |
| LATCH DATA INPUT D |   12   |      D10     |
----------------------------------------------


실제 연결은 다음과 같습니다.



소스는 아래와 같습니다.


// EDUCATIONAL CODE. Do What the Fuck You Want to Public License.

// Just a quick code to explain how the TIL311 hexa display works.
// I do not have it anymore, this is just based on the datasheet so no means of testing.
// This is not object-oriented or uC-style for education purpose.

// You will have to connect pins 1 and 14 of TIL311 to Vcc (5V)
// pin 7 to ground.

// Datasheet: https://www.jameco.com/Jameco/Products/ProdDS/32951.pdf for reference.

#define LSTROBE 3 // TIL311 pin 5. If HIGH, the TIL311 will not be affected by inputs. Useful for multiplexing.
#define BLANK 4 // To pin 8. To blank the screen, can be used to modulate intensity
#define LDP 5 // To pin 4. Left decimal point, put LOW to light up
#define RDP 6 // To pin 10. Right decimal point, same

const byte dataPins[] = {7, 8, 9, 10}; // TIL311 binary inputs
// Connect to 3, 2, 13, 12, in this order, see datasheet page 2

int disp=0; // Displayed number

void setup() {
	for (int i=0; i<4; ++i){
		pinMode(dataPins[i], OUTPUT);
	}

	pinMode(LSTROBE, OUTPUT);
	pinMode(BLANK, OUTPUT);
	pinMode(LDP, OUTPUT);
	pinMode(RDP, OUTPUT);

	digitalWrite(LSTROBE, LOW);
	digitalWrite(BLANK, LOW);

	// Decimal points off
	digitalWrite(LDP, HIGH);
	digitalWrite(RDP, HIGH);
}

void loop() {
	for (int i=0; i<4; ++i){
	    digitalWrite(dataPins[i], bitRead(disp, i));
	}

	disp++; // Same as disp = disp + 1;
	
	if (16 == disp) // This is a hexadecimal display
	    disp = 0;
  
	delay(1000); // Wait one second
}


구동 결과 동영상 입니다.



예쁘죠? 아주 조그마한 LED 들이 빛나는 모습을 실제로 보면 더 좋습니다.



불 켜진 실내에서 구동시킨 동영상이 위와 같습니다.

밝은 곳에서도 잘 보이는 세기 입니다.



단순히 궁금하여, 5V input 이지만, 3.3V 를 먹여 봤습니다. 제대로 동작하지 않군요.

요즘은 저전력 디자인으로 대부분의 소자 및 OLED 가 3.3V 를 지원하지만, 이 친구는 옛날것이라 5V 에서만 동작합니다.



숫자 3을 표시 시킬 때가 저는 가장 마음에 듭니다.



숫자 0 표시시할 때 찍어 보구요.



16진수를 표시하므로 A 부터 F 까지도 표시 됩니다.



이뿌죠?




5. Arduino 연결 및 소스 - 2


Arduino 를 가지고 TIL311 을 컨트롤 하는 방법이 단순하므로, 인터넷에 공개되어 있는 소스가 조금씩 다릅니다.

아래 소개되는 소스는, 가장 간단한 방법으로 구현한 소스라 공유해 봅니다.


* Arduino and a TIL311

http://www.getmicros.net/arduino-til311.php


연결은 다음과 같아요.


----------------------------------------------
|      FUNCTION      | TIL311 | Arduino Nano |
----------------------------------------------
| LED/LOGIC SUPPLY   | 1, 14  |      5V      |
| GROUND             |   7    |      GND     |
| LATCH STROBE INPUT |   5    |      GND     |
| BLANKING           |   8    |      D6      |
| LEFT D.P. CATHODE  |   4    |              |
| RIGHT D.P. CATHODE |   10   |              |
| LATCH DATA INPUT A |   3    |      D2      |
| LATCH DATA INPUT B |   2    |      D3      |
| LATCH DATA INPUT C |   13   |      D4      |
| LATCH DATA INPUT D |   12   |      D5      |
----------------------------------------------


왼/오른쪽 점은 연결시키지 않은 소스 입니다.


/* Control */
#define BLANK_INPUT 6

/* Latches */
#define LATCH_DATA_A 2
#define LATCH_DATA_B 3
#define LATCH_DATA_C 4
#define LATCH_DATA_D 5

void display (uint8_t value) {
	/* Send data to the latch */
	digitalWrite (LATCH_DATA_A, bitRead (value, 0));
	digitalWrite (LATCH_DATA_B, bitRead (value, 1));
	digitalWrite (LATCH_DATA_C, bitRead (value, 2));
	digitalWrite (LATCH_DATA_D, bitRead (value, 3));
}

void setup () {
	// setup the pins
	pinMode (BLANK_INPUT, OUTPUT);
	pinMode (LATCH_DATA_A, OUTPUT);
	pinMode (LATCH_DATA_B, OUTPUT);
	pinMode (LATCH_DATA_C, OUTPUT);
	pinMode (LATCH_DATA_D, OUTPUT);
	digitalWrite (BLANK_INPUT, LOW);
}

void loop () {
	static byte i = 0;
	
	display (i++);
	if (i> 15) i = 0;
	delay (1000);
}


단순히 0 부터 15까지 숫자를 증가시키면서, Data line 에 들어갈 high/low 를 디코딩하여 제어합니다.

결과는 처음 소스와 완벽히 동일하여 따로 올리지 않았습니다.




6. Arduino 연결 및 소스 - 3


또 다른 예제.


* geekman/til311-tester.ino

https://gist.github.com/geekman/b5abb878443ad0cddd68aa1881602a66


연결은 다음과 같습니다.


----------------------------------------------
|      FUNCTION      | TIL311 | Arduino Nano |
----------------------------------------------
| LED/LOGIC SUPPLY   | 1, 14  |      5V      |
| GROUND             |   7    |      GND     |
| LATCH STROBE INPUT |   5    |      D13     |
| BLANKING           |   8    |      D3      |
| LEFT D.P. CATHODE  |   4    |              |
| RIGHT D.P. CATHODE |   10   |              |
| LATCH DATA INPUT A |   3    |      D12     |
| LATCH DATA INPUT B |   2    |      D11     |
| LATCH DATA INPUT C |   13   |      D10     |
| LATCH DATA INPUT D |   12   |      D9      |
----------------------------------------------


여기서도 왼/오른쪽의 dot 는 표시하지 않는 내용입니다.

아래 소스에서 MSB_PIN 과 LSB_PIN 은, 각각 D9 와 D12 라고 표시되어 있지만, 나머지 Data line 에서는 표시가 없습니다.


자세히 보면, 순차적으로 값을 조정하고 있습니다. (i--)

그래서 LATCH DATA INPUT B = D11 과 LATCH DATA INPUT C = D10 이라는 것을 알 수 있죠.

소스를 간소화하는 좋은 테크닉이라고 생각합니다.


/*
 * TIL311 / DIS1417 tester
 * 
 * MSB_PIN -> input D
 *            input C
 *            input B
 * LSB_PIN -> input A
 * 
 * also hook up LATCH_PIN and BLANKING_PIN accordingly
 * 
 * 2016.09.14 darell tan
 */

// PWM pin. try to avoid 5 & 6
#define BLANKING_PIN    3

// LSB_PIN (larger) to MSB_PIN (smaller)
#define LATCH_PIN      13
#define LSB_PIN        12
#define MSB_PIN         9

void setup() {
	for (int i = LSB_PIN; i >= MSB_PIN; i--)
		pinMode(i, OUTPUT);
	
	pinMode(BLANKING_PIN, OUTPUT);
	analogWrite(BLANKING_PIN, 0);
	
	pinMode(LATCH_PIN, OUTPUT);
	digitalWrite(LATCH_PIN, 1);
}

static void send(unsigned int data) {
	data &= 0xF;
	
	for (int i = LSB_PIN; i >= MSB_PIN; i--) {
		digitalWrite(i, data & 1);
		data >>= 1;
	}
	
	
	// strobe it
	digitalWrite(LATCH_PIN, 0);
	
	delayMicroseconds(1); // T-setup = 40ns
	digitalWrite(LATCH_PIN, 1);
}

unsigned int count = 0;
int cycleCount = 0;
int dutyCycle = 0;

void loop() {
	// adjust brightness when it hits 0
	if (count == 0 && ++cycleCount == 1) {
		cycleCount = 0;
		
		analogWrite(BLANKING_PIN, dutyCycle);
		
		dutyCycle += 50;
		if (dutyCycle > 255)
			dutyCycle = 0;
	}
	
	send(count);
	count++;
	count &= 0xF;
	
	delay(500);
}


구동 동영상은 다음과 같습니다. 소스가 좀 다른 모양이지만 완벽하게 동일한 구동이죠?






7. Arduino 연결 및 소스 - 4


또 다른 예제. 밑 좌우에 있는 dot 도 이와 켜 보는게 좋겠죠?

위 소스 중에서 가장 간단한 소스에 dot 을 점멸하는 소스를 추가해 봤습니다.


----------------------------------------------
|      FUNCTION      | TIL311 | Arduino Nano |
----------------------------------------------
| LED/LOGIC SUPPLY   | 1, 14  |      5V      |
| GROUND             |   7    |      GND     |
| LATCH STROBE INPUT |   5    |      GND     |
| BLANKING           |   8    |      D6      |
| LEFT D.P. CATHODE  |   4    |      D7      |
| RIGHT D.P. CATHODE |   10   |      D8      |
| LATCH DATA INPUT A |   3    |      D2      |
| LATCH DATA INPUT B |   2    |      D3      |
| LATCH DATA INPUT C |   13   |      D4      |
| LATCH DATA INPUT D |   12   |      D5      |
----------------------------------------------


연결은 동일하고, arduino 와 dot 부분만 추가로 연결 했습니다.


/* Control */
#define BLANK_INPUT 6
 
/* Latches */
#define LATCH_DATA_A 2
#define LATCH_DATA_B 3
#define LATCH_DATA_C 4
#define LATCH_DATA_D 5

/* Cathods */
#define CATHOD_LEFT 7
#define CATHOD_RIGHT 8
 
void display (uint8_t value) {
    /* Send data to the latch */
    digitalWrite (LATCH_DATA_A, bitRead (value, 0));
    digitalWrite (LATCH_DATA_B, bitRead (value, 1));
    digitalWrite (LATCH_DATA_C, bitRead (value, 2));
    digitalWrite (LATCH_DATA_D, bitRead (value, 3));
	
	if (value % 2) {
		digitalWrite(CATHOD_LEFT, HIGH);
		digitalWrite(CATHOD_RIGHT, LOW);
	} else {
		digitalWrite(CATHOD_LEFT, LOW);
		digitalWrite(CATHOD_RIGHT, HIGH);
	}
}
 
void setup () {
    // setup the pins
    pinMode (BLANK_INPUT, OUTPUT);
    pinMode (LATCH_DATA_A, OUTPUT);
    pinMode (LATCH_DATA_B, OUTPUT);
    pinMode (LATCH_DATA_C, OUTPUT);
    pinMode (LATCH_DATA_D, OUTPUT);
    digitalWrite (BLANK_INPUT, LOW);
	
	pinMode(CATHOD_LEFT, OUTPUT);
	pinMode(CATHOD_RIGHT, OUTPUT);
}
 
void loop () {
    static byte i = 0;
     
    display (i++);
	
    if (i > 15) i = 0;
    delay (1000);
}


숫자 증가시 2로 나누고 홀짝으로 dot 점멸을 컨트롤 했어요.



좌우 dot 들도 잘 발광하네요. 좋다~!



오른쪽도 잘 찍힙니다. 아래는 동영상 입니다.





8. What Next ?


이번에는 간단한 동작만 구현해 봤습니다.

후에 추가 4개를 더 구매하여 6개가 되면, shift register 등을 사용하여 시계를 꾸며 볼까 합니다.



And

Hardware | 레트로 led 글자판 HPDL-1414 사용기 - 1

|

1. 인류의 문명


인류의 문명 발달, 그 이전 인간의 진화에서 가장 큰 변화는 "" 이었다고 합니다.

위험을 피하고, 주위 환경을 살피며, 좋은 상대를 고르는... 수정체같은 이 "눈" 은 확실히 다른 인체 기관과 다른 부분이 있습니다.


눈으로 보는게 중요한 것은 "생존" 에 필수 이며, 현대에 와서는 "기호" 로 바뀌는 것 같습니다.

그래서인지 요즈음, 레트로 LED 에 관심이 굉장이 많아졌습니다.



어렸을 적에 멋져 보였던 기계들에서 사용되었기 때문에 그런 것일까요?




2. HPDL-1414


레트로 LED 들은 요즘도 팔지만, 더 이상 생산을 하지 않는다던지, 수요가 없어서 희소가치가 높아져 있습니다.

그래서 다들 비쌉니다. 아시죠? 제가 1만원 이상 되는거 사기 어렵다는거. (직장인의 비애)


나중에 구입하게 되면 사용기를 올리겠지만,

현재 구할 수 있는 레트로 LED 중에서는 HPDL-1414 가 가장 저렴하지 않은가 합니다.


낼름 구입해 봤습니다.


* 1pcs X HPDL-1414 HPDL1414 Four character smart digital display. Digital Tube. Free Shipping

https://www.aliexpress.com/item/32920650954.html



요즘 알리 배송은 예전만큼 느리지 않습니다.



일단 두 개 구입했습니다.



인터넷에서 돌아다니는 사진과는 조금 다른 제품 마무리 입니다만, 나름 예쁩니다.



예전부터 말레이시아에서 이런 류의 부품들이 많이 생산되는 것 같습니다.

다만, 여기에 말레이시아라고 쓰여 있지만, 정말 그런지는 아무도 모르죠.



각 표시창이 볼록하게 되어 있어서, 가시성을 높여주는 모양입니다.



회로 chip 은 수지로 막혀 있네요. 카피품이면 chip 이 다르겠지만, 동작은 오리지널과 차이 없는 듯 합니다.





3. 사양


인터넷에서 스켄 버전이 있지만, 가장 깔끔한 사양서 PDF 를 발견하게 되어, 일반 사양서와 함께, 여기에 공유해 봅니다.


dl1414-4-char-magnified-led-display-siemens.pdf

HPDL-1414.pdf


사양서 대로라면, 아래 캐릭터를 표현할 수 있습니다.





4. 연결


I2C 통신이나 컨트롤러가 없기 때문에, HIGH/LOW 특성으로 단순 표시를 시도해 봅니다.

아직 이쪽 지식이 많이 않은지라, 아래 사이트의 소스를 그대로 사용했습니다.


* HPDL-1414 Test

http://psyclesam.blogspot.com/2013/03/hpdl-1414-test.html


연결은 다음과 같습니다.


-----------------------------------------
| HPDL-1414 |  function  | Arduino Nano |
-----------------------------------------
|     1     | Data Input |      D5      |
|     2     | Data Input |      D4      |
|     3     |  WR Wrtie  |      D10     |
|     4     |Digit Select|      D9      |
|     5     |Digit Select|      D8      |
|     6     |     VCC    |      5V      |
|     7     |     GND    |      GND     |
|     8     | Data Input |      D0      |
|     9     | Data Input |      D1      |
|     10    | Data Input |      D2      |
|     11    | Data Input |      D3      |
|     12    | Data Input |      D6      |
-----------------------------------------


소스는 다음과 같습니다.


const int dTime = 25;  // delay beteewn digit writes
const int lTime = 250; // delay between loops
const int cMin = 33;   // start Decimal Ascii value 32(space) to 95 (underscore) 
const int cMax = 95;   // start Decimal Ascii value 32(space) to 95 (underscore)


void setup() {
  DDRD = DDRD | B11111111; // set direction bits for pins 7-0
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}

void loop() {
  int asciiDec = cMin;
  while(asciiDec < cMax)  {
    // loop ascii set
    PORTD = (asciiDec);
    delay(1);                // wait for a ms 
    digitalWrite(8, HIGH);   // 8=A0 9=A1 select digit HH=3 LH=2 HL=1 LL=0
    digitalWrite(9, HIGH);   // 8=A0 9=A1 select digit HH=3 LH=2 HL=1 LL=0
    delay(1);                // wait for a ms    
    digitalWrite(10, LOW);   // Write pin Low
    delay(1);                // wait for a ms
    digitalWrite(10, HIGH);  // Write Pin High
    delay(dTime);            // delay between characters ms seconds

    PORTD = (asciiDec);
    delay(1);                // wait for a ms 
    digitalWrite(8, LOW);    // select digit
    digitalWrite(9, HIGH);   // select digit
    delay(1);                // wait for a ms
    digitalWrite(10, LOW);   // Write pin Low
    delay(1);                // wait for a ms
    digitalWrite(10, HIGH);  // Write Pin High
    delay(dTime);            // delay between characters ms seconds

    PORTD = (asciiDec);
    delay(1);                // wait for a ms 
    digitalWrite(8, HIGH);   // select digit
    digitalWrite(9, LOW);    // select digit
    delay(1);                // wait for a ms
    digitalWrite(10, LOW);   // Write pin Low
    delay(1);                // wait for a ms
    digitalWrite(10, HIGH);  // Write Pin High
    delay(dTime);            // delay between characters ms seconds  

    PORTD = (asciiDec);
    delay(1);                // wait for a ms 
    digitalWrite(8, LOW);    // select digit
    digitalWrite(9, LOW);    // select digit
    delay(1);                // wait for a ms
    digitalWrite(10, LOW);   // Write pin Low
    delay(1);                // wait for a ms
    digitalWrite(10, HIGH);  // Write Pin High
    delay(dTime);            // delay between characters ms seconds

    asciiDec++;              // increment character
    delay(lTime);            // loop delay ms seconds
  }

}




5. 동작


이미 검증하신 분을 그대로 따라 했더니만, 힘들지 않게 간단하게 표시를 시켜볼 수 있었습니다.



4개 LED 에 동일한 글짜를 표시하고, 바로 다음 글짜로 옮겨가는 단순한 구동입니다.



동영상도 올려 봅니다.

이 레트로 LED 의 매력을 느낄 수 있죠?



확대 스코프로 안을 들여다 봤습니다.

금으로 된 bonding 이랑, 발광하는(?) 소자들이 보입니다.



발광하게 되면 이렇게 보여요. 신기.





6. Reference


이번에는 간단한 동작만을 따라해 봤지만, 아래 두 사이트를 참고하여 좀더 다양한 표시 방법에 도전해 보겠습니다.

특히 I2C 를 통한 통신이 되면 편하게 문자를 표시할 수 있을것 같네요.


* Alphanumeric LED Displays Revisited

http://paul.zawada.us/2011/12/alphanumeric-led-displays-revisited.html



* Arduino Snippets: DL1414 LED Character Display

https://softsolder.com/2012/12/07/arduino-snippets-dl1414-led-character-display/


참고로, 추가 2개 더 구입함...


And
prev | 1 | 2 | next