전자회로 입문 — 센서 입력 검증 · 필터 차수·부하·주파수 응답 · 실습
RC를 두 번 붙이면 해결될까
목표
온실 센서용 필터를 차수·부하·주파수·시간 응답으로 비교하고, 실제 ngspice 자료를 보존한 검증 CLI를 만듭니다.
왜 중요한가
앞의 앨리어싱 단원과 Python 함수·파일·복소수·list·dict·예외를 알고 진행하세요. 실습120분을 예상하므로 기본60분이 끝나기 전에 +시간으로 연장하세요. 최대180분이며 세션 종료 시 파일이 사라집니다. 필요한 코드와 보고서를 별도로 보관하세요. 실제 장비나 물리 전압을 다루지 않습니다.
환경과 파일
산출물은 /root/filter-response/analyze.py입니다. Python3·ngspice42가 이미지에 있으며 외부 다운로드·추가 권한은 필요 없습니다. /opt/lab/fixtures/filter_response를 sys.path에 추가하면 simulator를 import할 수 있습니다. 제공 capture(cfg,새폴더)는 실제 회로를 실행하고 출력 폴더 Path를 반환합니다. 그 안에 input.cir·config.json·solver.log·ac.tsv·pass.tsv·stop.tsv·step.tsv를 남깁니다. 기존 폴더는 덮지 않으며 부모는 이미 있어야 합니다.
회로는 이론에 있는 네 구조 그대로입니다. AC 입력은 ac_v 진폭과23도 위상입니다. 계단 입력은0~1ms에0V, 다음1µs에1V로 상승하고50ms까지 유지됩니다. 이상 버퍼는 무한 대역폭·무제한 출력의 제어 전압원이며 실물 연산증폭기가 아닙니다.
설정 계약
config는 정확히 아래5키를 가진 dict만 받습니다. 수치는 int·float만 받고 bool·문자열·NaN·무한대·float 변환 범위 초과를 ValueError로 거절합니다. 수치는 float로 반환하고 topology는 str, Q가 없는 경우는None을 유지합니다.
| 키 | 허용 값 |
| --- | --- |
| topology | rc1, rc2-loaded, rc2-buffered, sk2 중 하나 |
| f0_hz | 220 또는300 |
| q | sk2이면0.5,1/math.sqrt(2),1.4 중 하나; 다른 회로는None만 |
| dt_s | 5e-6 또는2.5e-6 |
| ac_v | 0.5,1,2 중 하나 |
f0_hz는 주파수 척도이며 모든 회로의−3dB 주파수를 뜻하지 않습니다. R=1000Ω, C=1/(2πRf0_hz)입니다. sk2만 C1=2qC·C2=C/(2q), 나머지는 이론처럼 같은R·C를 사용합니다. q=1/sqrt(2)는 JSON에0.7071067811865475로 기록합니다.
AC 파일과 Bode 계약
read_ac의 kind는 sweep·pass·stop 중 하나입니다. 파일은 일반 파일·최대1MiB이며 헤더는 공백으로 구분한 frequency v(in) v(in) v(out) v(out)입니다. 빈 줄은 무시합니다. 각 데이터 행은 유한 float5개, 전압 성분 절댓값≤1e6, 복소 입력 크기≥1e-12입니다. 주파수는 양수·엄격히 증가해야 합니다. 내용 오류는ValueError, OS 파일 오류는 전달해도 됩니다.
- sweep: 정확히241행, i=0..240에서 주파수10*10**(i/80), 시작10Hz·끝10000Hz.
- pass: 정확히3행,125·126·127Hz.
- stop: 정확히3행,875·876·877Hz.
첫 주파수는 명시값에서1e-8Hz 이내, 마지막은1e-7Hz 이내여야 합니다. 모든 내부 주파수는 지정 격자와 상대1e-10 또는 절대1e-9 이내로 같아야 합니다. 시작·끝만 검사하지 않습니다. 반환은5개 float tuple의 list입니다.
bode는 검증된 rows를 받고 원본을 바꾸지 않습니다. H=complex(출력실수,출력허수)/complex(입력실수,입력허수)입니다. 각 반환 dict의 키는 frequency_hz, h_re, h_im, gain=abs(H), db=20log10(gain), phase_deg=degrees(atan2(H.imag,H.real))입니다. gain=0이면 db와phase_deg는None입니다. 목록 순서는 유지합니다.
모델과 계단 관측 계약
transfer는config로 설정을 검증하고0≤freq≤1e6의 유한 수치를 받습니다. p=1j*freq/f0_hz일 때 rc1:1/(1+p), rc2-loaded:1/(1+3p+p²), rc2-buffered:1/(1+p)², sk2:1/(1+p/q+p²)를 complex로 반환합니다.
제공 simulator.load_step(path)는 time v(in) v(out) 헤더의 최대8MiB·데이터2~100000행을 검증해3열 tuple 목록을 반환합니다. 모든 값은 유한하며 전압 절댓값≤1e6, 시간은0이상·엄격한 증가입니다. 첫 시간≤1µs, 마지막은50ms에서1e-12초 이내여야 합니다. 내용 오류는ValueError입니다. 학생이 이 로더를 다시 구현할 필요는 없습니다.
measure_step은 로더를 사용하고 t=0.001001+i*1e-5(i=0..4899)에서 출력 전압을 선형 보간합니다. 정확한 행은 그대로 읽고 외삽은ValueError입니다. 반환 키는 samples_v(4900전압), overshoot_v=max(0,max(samples_v)−1), settled_at_s, grid_step_s=1e-5, observation_end_s=0.001001+4899*1e-5입니다.
settled_at_s는1.001ms 상승 완료 기준 상대 시간입니다. |전압−1|>.02인 마지막 표본의 다음 인덱스*1e-5를 반환합니다. 마지막 표본도 밖이면None, 모두 안이면0입니다. 이것은 관측 격자·유한 관측 구간에서의 판정이며 연속 시간 최대값이나 무한 시간 안정성 증명이 아닙니다.
판정과 분석 계약
assess는 정상 설정, bode의sweep 목록,125Hz의wanted dict,875Hz의nuisance dict,measure_step의step dict를 받습니다. 전달된 중간 보고가 위 계약을 따르는 것은 전제이며 전체 구조 검증을 반복할 필요 없습니다. 반환 키는 다음과 같습니다.
- max_model_error: sweep과wanted·nuisance 전부에서 complex(h_re,h_im)와transfer의 차이 크기 중 최댓값. 단위는 전압이 아니라 이득입니다.
- model_consistent: 오차≤1e-8.
- passband_ok: wanted.gain≥.9. 이 요구에는 상한이 없습니다.
- stopband_ok: nuisance.gain≤.1.
- step_ok: overshoot_v≤.05이고 settled_at_s가None이 아니면서≤.01.
- all_pass: 위 model_consistent·passband_ok·stopband_ok·step_ok가 모두True.
analyze(value,folder)는 config, read_ac, bode, measure_step, assess를 연결합니다. 반환은 schema=1, config, sweep, wanted, nuisance, step, assessment입니다. ac.tsv는sweep, pass.tsv·stop.tsv는 각각pass·stop으로 읽고 첫 항목을wanted·nuisance로 사용합니다. 원 파일과 원 설정을 변경하지 않고 오류는 전달합니다.
조건 비교와 CLI 계약
campaign(values,runner)는 정확한list2~6개의 설정을 모두 먼저 검증합니다. 입력dt_s는 전부5e-6이어야 합니다. 각 조건에 대해 runner(기본설정사본)→analyze, 이어dt_s만2.5e-6으로 바꾼 새 설정으로runner→analyze합니다. 한 조건을 끝낸 다음 다음 조건을 실행합니다. runner의 예외는 전달하며 원 입력은 바꾸지 않습니다.
반환은 schema=1, runs, candidate_indices, scope='ideal-linear-filters-and-finite-step-observation'입니다. runs는 입력순이며 coarse·fine(각analyze 보고), difference_v(같은4900시각 표본의 최대 절대 차이), converged(차이≤1e-5V)를 담습니다. candidate_indices는 수렴하고 양쪽assessment.all_pass가True인 조건의0기반 인덱스 목록입니다. 빈 후보는 정상 결과이며 실행 오류와 구별합니다.
main(argv)는 설정 목록JSON 파일과 아직 없는 출력 폴더 경로를 받습니다. JSON의 모든 설정과 기본dt를 확인한 뒤 폴더를 만듭니다. 부모는 이미 있어야 합니다. runner 호출 순서대로 run-00,run-01,... 새 하위 폴더에서 제공capture를 호출합니다. 결과를stdout JSON한 줄로 출력하고0을 반환합니다. 인자·설정·파일·실행 Exception이면 {"error":"analysis_failed"} 한 줄과2를 반환하며traceback을 출력하지 않습니다. 이미 생성한 새 증거는 실패해도 지우지 않습니다. import에서는CLI를 실행하지 않고 직접 실행일 때만main의 반환값으로 종료합니다.
제공 설정은 /opt/lab/fixtures/filter_response/cases.json입니다. 최종 단계에서 다음처럼 새 이름으로 실행하고 보고서와 함께 원 파일을 확인하세요. 리다이렉트도 이전 보고서를 덮지 않는 경로로 고릅니다.
python3 /root/filter-response/analyze.py /opt/lab/fixtures/filter_response/cases.json /root/filter-response/trial-01 > /root/filter-response/report-01.json단계
1. 회로 조건을 먼저 검증한다: /root/filter-response/analyze.py에 config(value)를 구현합니다. 아래5키 설정을 검증해 수치를 float로 정규화한 새 dict를 반환합니다. 잘못된 값은 ValueError이며 원 입력은 바꾸지 않습니다.
2. 복소 전압의 다섯 열을 읽는다: read_ac(path,kind="sweep")를 추가합니다. 아래 파일·격자 계약을 검사한 뒤 주파수·입력 실수부·입력 허수부·출력 실수부·출력 허수부 tuple의 list를 반환합니다.
3. 입력 진폭과 위상을 제거한다: bode(rows)를 추가합니다. 검증된 각 행에서 복소 출력/입력을 구해 주파수·복소 이득·크기·dB·위상 목록을 아래 형식으로 반환합니다.
4. 부하를 포함한 전달함수를 계산한다: transfer(cfg,freq)를 추가합니다. 설정과 주파수를 검증하고 이론의 네 회로 전달함수를 complex로 반환합니다.
5. 마지막 대역 이탈을 찾는다: measure_step(path)를 추가합니다. 제공 load_step으로 원 파형을 읽고 지정한4900시각에서 출력 전압을 선형 보간합니다. 초과 전압·정착 시점·관측 격자·표본을 반환합니다.
6. 주파수와 시간 요구를 함께 판정한다: assess(cfg,sweep,wanted,nuisance,step)를 추가합니다. 모든 AC 점의 복소 모델 오차, 두 요구 주파수의 이득, 계단 초과·정착 요구를 따로 계산하고 최종 AND를 반환합니다.
7. 파일에서 검증 보고를 만든다: analyze(value,folder)를 추가합니다. 설정과 AC3파일·계단1파일을 읽어 전체 분석과 판정을 연결합니다. 오류는 성공 보고로 바꾸지 않고 전달합니다.
8. 두 계산 정밀도와 실제 CLI를 연결한다: campaign(values,runner), main(argv), CLI 진입점을 추가합니다. 모든 설정을 검증한 뒤 각 회로를5µs·2.5µs로 실행하고 수렴과 양쪽 설계 판정을 만족한 조건만 선택합니다.
참고
채점은 임시 파일의 순수 함수 검사와 실제 ngspice·별도CLI 실행을 구분해 수행합니다. 학생의 코드와 폴더는 바꾸지 않습니다. 수치 표를 하드코딩하면 다른 입력 진폭·주파수·부하 조건에서 실패합니다. 이번 선택은 이상 선형 모델 안의 후보입니다. 실제 증폭기 전원·대역폭·슬루율·잡음·부품 공차·온도 신뢰성은 별도 검증이 필요합니다.
단계 8개
- 회로 조건을 먼저 검증한다
- 복소 전압의 다섯 열을 읽는다
- 입력 진폭과 위상을 제거한다
- 부하를 포함한 전달함수를 계산한다
- 마지막 대역 이탈을 찾는다
- 주파수와 시간 요구를 함께 판정한다
- 파일에서 검증 보고를 만든다
- 두 계산 정밀도와 실제 CLI를 연결한다