Posted to tcl by jima at Thu Jun 12 18:50:58 GMT 2014view pretty

# demonstration of VecTcl computing
# the impedance of serial RCL resonator circuit

# this proc should really go into the VecTcl core
vproc logspace {from to N} {
	10.^linspace(from, to, N)
}

# compute pi. Should actually be in the core somehow
vexpr { pi=4*atan(1) }

# the impedance of a serial circuit
vproc Z {omega R C L} {
	R + 1i*omega*L + 1.0/(1i*omega*C)
}

# create a toplevel with a plot for amplification and phase 
# and 3 sliders to control it

toplevel .circ
set mfr [ttk::frame .circ.mfr]
pack $mfr -expand yes -fill both


ukaz::graph $mfr.gv -width 600 -height 340
ukaz::graph $mfr.gph -width 600 -height 340

ttk::label $mfr.r_label -textvariable Rlabel
ttk::scale $mfr.r -variable Rlog -from 0.0 -to 1.0 -command updatePlot

ttk::label $mfr.l_label -textvariable Llabel
ttk::scale $mfr.l -variable Llog -from 0.0 -to 1.0 -command updatePlot

ttk::label $mfr.c_label -textvariable Clabel
ttk::scale $mfr.c -variable Clog -from 0.0 -to 1.0 -command updatePlot

grid $mfr.gv - -sticky nsew
grid $mfr.gph - -sticky nsew
grid $mfr.r_label $mfr.r -sticky nsew
grid $mfr.l_label $mfr.l -sticky nsew
grid $mfr.c_label $mfr.c -sticky nsew

grid columnconfigure $mfr 1 -weight 1
grid rowconfigure $mfr 0 -weight 1
grid rowconfigure $mfr 1 -weight 1


set Rlog 0.5
set Llog 0.5
set Clog 0.5

# plot some dummy data
set vid [$mfr.gv plot {1 2 1 2} w l color blue title "Voltage over resistor"]
set phid [$mfr.gph plot {1 2 1 2} w l color red title "Phase"] 

$mfr.gv set log x
$mfr.gph set log x

$mfr.gv set yrange 0.0 1.0
$mfr.gph set yrange {*}[vexpr {list(-pi/2, pi/2)}]

proc updatePlot {args} {
	
	vexpr {
		# base values
		R0=5.0; # 5 ohms
		L0=7e-3 ;# 7 mH
		C0=10e-6 ; # 10µF
		R=R0*20^::Rlog
		C=C0*20^::Clog
		L=L0*20^::Llog
		wres = 1.0/sqrt(L*C)
	}
	
	# create text for description
	set ::Llabel [format "L = %g mH" [expr {$L/1e-3}]]
	set ::Rlabel [format "R = %g \u03a9" $R]
	set ::Clabel [format "C = %g \u03bcF" [expr {$C/1e-6}]]
	#puts "Resonance: $wres"
	
	vexpr {
		# create frequency data
		f=logspace(1,3,300)
		omega=2*::pi*f
		# compute impedance of total resonator
		Z=Z(omega, R, C, L)
		# compute voltage at the resistor
		Vres=R/Z
		# split into absolute value and phase
		Vabs=abs(Vres)
		Vph =arg(Vres)
		# create interleaved lists for Vabs and Vph
		Vabs=interleave(f, Vabs)
		Vph= interleave(f, Vph)
	}

	$::mfr.gv update $::vid data $Vabs
	$::mfr.gph update $::phid data $Vph

}

vproc interleave {x y} {
	# from two vectors of equal length
	# create an interleaved vector. This is needed
	# for e.g. canvas lines or ukaz::graph
	N=rows(x)
	z=hstack(x,y)
	reshape(z,2*N)
}

updatePlot