Version 8 of A simple voltmeter

Updated 2014-01-28 01:13:56 by uniquename

From a news:comp.lang.tcl posting by Bob Techentin:

I'm looking more for an analog style meter. Kinda like those old volt meter.

Well, if you just want to display, why not write one into a canvas? It's pretty easy, and fun too. Try this:

    # example volt-meter like display
    package require Tk

    grid [canvas .c -width 200 -height 110 -borderwidth 2 -relief sunken]
    grid [scale .s -orient h -from 0 -to 100 -variable v]

    .c create line 100 100 10 100 -tag meter

    trace variable v w updateMeter

    proc updateMeter {name1 name2 op} {
        upvar #0 $name1 v
        set min [.s cget -from]
        set max [.s cget -to]
        set pos [expr {$v / abs($max - $min)}]
        set x [expr {100.0 - 90.0*(cos($pos*3.14))}]
        set y [expr {100.0 - 90.0*(sin($pos*3.14))}]
        .c coords meter 100 100 $x $y
    }

DKF: Here is a slightly more complex version which shows a little bit of history and fades nicely. Isn't Tk wonderful?

 package require Tk
 set ::pi 3.1415927 ;# Good enough accuracy for gfx...

 # Create a meter 'enabled' canvas
 proc makeMeter {w} {
     global meter angle
     canvas $w -width 200 -height 110 -borderwidth 2 -relief sunken -bg white
     for {set i 70;set j 0} {$i<100} {incr i 2;incr j} {
         set meter($j) [$w create line 100 100 10 100 \
                 -fill grey$i -width 3 -arrow last]
         set angle($j) 0
         $w lower $meter($j)
         updateMeterLine $w 0.2 $j
     }
     $w create arc 10 10 190 190 -extent 108 -start 36 -style arc -outline red
     return $w
 }
 
 # Draw a meter line (and recurse for lighter ones...)
 proc updateMeterLine {w a {l 0}} {
     global meter angle pi
     set oldangle $angle($l)
     set angle($l) $a
     set x [expr {100.0 - 90.0*cos($a * $pi)}]
     set y [expr {100.0 - 90.0*sin($a * $pi)}]
     $w coords $meter($l) 100 100 $x $y
     incr l
     if {[info exist meter($l)]} {updateMeterLine $w $oldangle $l}
 }

 # Convert variable to angle on trace
 proc updateMeter {name1 name2 op} {
     upvar #0 $name1 v
     set min [.s cget -from]
     set max [.s cget -to]
     set pos [expr {($v - $min) / ($max - $min)}]
     updateMeterLine .c [expr {$pos*0.6+0.2}]
 }
 
 grid [makeMeter .c]
 grid [scale .s -orient h -from 0 -to 100 -variable v]
 trace variable v w updateMeter

 # Fade over time
 proc updateMeterTimer {} {
     set ::v $::v
     after 20 updateMeterTimer
 }
 updateMeterTimer

uniquename 2014jan27

Here is an image produced by the DKF code, on my Linux (Ubuntu 9.10) installation. The image indicates the needle history and fade that DKF mentions above.

voltmeter_withNeedleFade_wiki877_209x180.jpg


vu has a dial widget.


http://img197.imageshack.us/img197/3789/image49.gif gold added pix