astra/iphone-encoder-counter
A CR2450-powered MSP430 FRAM counter combines an always-on dual-channel TMR rotation sensor, pushbutton input, and ST25DV NFC tag with an integrated tuned printed antenna and I²C/GPIO interface.
- Version
- 1.0.3
- License
- unset
- Stars
- 0
scripts/check_antenna.py
from pathlib import Path
import math,json,csv,collections,datetime
r=Path(__file__).resolve().parents[1];j=json.loads((r/'dist/index/circuit.json').read_text())
# Screening estimate only: rectangular-strip partial self-inductance and
# Neumann mutual integrals for pairs of parallel straight segments.
route=next(x['route'] for x in j if x['type']=='pcb_trace' and x.get('pcb_component_id') and len(x['route'])==30)
segments=[];L=0;length=0;w=.00025;t=.000035
for a,b in zip(route,route[1:]):
axis=0 if a['x']!=b['x'] else 1;p=[a['x']/1000,a['y']/1000];q=[b['x']/1000,b['y']/1000];ell=math.dist(p,q);length+=ell
L+=2e-7*ell*(math.log(2*ell/(w+t))+.5+.2235*(w+t)/ell)
segments.append((axis,min(p[axis],q[axis]),max(p[axis],q[axis]),p[1-axis],1 if q[axis]>p[axis] else -1))
for i,(axis,a,b,z,sign) in enumerate(segments):
for axis2,c,d,z2,sign2 in segments[i+1:]:
if axis!=axis2:continue
h=abs(z-z2)
if h==0:continue
def f(x):return x*math.asinh(x/h)-math.sqrt(x*x+h*h)
L+=2e-7*sign*sign2*(f(b-c)-f(a-c)-f(b-d)+f(a-d))
feed={}
for e in j:
if e['type']=='pcb_trace' and str(e.get('pcb_trace_id','')).startswith(('source_net_15','source_net_16')):
feed[e['pcb_trace_id']]=sum(math.hypot(a['x']-b['x'],a['y']-b['y']) for a,b in zip(e['route'],e['route'][1:]) if a['route_type']==b['route_type']=='wire')
report={'status':'NOT RF QUALIFIED; prototype screening only','coil_turns':7,'trace_width_mm':.25,'trace_spacing_mm':.25,'copper_thickness_assumed_um':35,'spiral_length_mm':length*1000,'screening_self_inductance_uH':L*1e6,'dc_resistance_estimate_ohm':1.724e-8*length/(w*t),'required_total_capacitance_at_13_56MHz_pF':1/(L*(2*math.pi*13.56e6)**2)*1e12,'chip_CTUN_pF':{'min':26.5,'typ':28.5,'max':30.5},'C9_pF':15,'assumed_parasitic_pF_for_nominal_screen':3,'nominal_screen_frequency_MHz':1/(2*math.pi*math.sqrt(L*46.5e-12))/1e6,'RF_feed_branches_mm':feed,'limitations':['Model excludes feed inductance, substrate capacitance, RF proximity losses, phone metal, ferrite, magnets and reader coupling','3 pF parasitic capacitance is an assumption, not a measurement','Final enclosure RF tuning and same-phone read/write testing required'],'manufacturer_references':['https://www.st.com/resource/en/application_note/an2972-how-to-design-an-antenna-for-dynamic-nfc-tags-stmicroelectronics.pdf','https://www.st.com/resource/en/datasheet/st25dv04kc.pdf']}
(r/'validation/antenna-audit.json').write_text(json.dumps(report,indent=2)+'\n')
print(json.dumps(report,indent=2))