주차별 진행했던 작업 또는 고찰에 대해서 간략하게 정리 합니다.
처음부터 보시면 의식의 흐름대로 정처없이 흘러가는 작업기에 대한 간접적 체감이 가능합니다.
업데이트는 비정기 입니다.
2025년#
37주차#
- 블로그 작성
- 부품 구매
- 반짝 보드 조립 및 테스트
- PD 전원 5V, 12V 출력 확인
- 레벨 시프터 정상 출력 확인
- 이후 작업은 이 보드 버전을 기본으로
- LED 전원 인디케이터 출력 안됨(확인 필요)
- 서브 전원(스탠드얼론 용도) 출력 안됨(확인 필요)
35, 36주차#
- 블로그 정리
34주차#
- 보드 마무리 및 제작 신청
- 4번째 버전 (빛나리 프로젝트, 반짝 쉴드)
33주차#
- 보드 재설계
- FET 직접 제어에서 하이사이드 스위치 변경 적용
- 레벨 시프터 별도 IC 적용 검토
- 4채널이 기본이라 불필요하므로 적용 취소
- FET 방식으로 비반전 적용
- xiao 버전에서 rp2040 버전으로 다시 원복
- 이름 빛나리 를 정식 프로젝트로 고려, 쉴드 이름은 반짝
- bitnari
- banchack
32주차#
- 문서화
- 블로그 재정비 및 업로드
- 하드웨어
- XIAO 버전 고려 시작
- 외부 전원만 사용하는 방식 우선 고려
- 또는 VBUS 가능하지만 PD가 연결되면 PD 출력을 우선 하는 회로
- 반짝(BANCHAK) 보드
- 출력 이상 재 검증
- 기존 회로 풀다운 저항을 풀업으로 점퍼 날리기
- 특별한 개선점 없음
- 다이렉트 연결 테스트 요망 (FET 문제인가)
- 출력 안됨 (일단 보류)
- 아 이런.. 레벨 시프터가 인버팅 회로라서 신호 반전 문제 였음 (설계 실수)
- 기존 회로 풀다운 저항을 풀업으로 점퍼 날리기
- XIAO 버전 고려 시작
31주차#
- 펌웨어
- USB 연결 해제 시 이벤트 및 동작 정의
- RPC 핸들러 함수 분리 (파일 단위)
- 파워 제어 및 자동 꺼짐 기능 추가
- 하드웨어
- 신규 버전 조립
- PD 회로 5, 12v 출력 확인
- 타이밍 문제
- RGB가 CYMK로 출력되는 문제
- FET 변경했으나 효과 없음
- 다른 FET 또 고려
30주차#
- 애플리케이션
- 레이아웃 수정
- 뷰모델 의존성 분리
- 캡쳐 모듈 안정성 개선
- WinRT 캡쳐 방식 검토
- 캡쳐 시 노란테두리가 유지되어서 실 사용은 보류
- DXGI 캡쳐 방식 개선 및 검증
- HDR 포맷으로 캡쳐 안됨 재 확인
- F16161616 포맷 지정해도, UINT8888로 캡쳐 됨
- 동적으로 디스크립터 변경으로 대응
- 다른 라이브러리로 구현하여, Vortice 라이브러리 오류인지 확인
- DSoft.SharpDX.Desktop
- 확인 결과 동일하게 안됨 (더 이상 검증은 안하는걸로)
- 펌웨어
- rpc 마이너 개선
- 주요로직 개선
- RPC 핸들러
- 디코딩 및 실행, 파싱
- 노티피케이션 구현
- Transport 추상화
- USB CDC 개선 송/수신 메시지 큐
- RPC 핸들러
29주차#
- 애플리케이션
- 일렉트론 기반 앱 가능성 검토
- 뷰모델 문제 수정
- 밝기 기능 구현
- 정적 밝기
- 동적 밝기
- 픽셀 와트 측정 기능 추가
모든 픽셀 순차적으로 측정- 한번에 측정
- RGB 개별 측정 방식으로 변경 (전력 최대 1/3)
- 3번 측정
- 디스플레이 정보 관련 강화
- 확장 아이디 정보 포함
- 디바이스 펌웨어
- RPC 개선 준비 (exe, enc 통합은 보류)
- 새 RPC 적용
- 문서화 준비
- 블로그 재정비
- 스킨 변경
- 문서 정리
- 블로그 재정비
- 디바이스
- 단종 칩 구매
28주차#
- 서버 코드 생성기 초안 완성
- 기존 서버 코드 매크로 변경
- 생성기 작업을 수월하게 하기 위함
- 단점 기존 서버 코드 가독성이 낮아짐
- request id 무시 또는 스트링, bytes 선택 옵션 추가
- UTIL_CAT 제퍼와 호환되지 않음 (수정)
- 빛나리 보드 땜질
- 잠시 중단 (DFN 부품으로 땜질 어려움, PD 동작 및 레귤레이터 동작이 되지 않음)
- 인두기 및 추가 부품 구매
27주차#
- rpc 스펙 구조 변경
- 코어 스펙 분리
- proto 생성기 개발
- 생성기 개선 (proto 폴더 분리, import 기능 강화)
- 서버 코드 생성기 작업 (MCU 사이드 C 코드 생성)
- 서버 코드 최적화
26주차#
- nanoRPC proto 자동 생성 스크립트 구현
- 초안 완성
- 방식 변경 리빌딩
25주차#
- 디바이스
- PCB 변경 설계 및 주문
- 부품 구매
- 애플리케이션
- DI 서비스 관련 라이프사이클 변경
- Disposable 인스턴스 호출 시 신규 생성
24주차#
디바이스
- PCB 제작 주문
- 부품 구매 검토
- 아니 왜 USB PD칩 갑자기 재고 없음? (구매 불가 ㅠㅠ)
- PCB가 제작 중이단 말이다!
- TI 걸로 제 설계해야할 것 같음
- 재설계
- CH224K 칩으로 PD 변경
- USB-C 커넥터 변경
애플리케이션
큐 방식으로 RPC 통신 고려?- 요청과 응답형태로 송수신 변경
- 서비스는 바이트 형태로 송수 신하고 랩퍼 클래스를 더 만들어야 할 듯?
23주차#
- RPC
- 개선 및 최적화
- 실행 및 응답 메시지 생성을 위한 매크로 및 구조 정의
- DEFINE, DECLARE
- 스펙 정보 읽어오기 구현
- NanoRPC 구상 (전용 RPC)
- 자동 코드 생성 검토
- USB CDC 상 DTR 적용 (펌웨어)
- 마소 시리얼 모니터 프로그램 동작 확인
- C# 에서 DTR 활성화 안 됨 (확인 필요)
22 주차#
- 디바이스 PD 반영 아트워크 완료
- 애플리케이션 뷰모델 관련 개선
21 주차#
- 디바이스
- 2차 보드 회로도 완료
- 아트워크
- 전원 회로 변경
- 애플리케이션
- 뷰모델 개선
- 뷰모델 직접 YAML 저장
- 보류 및 취소(복원 시 문제)
20 주차#
- 디바이스
- USB PD 변경
- 전원 선택 회로 설계
- 회로 DIP 스위치 기능
- PD 전압 선택 (5V or 12V)
- USB PD 변경
- 애플리케이션
- 디바이스 상태 정보 관련 정의
- 마지막 동기화 시간
- 디바이스 스펙 proto 정의
- 스펙 정보는 YAML로 작성 후. protobuf로 AI 통해서 역설계
- 뷰모델 개선
- Locator를 이용한 전역 뷰모델 관리
- 뷰모델 일부 통합
19 주차#
- 5월 내 0.1.0-preview 버전 목표
- 디바이스
- USB PD 솔루션 변경 검토 (회로가 단순하고 저가일 것)
- 애플리케이션
- 캡쳐 모듈 DI 적용
18 주차#
- 디바이스
- USB PD 전원 설계 및 회로도 작성
- 애플리케이션
- 이미지 처리 관련 코드 최적화
- 스크린 설정 컨트롤 분리
- MainForm에 직접 삽입 이후 메인 폼 디자인 변경 후 저장 시 멈춤
- VS 뿐만 아니라 라이더에서도 동일하게 멈춤 발생하는 것 보면, 단순 VS 문제는 아닌 것 같음
- 디자이너가 아닌 코드로 삽입 (임시 조치)
- 디자이너에서 Load 이벤트 코드가 실행 되는 것으로 보임 (해결!)
- MainForm에 직접 삽입 이후 메인 폼 디자인 변경 후 저장 시 멈춤
- 감마 보정 기능 추가
- 적당히 기본 기능만 넣어서 0.1.0 버전으로 내놓아야 할 듯
- LED 출력 기능
- 기타 통신
- 디바이스 정보 송수신 (동기 통신)
- PING
- 데이터 통신 관련 DI(Dependency Injection) 적용
17 주차#
- RPC
- 교환 데이터 1차 정리
- LED 출력 및 전력 상태
- 디바이스 정보 (버전, 지원 기능 등)
- 각종 설정 (추후 고려)
- noti 수명 옵션 (추후 고려)
- 구독 시 결정
- last or count
- will dispose
- 교환 데이터 1차 정리
- 디바이스
- 외부 전원 USB PD 고려
- 부품 선정 (가격, 옵션)
- 회로도 작성
- 외부 전원 USB PD 고려
- 애플리케이션
- Tab 내부 뷰 분리
- ScreenConfig
- ViewModel 마이너 업데이트
- Yaml 설정 파일 저장 및 복원 구현
- ReactiveUI에서 콤보박스 결과는 index로 처리하는 것이 나음 초기화 직전에 index 값은 -1이지만 Value 지정 시 오류의 문제
- HybridWebview 재검토
- 스벨트 빌드 후 동작 확인
- 개발 서버 핫 리로디드 방식 불가 (일반적인 방법)
- iframe을 통한 간접 가능 확인
- https://learn.microsoft.com/ko-kr/dotnet/maui/user-interface/controls/hybridwebview?view=net-maui-9.0
- iframe 내부에서 window.HybridWebview 호출 가능
- 반대는 불가
- postMessage 성공
- 비동기 방식 오류인데 확인은 필요 —> 비동기 함수 호출로 재확인 필요
- 제대로 초기화가 되지 않아서 발생하는 문제
- 비동기로 데이터 주고 받기 가능 확인
- 공식 예제 JS —> C# 비동기 호출 응답 없음
- 맥 데스크탑 환경, dotnet sdk 9.0.203 버전
- 동기 호출은 잘 됨
- 원인 불명
- Tab 내부 뷰 분리
16 주차#
- RPC 구조 최적화 및 마이너 룰 변경
- 비동기 타입 세분화 및 구독 타입 분리
- RPC 핸들러 생성 매크로 작업
- 최종 제외 결정 (디버깅 및 추가 작업 불편함)
- 적용 테스트 완료
- 파싱 속도 등 이슈는 없었음
15 주차#
- 하드웨어
- PIO 제어 방식을 DMA 방식으로 개선
- 13ms → 1 ~ 2ms 이하
- DMA 추상화 계층에서는 드라이버 구동이 잘 안됨
- 라즈베리파이 전용 드라이버로 성공
- 프로젝트에 쉴드 설정 적용
- LED 문제 (USB 전원 사용)
- LED 스트립 방향 문제
- 실수로 방향 미확인 (정 방향 장착 후 해결)
- LED 전력 문제
- 양 끝 전원 선 연결하여 해결
- 불 미세하게 깜박임
- 전력 문제인가? 어뎁터 구입 후 확인
- 전체 LED 켤 시 1A 까지 소모 될 것으로 예상
- USB 전력 제한 초과!
- LED 스트립 방향 문제
- PIO 제어 방식을 DMA 방식으로 개선
- 소프트웨어
- 프로토콜버퍼 파일 분리 및 재정의
- COBS 깃헙 공개
- 스크린 챕쳐 및 출력 테스트
- 60개 LED 데이터 파싱 및 출력 처리 13 ~ 14ms
- Elapsed time: 44.536000, 13009.512000 us
- 30 프레임 출력 시 USB 오류 발생
- 전력 문제 인지 또는 스루풋 문제인지 확인 필요
- 디버그 출력 영향
- 15 프레임이 적당하지 않을까?
- 60개 LED 데이터 파싱 및 출력 처리 13 ~ 14ms
14 주차#
- 모니터에 LED STRIP 장착
- Zephyr에 COBS 추가 됨
- 아니 직접 만들었건만! (그래도 환영)
- 확장성을 위해서 기존 직접 만든 라이브러리는 잠정 사용 보류 고민
- RPC 일부 구현 및 적용
- 200개의 픽셀 데이터 처리 속도 성능 테스트
- RP2040 기준
- COBS 디코딩, Property 디코딩, 픽셀 데이터 전체 디코딩
- 한 메시지 처리 기준 1ms 이하
- RP2040 기준
- 200개의 픽셀 데이터 처리 속도 성능 테스트
clock freq: 125000000
Elapsed time: 115.312000, 123.112000, 510.912000 us
13 주차#
Proto를 이용한 RPC 구현 고려
BLE의 service 의 characteristic 개념을 차용해서 데이터를 주고 받는 것을 고려
- READ, WRITE, WRITE WITH NO RESP, NOTIFY 등을 고려
- 그러나 설계를 할 수록 characteristic은 value oriented 된 방식이라는 생각이 들고
- READ를 하더라도 시스템 상으로는 READ request와 read에 대한 response가 구분되어야 하는 문제가 있음
- 그리고 BLE read에서는 파라미터와 리턴 값을 주고받는 개념이 아니라서 애매해서 procedure와는 결이 다르다고 느낌
- 그래서 좀 더 HTTP 통신이나 METHOD 호출에 가까운 형태로 바꾸기 위해 네이밍으로 RPC 서비스를 흉내 REQUEST, RESPONSE로 단순화
- 클라이언트에서 비동기 이벤트나 데이터 수신을 위해서 STREAM (BLE 기준 notification) 형식을 추가로 차용
임베디드 환경에서 호스트 클라이언트 간 데이터 교환에 있어서, 완전 자동화(코드 제네레이션)된 방식으로 RPC 구현이 어려운 상황에서, 메시지만 가지고 수동으로 RPC 기능을 흉내내고자 함
- nanopb에서 gRPC를 지원하지 않음
별도의 코드 제네레이터를 설계하거나 구현한 방식이 아니므로, 호스트 클라이언트 간 프로토콜 정의에 있어서 데이터 교환 시 잘못된 데이터를 정의하거나 주고 받는데 실수를 줄이는 방향성과 주 목적으로 아래와 같은 룰을 정의하고, 그에 사용하여 RPC 처럼 동작할 수 있도록 함
실제 적용환경은 요청을 받는 쪽이 임베디드 시스템에서 C언어 기반의 개발 환경을 가정하고, 매크로를 통해서 proto에 선언된 메소드(실제는 메시지)에 대한 파싱이나 콜백, busy 와 같은 처리를 쉽게 할 수 있도록 함
설계 룰
- 일반적으로 요청을 받는 쪽이 호스트, 응답을 받는 쪽이 클라이언트이다.
- 메소드를 대표하는 각 메시지의 이름에는 요청과 응답이 포함되어 전송 방향을 추정할 수 있도록 한다.
- RPC 관련 코드가 자동으로 생성되는 것이 아니기 때문
- 일반적으로 동사 + 목적어 형태의 이름 뒤에 요청과 응답으로 구분을 지어서 한쌍을 유지하도록 한다
- 만약 응답이 필요 없을 경우 (HTTP 환경 기준에서는 UDP)에는 별도의 RESPONSE 메시지를 정의하지 않는다.
- 메소드(메시지) 이름 예시
- WriteConfigRequest
- WriteConfigResponse
- 메소드(메시지) 이름 예시
- 실제 메시지를 구분 하는 것은 한쌍의 메시지를 대표하는 즉, 메소드 이름으로 선언된 enum 값이다.
- WRITE_CONFIG = 0x01;
- 파라미터와 리턴 메시지 각각 존재할 수 있어도 본래 메소드는 하나이어야 하기 때문에, Request, Response 모두 같은 id를 사용한다.
- 대신 Request, Response를 구분하기 위해서 별도 타입 enum으로 구분한다.
- 메시지 분류를 위해서 커다란 공용체에 해당하는 메시지에 oneof나 optional로 모든 메소드(메시지)를 포함하지 않는다.
- 처리 시간 및 비용의 문제
- 아래 best practice 참고
- 각 메소드 요청이나 응답에 있어 공통된 필드 형식을 가지고 있더라도, 공용 메시지를 선언하여 이를 대신하여 사용하지 않는다. 사용자 코드 작성 시 혼돈 방지.
RPC#
enum rpc_method_type {
RPC_UNKNOWN = 0,
RPC_REQUEST,
RPC_REQUEST_WITH_NO_RESP,
RPC_RESPONSE,
RPC_STREAM
};
struct rpc_procedure {
uint32_t id;
enum rpc_method_type type;
bool is_busy;
void *res_data;
void (*on_requested)(pb_istream_t *stream);
void (*encode_reponse)();
};
// 응답 전역 변수 생성
// res_data_##id
// res_data = &res_data_##id,
#define RPC_RES_DATA_INIT(...)
#define RPC_PROC_INIT()
#define RPC_INIT(_proc, ) \
RPC_RES_DATA_INIT()
// 프로시저 링크드 리스트로 생성?
// 함수 타입
// param 없음, return 없음
void func1(void);
// param 없음, return 있음
int func2(void);
// param 있음, return 없음
void func3(int);
// callback (비동기 수신)
void func4(callback);
// 다른 방법 (아이디어)
// 메소드 메시지에 요청 메시지 id, 리턴 메시지 id를 담아서 전송
// message proto
syntax = "proto3";
import "nanopb.proto";
// int32
enum MethodId {
UNKNOWN = 0x00;
WRITE_PIXELS_WITH_NO_RESP = 0x01;
READ_DEVICE_INFO = 0x02;
}
enum MethodType {
UNKNOWN = 0x00;
REQUEST = 0x01; // request
REQUEST_WITH_NO_RESP = 0x02; // request with no response
RESPONSE = 0x03; // response for request
STREAM = 0x04; // stream without request
}
enum ErrorCode {
ERR_NO = 0; // no error
ERR_PERM = 1; // no permisttion
ERR_REQ = 2; // wrong request
}
message Property {
MethodId id = 1;
MethodType type = 2;
optional string name = 10;
optional uint32 version_code = 11;
}
message PixelData {
uint32 offset = 1 [(nanopb).int_size = IS_16];
uint32 length = 2 [(nanopb).int_size = IS_16];
repeated fixed32 colors = 3 [(nanopb).max_count = 255];
}
syntax = "proto3";
import "message.proto"; // message for request and response
import "enum.proto";
// Create Unique Protos per Method (비용의 문제)
// Don’t Include Primitive Types in a Top-level Request or Response Proto
//message GetUserRequest {
// int32 user_id = 1; // Primitive type at top-level
//}
message WritePixelsRequest {
Property prop = 1;
PixelData data = 2;
}
message ReadDeviceInfoRequest {
Property prop = 1;
}
message ReadDeviceInfoResponse {
Property prop = 1;
optional DeviceInfo data = 2;
optional ErrorCode error = 3;
}
message WritePowerConfigRequest {
Property prop = 1;
PowerConfig data = 2;
}
message WritePowerConfigResponse {
Property prop = 1;
ErrorCode error = 2;
}
message StreamPowerStatusRequest {
Property prop = 1;
bool enabled = 2;
}
message StreamPowerStatusResponse {
Property prop = 1;
ErrorCode error = 2;
}
message StreamPowerStatus {
Property prop = 1;
PowerStatus data = 2;
bool is_last = 3;
}
RPC (BLE like, Value oriented)#
syntax = "proto3";
import "nanopb.proto";
message RpcCommon {
fixed32 uuid = 1;
optional uint32 version_code = 2;
// optional string name = 2 [(nanopb).max_length = 32];
RpcType type = 3;
}
message RpcNotify {
RpcCommon common = 1;
optional bool enabled = 2;
optional sint32 result = 3;
}
// message rules
// naming
// Procedure name has type
// prefix: Rpc
// name
// postfix: Type (ex: Read, Write, WiretNoResp, Notify)
// RpcTemperatureRead
// signature rules
// naming
// value (return value for read, )
// result (response for write, optional)
// ret (return value for read)
// dont' use to avoid increase decoding complexity
message DoNotUseThisMethod {
RpcCommon common = 1;
optional string w_arg = 2;
optional string r_arg = 3;
optional sint32 res = 4;
optional uint32 ret = 5;
}
// write, no response
message RpcPixels {
RpcCommon common = 1;
oneof req {
PixelData data = 2;
}
message PixelData {
uint32 offset = 1 [(nanopb).int_size = IS_16];
uint32 length = 2 [(nanopb).int_size = IS_16];
repeated fixed32 colors = 3 [(nanopb).max_count = 255];
}
}
// read, response
message RpcDeviceInfo {
RpcCommon common = 1;
oneof res {
optional DeviceInfo data = 2;
}
message DeviceInfo {
string board_name = 1;
optional string shild_name = 2;
string version = 3;
uint32 coms_supported = 4;
}
}
message RpcPowerMon {
RpcCommon common = 1;
oneof noti {
bool enabled = 2;
}
}
message RpcLedControllerWrite {
RpcCommon common = 1;
oneof signature {
string value = 2;
sint32 result = 3;
}
}
enum RpcType {
RPC_NONE = 0x00; // dummy type (should not choose)
RPC_READ = 0x01;
RPC_READ_RES = 0x02;
RPC_WRITE = 0x02;
RPC_WRITE_NO_RESP = 0x03;
RPC_WRITE_RES = 0x04;
RPC_NOTIFY = 0x05;
RPC_NOTIFY_RES = 0x06;
}
12 주차#
- 디바이스
- 풀업 저항 낮추어 확인 4.7k, 1k
- 4.7k 낮출 경우 정상 동작 확인
- LED 입력 쪽 임피던스 또는 저항 값에 의한 신호 늘어짐 이슈 예상
- Protobuf 정의
- 형식 변경을 계속 하고 있음
- 디코딩 테스트 중
- 복잡할 수록 패킷이 늘어남 → 단순화 할 필요 있음
- 픽셀 데이터
- 커맨드
- 응답 메시지 별도
- 심플한 RPC 구조를 만드려고 시도 및 테스트 중
- 주요 관심사는 메시지 파싱 시 시간이 오래걸리는 것을 우려
- 간단한 방법은 LED 전용 메시지를 두고 나머지는 세팅 용도 분리
- AT 커맨드는 제외 결정
- 이 경우 시리얼 터미널에서 띄워서 수동 테스트는 불가하게 됨
11 주차#
- 디바이스
- 보드 수령 확인 및 부품 납땜
- 컴퓨터 재 설치에 따른 VS CODE 및 Zephyr 환경 설정
- 보드 테스트
- PIO 로 LED 스트립 출력 확인
- 동작이 가끔 제대로 안됨 (안정성 떨어짐 not stable)
- SPI 방식으로 변경
- 안정적으로 출력 잘 됨
- DMA 출력 일부 검토
- 알고보니 SPI 방식이라 안정적이 아님
- 레벨 쉬프터 쪽 문제가 있어 보임
- 직결 시 문제 없음
- 풀업 저항 값을 낮추어 테스트 예정
- 레벨 쉬프터 쪽 문제가 있어 보임
- PIO 로 LED 스트립 출력 확인
- INA226 테스트
- 전압, 전류, 전력 측정 기능 확인
- Alert 관련 Trigger 부분 미구현이라 커스텀 드라이버 개발 필요
- 애플리케이션
- DXGI HDR 영향 없이 캡쳐 확인
- 성공하지 못했고 방법은 찾았으나 검증이 안됨
- 성공하더라도 처리 시간이 많이 요구 될 것으로 예상
- 일부 색상이 날아가는 것을 감안해야 할 수도
- experience 기능
- DXGI HDR 영향 없이 캡쳐 확인
- 우선 디바이스 테스트 및 기본 기능 구현에 집중
10 주차#
- ReactiveUI 적용
- DXGI 방식 캡쳐 시 HDR 영향
- 톤 매핑으로는 해결 안됨 (톤 매핑 시 뿌옇게 변환)
- 하이라이트로 인해서 원 색상이 날아가버린 것이라 복원 안될 것으로 예상
- HDR 포맷으로 캡쳐 후 변환해야 할 것 같은데 HDR 포맷으로 캡쳐 안되고 있음
9 주차#
- 애플리케이션 캡처 모듈 개선
- ReactiveUI 일부 적용
- 설정 값 저장 및 복원 구성 편의
- 특정 동작 시 UI 조작 허용 및 금지 구성 편의
8 주차#
- 애플리케이션 캡처 모듈 개선
7 주차#
- PCB 아트워크
- 실크 스크린 삽입용 벡터 이미지 제작
- PCB 발주, 부품 주문
- 해외 셀러 부품이 많아서 2주 예상
- 부품 없이 PCB 미리 받아 놓을 이유가 없으므로
- PCB 발주 및 배송도 제일 가격이 저렴한 우편으로 선택 (2주 예상)
5, 6 주차#
- 회로 수정 및 PCB 아트워크
3, 4 주차#
- 쉽니다
2주차#
- 만능기판 뜨개질은 이제 그만
- PCB 아트워크 초안
1주차#
- 회로도 초안 작성
2024년#
52 주차#
- 회로도 초안 작성
- 주요 부품 선정
51 주차#
- 하드웨어 없이 날 코딩하려니 안되겠다
- 보드 회로 설계
- RP2040 기반 쉴드/도터(Daughter) 보드
- 주요 기능
- 외부 전원 입력 및 ON/OFF 제어
- 전력 측정 및 과전류 관련 옵션 고려
- USB 전원이 아닌 외부 전원만으로 동작 고려
- RP2040W (USB 연결 없이 WIFI 통신만 할 경우)
50 주차#
- C# COBS 알고리즘 개발 및 적용
- 시리얼 포트 제어 및 데이터 패킷 프로토타입 정의
- C# Protobuf 적용
49 주차#
- ROI 픽셀 평균 RGB 계산 기능 구현
- 설정 저장 및 복원 기능
- 캡처 모듈 개선 및 시리얼 포트 제어 일부 추가
48 주차#
- 윈폼기반 스크린 캡처 기능 구현
- GDI(Graphics Device Interface) 방식
- 20 ~ 40ms (약 25fps)
- 구현 쉬움, 신경 쓸 요소 없음
- DXGI(DirectX Graphics Interface) 방식
- 9 ~ 15ms (60fps 이상 가능)
- 캡쳐 모듈 정리 시 disposing 철저 필요
- 그렇지 않으면 메모리 누수
- 두 방식 선택 가능한 모듈 구현
- GDI(Graphics Device Interface) 방식
- 모니터 및 스트립 설정
- ROI(관심 영역) 미리 보기 기능 구현
47 주차#
- 플러터 개발 검토
- 시리얼 포트 핸들러 구현
- 연결 및 데이터 수신 테스트
- 리버팟 적용
- 화면 캡쳐 라이브러리 딜레이 시간 검증
- 와우 100ms 이상 측정
- 10 프레임도 안되네 (안될 것 같다)
- 플러터 프로젝트 폐기
- 결국 돌고 돌아 C# 기반 윈폼
- 당분간은 윈도우 전용
- 크로스 플랫폼은 차후 로드맵
46 주차#
- 펌웨어 초기 코드 작성
- 크로스플랫폼 애플리케이션 프레임워크 검토
- 타우리(Tauri)
- 환경 구축 및 UI 작성 용이(스벨트킷 적용)
- Rust 러닝커브(익숙하지 않은 개념, 애플리케이션 개발에 용이할까?)
- 빈약한 시리얼 통신 라이브러리(이벤트, 콜백이 없어서 스레드 폴링 예상)
- 핫 리로드가 되지만 꿈뜬 느낌, 프로젝트 생성만 한 수준인데 중간 빌드 폴더가 5기가 소모(이런!)
- C# 기반(Uno, MAUI, Avalonia)
- 당장 개발 가능한건 윈폼이나 윈도우만 지원해야 하므로 MAUI, 아발로니아, Uno 우선 검토
- XAML가 익숙치 않음 (단일 페이지는 괜찮은데, Fragments가 많으면 복잡할 것 같다)
- 뷰 모델이 무언가 내 기준에서는 직관적으로 보이지 않음
- 개발자 커뮤니티를 보니 쉬운 선택은 아닐 것 같음
- 크로스 플랫폼 캡처 솔루션 미확보
- C 또는 Rust기반 라이브러리를 별도로 빌드하고 연결을 해야 함
- Rust 기반 라이브러리로 시도 했으나 마샬링 문제로 1차 실패
- 플러터(Flutter)
- 언어 자체는 생소한 듯 하나 결국 모던 언어는 거기서 거기
- 러스트에 비하면 내 기준에선 선녀!
- UI 구성은 코드 기반에 익숙해져야 겠지만
- XAML 생각하면 내 기준에선 선녀!
- 상태 관리 및 뷰 모델은 Riverpod 사용 경험이 있으므로 이걸 활용
- 핫 리로드 빠름, 빌드나 디버그 실행 양호
- 크로스플랫폼 시리얼 통신 라이브러리 확인
- 언어 자체는 생소한 듯 하나 결국 모던 언어는 거기서 거기
- 타우리(Tauri)
45 주차#
- COBS 드라이버 GitHub 등록 및 수정
- 제퍼 프로젝트 의존성 관리 용이한 구조 반영
- 소프트웨어 아키텍처 설계
44 주차#
- COBS (Consistent Overhead Byte Stuffing) 드라이버 개발 및 테스트
43 주차#
- 크로스 플랫폼 애플리케이션 개발 환경 검토 (Tauri, Avalonia UI 등 조사)
- Zephyr 프로젝트 기본 구조 결정
- Pico USB 통신 및 처리량(Throughput) 테스트, COBS 드라이버 구현
- 기존 자료 문서화 (노션)
42 주차#
- 주요 컨셉 및 기능 구상, 기술적 고찰
- LED 스트립 관련 정보 수집 (종류, 특징, 통신 방식)
- 기본 개발 장비 준비 (RP2040 및 HAT 구매)
41 주차#
- 프로젝트 전반적인 구상 및 목표 설정
- LED 스트립 구매