LabHub
배우기 러닝패스 코스

전자회로 입문 — 센서 입력 검증 · ADC 획득 시간과 채널의 기억 · 실습

온실 센서가 지난 채널을 기억한다

LabHub 에서 이어서 보기

목표

우주 온실의 ADC가 지난 채널 값을 기억하는 현상을 실제 ngspice 파형으로 분석하고, 오차·모델·수렴을 구분한 비교 보고서를 만듭니다.

왜 중요한가

앞의 DC 부하·RC·ADC 단원을 마친 뒤 진행하세요. Python 함수·list·dict·예외·파일 읽기와 지수함수를 사용합니다. 실제 장비에 전압을 인가하지 않습니다. 예상120분이므로 만료 전에 +시간으로 연장하세요. 최대180분이며 세션 종료 시 파일이 사라집니다. 필요한 코드와 보고서를 별도로 보관하세요.

환경과 산출물

산출물은 /root/adc-acquisition/analyze.py입니다. Python3와ngspice42는 이미지에 있습니다. 외부 다운로드·권한 추가는 필요 없습니다. 제공 /opt/lab/fixtures/adc_acquisition/simulator.py의 capture(cfg,새폴더)는 고정 회로를 실제 실행하고 새폴더/trace.tsv 경로를 반환합니다. 같은 폴더에 input.cir·config.json·solver.log도 남기며 기존 폴더를 덮지 않습니다. 분석/판정 정답은 제공하지 않습니다.

파형 생성 도우미는 이론의 회로와 동일한 입력 스위치 모델을 사용합니다. 첫 입력은 high_v,1.8µs부터1.801µs 사이에 low_v로 선형 전환합니다. 제어 펄스는100ns부터 시작, 상승/하강1ns, 고레벨 폭acq_s, 주기1µs입니다. Ron100Ω·Roff10¹²Ω·임계값0.5V·초기 샘플 전압0V입니다. high_v는 첫째 채널이라는 이름일 뿐 low_v보다 낮아도 됩니다.

설정 계약

config는 정확한 dict이며 아래8개 키만 받습니다. 모든 수치는 bool·문자열·NaN·무한대를 거절합니다. bits는 정확한 int, 나머지는 int 또는 float를 받아 float로 반환합니다.

| 키 | 단위와 허용 범위 |
| --- | --- |
| rs_ohm | Ω,100~10000 포함 |
| cap_f | F,10e-12~40e-12 포함 |
| acq_s | s,100e-9~350e-9 포함 |
| dt_s | s,5e-12 또는2.5e-12 |
| high_v·low_v | V,각각0~vref_v 포함, 두 값은 서로 다름 |
| vref_v | V,1~5 포함; 코드 폭 환산용이며 회로 전원 모델 아님 |
| bits | 실제 int,8~16 포함; 코드 폭 환산용 |

파형·관측 계약

read_trace는 일반 파일, 최대256MiB, 빈 줄을 제외한 데이터2~2,000,000행을 받습니다. 헤더는 공백으로 구분한 time v(vin) v(gate) v(hold) 순서입니다. 각 행은 유한 float4개이며 시간은0이상·엄격한 증가, 첫 시간1ns이하, 마지막 시간은3.5µs와 절대1e-15초 이내로 같아야 합니다. 잘못된 내용은 ValueError이고 OS 파일 오류는 전달해도 됩니다. 검증된 points에 대한 sample은 전체 검증을 매 호출마다 반복할 필요가 없습니다.

observe의 관측 시각은 k=0..3에 대해100e-9+k*1e-6+acq_s+27e-9초입니다. 목표 목록은 high_v,high_v,low_v,low_v입니다. 각 hold 끝은 min((k+1)*1e-6+50e-9,3.5e-6)초입니다. 반환 키는 times_s(네 시각), targets_v(네 목표), samples_v(네 저장 전압), hold_drift_v(각 관측부터 hold 끝까지 절대 변화의 최댓값)입니다. 입력·gate·hold 조건을 벗어나면 ValueError입니다. 파형과 설정을 수정하지 않습니다.

