Version 11 of A simple voltmeter

Updated 2022-03-28 12:20:09 by APE

See Also

VUW Widgets
Provides a dial widget

Description

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 add variable v write 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 add variable v write updateMeter

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

uniquename 2014-01-27:

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


simple voltmeter screen.png

A simple voltmeter screen.png gold added pix