#!/usr/bin/wish -f

wm title . "4-20mA utility"

#Description: This utility is used to calculate various units used in 4-20mA circuits like:
# Percentage(0-100)
# Raw numeric (6400-32000)
# Current(4-20mA)
# Voltage across 250R reisistor (1-5V)

#Set up default value(s)
set percentage 0

#Set up widgets
label .percentage -justify right -text "%"
entry .percentage_entry -textvariable percentage -justify right
label .numeric -text "6400-32000"
entry .numeric_entry -textvariable numeric -justify right
label .current -text "mA"
entry .current_entry -textvariable current -justify right
label .voltage -text "V across 250R"
entry .voltage_entry -textvariable voltage -justify right

#Place widgets
grid .percentage -row 0 -column 1 -sticky "w"
grid .percentage_entry -row 0 -column 0
grid .numeric -row 1 -column 1 -sticky "w"
grid .numeric_entry -row 1 -column 0
grid .current -row 2 -column 1 -sticky "w"
grid .current_entry -row 2 -column 0
grid .voltage -row 3 -column 1 -sticky "w"
grid .voltage_entry -row 3 -column 0

bind . <Control-q> exit

bind .percentage_entry <Escape> {
	setpercentage 0
}

bind .percentage_entry <KeyRelease> {
	if {$percentage <= 100 && $percentage >= 0} {
		numeric_calc $percentage
		current_calc $numeric
		voltage_calc $current
		.percentage_entry configure -bg  "#d9d9d9" -fg black
	} else {
		.percentage_entry configure -bg red -fg white
	}
}

bind .numeric_entry <KeyRelease> {
	if {$numeric <= 32000 && $numeric >= 6400} {
		current_calc $numeric
		voltage_calc $current
		percentage_calc $voltage
		.numeric_entry configure -bg  "#d9d9d9" -fg black
	} else {
		.numeric_entry configure -bg red -fg white
	}
}

bind .current_entry <KeyRelease> {
	if {$current <= 20 && $numeric >= 4} {
		voltage_calc $current
		percentage_calc $voltage
		numeric_calc $percentage
		.current_entry configure -bg  "#d9d9d9" -fg black
	} else {
		.current_entry configure -bg red -fg white
	}
}

bind .voltage_entry <KeyRelease> {
	if {$voltage <= 5 && $numeric >= 1} {
		percentage_calc $voltage
		numeric_calc $percentage
		current_calc $numeric
		.voltage_entry configure -bg  "#d9d9d9" -fg black
	} else {
		.voltage_entry configure -bg red -fg white
	}
}

# Initialize focus onto first entry box
proc setpercentage {n} {
	focus .percentage_entry
	.percentage_entry delete 0 end
	.percentage_entry selection adjust end
	.percentage_entry icursor end
	.percentage_entry insert 0 $n
}

#convert entered value into a decimal value
proc oct2dec {oct} {
  set dec [scan [string trimleft $oct 0] %f]
  if {[string length $dec] == 0 } {set dec 0}
  if {$dec == "{}" } {set dec 0}
  set output [string length $dec]
  return [expr {$dec}]
}


# determine numeric 6400-32000 value from percentage value 0-100
proc numeric_calc {n} {
	set numeric [expr [oct2dec $n] * 256.0 + 6400.0]
	.numeric_entry delete 0 end
	.numeric_entry insert 0 $numeric
}

# determine current 4.00-20.00 value from numeric value 6400-32000
proc current_calc {n} {
	set current [expr [oct2dec $n] / 1600.0]
	.current_entry delete 0 end
	.current_entry insert 0 $current
}

# determine voltage 1.00-5.00 value from current value 4-20
proc voltage_calc {n} {
	set voltage [expr [oct2dec $n] * .250]
	.voltage_entry delete 0 end
	.voltage_entry insert 0 $voltage
}

# determine percentage 0-100 value from voltage value 1-5
proc percentage_calc {n} {
	set percentage [expr ([oct2dec $n] -1.0) * 25.0]
	.percentage_entry delete 0 end
	.percentage_entry insert 0 $percentage
}


setpercentage 0
numeric_calc $percentage
current_calc $numeric
voltage_calc $current