예측·판정 계약

predict는 Vnew=Vtarget+(Vold−Vtarget)*exp(−(acq_s+1e-9)/((rs_ohm+100)*cap_f))를 이전 결과에서 이어갑니다. 시작 Vold=0, 목표는 위4개입니다. 꺼진 동안의 유한 누설은 이 해석식에서 무시합니다.

assess는 observed의 samples_v·targets_v만 사용합니다. 길이4·bool 아닌 유한 수치와 설정의 목표 목록을 확인하세요. 반환 키는 max_model_error_v, model_consistent, error_lsb, decision, all_pass입니다. model_error는 관측과 predict의 최대 절대 차이, model_consistent는100µV이하인지의 bool입니다. error_lsb는 각 |관측−목표|를 vref_v/(2**bits)로 나눈4개입니다.

모델이 불일치하면 decision4개 모두 invalid_model입니다. 일치하면 각 절대 전압 오차e에 대해 e+10µV≤0.5LSB이면 pass, e−10µV>0.5LSB이면 fail, 나머지는 borderline입니다. all_pass는 네 개 모두pass일 때만 True입니다. 10µV는 이 실험의 판단 여유 구간이지 실물 계측 불확도의 인증값이 아닙니다.

조건 비교와 CLI 계약

campaign은 정확한 list2~6개의 설정을 받고 모두 검증한 뒤 실행합니다. 모든 입력dt_s는5e-12여야 합니다. runner(cfg)는 파형 파일 경로를 반환하는 제공 호출입니다. 각 조건에서 원 설정 사본으로 runner→analyze, 이어 dt_s만2.5e-12로 바꾼 사본으로 runner→analyze합니다. 한 조건의 두 실행을 끝낸 뒤 다음 조건을 실행하며 원 입력을 바꾸지 않습니다. 실행 예외는 호출자에게 전달합니다.

반환은 schema=1, runs, candidate_indices, scope='ideal-switched-rc-only'입니다. runs는 입력순이며 각 항목에 coarse·fine(각 analyze 보고), difference_v(네 저장 전압의 최대 절대 차이), converged(차이≤10µV bool)를 둡니다. candidate_indices는 수렴하고 양쪽 all_pass가 모두True인 조건의0기반 인덱스 목록입니다. 후보가 없으면 빈 목록이며 오류와 혼동하지 않습니다. 서로 다른 변수를 동시에 바꿨다면 이 목록만으로 원인별 효과를 단정하지 않습니다.

main(argv)는 설정 목록 JSON 파일과 아직 없는 출력 폴더 경로, 두 인자를 받습니다. JSON의 모든 설정과 기본dt를 검증한 다음 출력 폴더를 만듭니다(부모는 이미 있어야 합니다). sys.path에 /opt/lab/fixtures/adc_acquisition을 넣고 simulator.capture를 읽습니다. runner 호출마다 출력폴더/run-00,run-01,...의 새 하위 폴더로 capture를 호출하세요. campaign 결과를 stdout에 JSON한 줄로 출력하고0을 반환합니다. 인자·설정·파일·실행 Exception은 {"error":"analysis_failed"} 한 줄과2를 반환하며 traceback은 출력하지 않습니다. 실패 전 생성된 새 증거는 지우지 않습니다. import 시에는 CLI를 실행하지 않고 직접 실행했을 때만 main의 반환값으로 종료합니다.

단계8의 제공 예제 목록은 /opt/lab/fixtures/adc_acquisition/cases.json입니다. 직접 확인하려면 아래처럼 새 폴더 이름으로 실행하고, 보고서와 함께 input.cir·config.json·solver.log·trace.tsv를 살펴보세요. 보고서 파일도 기존 자료를 덮지 않는 이름을 고릅니다.

python3 /root/adc-acquisition/analyze.py /opt/lab/fixtures/adc_acquisition/cases.json /root/adc-acquisition/trial-01 > /root/adc-acquisition/report-01.json

단계

