오랜만의 포스팅입니다. 그냥 제 느낌이 그런 것인지 지구온난화의 영양인지 올여름은 아무것도 하기 싫을 정도로 더웠네요.
이번 포그트엔 한 달 정도 걸쳐 회로도를 그리고, PCB를
만들고, 코드 작업을 한 공작에 대해서 이야기하려 합니다.
사실 막 그렇게 고난도의 공작이 아니라 PCB를 설계/주문해서 배송되는 시간이 제일 길었어요. 어떻게 보면 이번 포스팅은 KiCad를 이용해서 설계를 하고 PCB를 주문한 과정의 일들 입이다.
LED 룰렛은 아주 오래 전에는 카운터와 디코더를 사용하여 만들었습니다. 지금은 마이크로컨트롤러로 LED를 켜고 끄는 동작을 제어할 수 있으니, 완전히 디지털로직에만 의존하던 공작보다 엄청나게 유연하게 만들 수 있게 되었죠. 저는 EFR32xG24 Explorer Kit에 CircuitPython을 사용하여 만들어 보았습니다.
회로도 그리기
LED 룰렛을 만들기 위하여 회로도를 그립니다.
https://www.youtube.com/watch?v=yyT5uN93JMY&list=PLlT0qmKc0_5ddENmn3fNbMIVXvFqQTv2Z&index=3
LED를 제어하는 GPIO의 수를 어떻게 줄일 수 있을까
일반적으로 LED는 GPIO 하나씩을 할당하여 개별적으로 제어를 합니다. 하지만, LED 룰렛과 같이 많은 LED를 제어하기 위하여 하나하나 GPIO를 할당하는 것은 매우 곤란한 일이 아닐 수 없습니다. 그래서 LED의 애노드와 캐소드를 모두 제어할 수 있도록 GPIO를 할당하는 아이디어를 생각하게 됩니다.
위의 회로도는 애노드가 6개의 그룹으로, 캐소드가 5개의 그룹으로 묶여 있습니다. 이렇게 한꺼번에 묶었다고 해서 LED가 한꺼번에 켜지는 것은 아닙니다. 애노드가 모두 한 그룹에 속해 있더라도, 캐소드를 제어해서 한 그룹 내에서도 하나의 LED만 켜질 수 있도록 제어할 수가 있게 됩니다. 쉽게 이야기해 본다면 애노드 그룹 중의 하나만 HIGH, 캐소드 그룹 중의 하나만 LOW로 제어한다면 그 교차점에 있는 LED만이 정방향 바이어스가 되어 켜지게 되는 것입니다. 이렇게 하면 30개 LED의 제어를 위해서 11개의 GPIO만을 사용할 수 있는 것이죠.
PCB Layout
회로도는 그냥 부품들이 어떻게 연결되는지를 나타내는 그림일 뿐입니다. 아제 이 회로도를 바탕으로 실제 하드웨어를 만들어야 하는데요, 간단한 것이라면 만능기판(Universal Board)이나 브레드 보드(Bread Board)를 사용하겠죠. 그런데, 이번 보드는 LED도 저항도 30개씩 되다 보니 이것들만 연결해도 그냥 점퍼선으로 연결한다면 아주 피곤한 일이죠. 캐드를 사용한 김에 PCB 설계까지 했습니다. 요즘은 취미용 PCB 몇 장 정도는 예전엔 상상도 할 수 없는 비용에 제작을 할 수 있으니 이게 더 경제적일 수도 있겠죠.
https://youtu.be/pz3rLksVW0E?si=WXIv8vOqsDVoBuQv
코드 작성
PCB를 온라인울 통해서 주문했는데, 제일 저렴한 배송 옵션을 선택했습니다. 2-3주 걸린다네요. 화급을 다투는 일도 아니고, 2-3주 기다리면 해외에서 배송됨에도 불구하고 배송료 2-3불이라니 그냥 감수하기로 합니다. 최종 하드웨어 없는 상태에서 print에 의존해서 동작만 확인하면서 코드를 작성하기로 합니다.
https://youtu.be/HdLD7D4zdAQ?si=LlnbzWSgDoT5Cbm9
애노드와 캐소드를 모두 제어하는 LED 클래스
보통은 LED의 동작을 추상화하기 위하여 GPIO 하나만 할당하는데, 위에 회로도에서도 언급했지만, 애노드와 캐소드를 모두 제어하게 됩니다. 회로도에서 설명한 것처럼 애노드 혹은 캐소드에 연결된 GPIO를 공유하는 LED들 중에서 하나의 LED만 정방향 바이어스가 되도록 하기 위함이죠. 물론 앞선 영상에서는 버그를 만들었지만 최종적으로는 다음 영상에서는 정상적으로 동작할 수 있도록 수정이 되었습니다.
class LED2:
'''
Class LED2 (version 2)
Abstract LED with anode and cathode
'''
initialized_ports = {}
def __init__(self, anode_port, cathode_port):
if anode_port in LED2.initialized_ports: # Check if the anode_port already has been initialized.
self.anode = LED2.initialized_ports[anode_port] # Use already initialized instance.
else: # if not, newly initialize.
self.anode = digitalio.DigitalInOut(anode_port)
self.anode.direction = digitalio.Direction.OUTPUT
LED2.initialized_ports[anode_port] = self.anode # Add to the dictionary.
if cathode_port in LED2.initialized_ports: # Check if the cathode_port already has been initialized.
self.cathode = LED2.initialized_ports[cathode_port] # Use already initialized instance.
else: # if not, newly initialize.
self.cathode = digitalio.DigitalInOut(cathode_port)
self.cathode.direction = digitalio.Direction.OUTPUT
LED2.initialized_ports[cathode_port] = self.cathode # Add to the dictionary.
debug_print(LED2.initialized_ports)
debug_print(self.anode)
debug_print(self.cathode)
def on(self):
self.anode.value = True # Anode --> High
self.cathode.value = False # Cathode --> Low
def off(self):
self.anode.value = False # Anode --> Low
self.cathode.value = True # Cathode --> High
조립과 디버그
PCB에 부품을 조립하는 것은 납땜의 기술입니다. 하드웨어가 준비되고 그저 상상으로만 작업했던 코드도 디버그를 해야 하죠. 실제로 시험해 보지 않은 코드가 한 번에 동작할 수는 없습니다. 반복된 시험과 수정을 거쳐 완벽한 코드가 되는 것입니다.
https://youtu.be/RBw1MuXBfwE?si=klM6A-NL_DgWiBMm
납땜하는 법에 대해서는 예전에 한 번 포스팅한 적이 있습니다.
많은 초보자들이 납땜은 납을 녹여 납땜 패드에 붙이는 것이라고 생각을 하는 경우가 많습니다. 하지만, 납땜은 납을 녹여 가지고 가는 것이 아니라, 열이 오른 납땜 부위에 납이 스며들도록 하는 것이라고 생각하여야 합니다. 납땜 패드에 열이 충분히 오르지 않으면 땜납이 납땜 패드와 겉돌게 되어 냉납(cold solder)이 됩니다. 냉납은 접촉 불량을 발생시키게 되고, 완성품이 동작을 하지 않거나 신뢰성을 떨어지게 하는 원인이 됩니다. 납땜은 납땜 패드의 가열→가열된 납땜 패드에 땜납 가져가기→납땜 패드에서 땜납 녹이기→땜납이 충분히 공급되었으면 땜납 제거→녹은 땜납이 충분히 퍼졌으면 납땜인두 제거의 순서가 되도록 몸에 익혀야 합니다.
회로 설계 도면과 코드
KiCad로 설계한 디자인 파일과 Gerber, 그리고 소스 코드는 GitHub에 올려 두었습니다.
https://github.com/sangyoungn/led-roulette-with-circuitpython
캐드도 코딩도 직접 만들어 보면서 익히는 것이 빠르게 익히는 방법입니다. 책으로만 읽는 것은 돌아서면 잊게 됩니다. 즐거운 마음으로 공작도 하면서 나도 모르게 프로그래밍 언어도 캐드도 익히게 되는 자신을 보게 될 것입니다.
'전자공학을 즐겁게 > 누구나 취미전자공학' 카테고리의 다른 글
CircuitPython으로 만드는 LED 주사위 놀이 (0) | 2024.08.24 |
---|---|
CircuitPython 시작하기 (feat. xG24 Explorer Kit) (0) | 2024.07.05 |
원격으로 라즈베리 파이 코드 편집하기 - Visual Studio Code 활용 (2) | 2024.06.02 |
Python을 이용한 UART 활용 - pyserial과 xmodem (0) | 2024.05.09 |
라즈베리 파이의 Device Tree Overlay와 UART 하드웨어 흐름제어 사용하기 (0) | 2024.04.21 |