1. 숫자와 단위를 명시한다: config(value)를 구현합니다. 아래8개 키의 타입·범위를 검사하고 원본을 바꾸지 않은 새 dict를 반환합니다. bits만 int로, 나머지는 float로 정규화하며 잘못된 값은 ValueError입니다.
2. 끝까지 생성된 파형만 읽는다: read_trace(path)는 아래 TSV 계약을 검사해 네 float의 tuple을 담은 list를 반환합니다. UTF-8·공백 구분 헤더, 행·크기·유한 수치·시간 순서·시작/끝 범위를 확인하세요. 빈 줄은 무시합니다. 파형을 고치지 않습니다.
3. 관측 시각을 보간한다: sample(points,when,col=3)는 검증된 파형에서 해당 시각을 선형 보간합니다. col은 실제 int1·2·3, when은 bool 아닌 유한 수치이며 양 끝점은 허용합니다. 시간 범위 밖과 잘못된 열은 ValueError입니다.
4. 입력·스위치·저장 전압을 구분한다: observe(cfg,points)는 config로 검증 후 네 관측 시각과 목표 전압을 계산합니다. 관측 시 gate의 절댓값과 목표 대비 vin 차이는 각각1µV 이하여야 합니다. sample 전압과 hold 끝 전압의 최대 차이도1µV 이하여야 합니다. 아래 관측 dict를 반환합니다.
5. 지난 획득 전압을 이어받는다: predict(cfg)는 설정 검증 후 초기0V에서 첫째 채널 두 번·둘째 채널 두 번을 획득하는 재귀식으로 전압4개의 list를 반환합니다. 연결 시간은 acq_s+1ns, 저항은 rs_ohm+100Ω입니다.
6. 오차·모델·경계 판정을 분리한다: assess(cfg,observed)는 아래 판정 계약대로 LSB 오차, 해석식과의 최대 차이, 모델 일치, 네 표본 판정과 all_pass를 반환합니다. 관측 dict의 samples_v와 targets_v는 유한 수치4개이며 목표 목록이 설정과 다르면 ValueError입니다.
7. 실제 파일에서 보고를 만든다: analyze(cfg,trace_path)는 config→read_trace→observe→assess를 연결해 schema=1, config, observation, assessment 네 키의 dict를 반환합니다. 파일 손상은 성공 보고로 바꾸지 않고 전달합니다.
8. 조건 비교와 실제 CLI를 연결한다: campaign(configs,runner)와 main(argv), CLI 진입점을 아래 계약으로 구현합니다. 모든 설정을 먼저 검증하고 조건마다5ps·2.5ps 파형을 각각 분석해 수렴과 양쪽 판정을 함께 확인합니다. 실제 ngspice·별도 CLI 프로세스로 검사합니다.

참고

채점은 임시 폴더의 별도 파형으로 함수를 검사하고 마지막 단계는 실제 ngspice와 별도 CLI 프로세스도 실행합니다. 학생 폴더를 바꾸지 않으며 검사 전용 폴더만 정리합니다. 예제 숫자만 반환하면 다른 전압 방향과 조건에서 실패합니다. 약70만~140만행 파형을 다루므로 여러 실행을 한꺼번에 띄우지 마세요. 출력 폴더 하나를 보존한 채 결과를 검토합니다.

이상 스위치 RC 모델 안에서만 후보를 고릅니다. 실제 ADC의 전하 주입·잡음·보호 회로·온도·비선형성·실제 버퍼 안정도는 검증하지 않습니다. 장비를 연결하거나 물리 전압을 인가하는 과제가 아닙니다.

단계 8개

  1. 숫자와 단위를 명시한다
  2. 끝까지 생성된 파형만 읽는다
  3. 관측 시각을 보간한다
  4. 입력·스위치·저장 전압을 구분한다
  5. 지난 획득 전압을 이어받는다
  6. 오차·모델·경계 판정을 분리한다
  7. 실제 파일에서 보고를 만든다
  8. 조건 비교와 실제 CLI를 연결한다