ea-ps_2084-03b/control.rb

120 lines
3.5 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# encoding: utf-8
# ruby: 2.2
require 'serialport'
require './telegram'
DEBUG = false
@serial = SerialPort.open("/dev/ttyACM0",{ baud: 57600, databits: 8, parity: SerialPort::ODD, stop_bit: 1, flow_control: SerialPort::NONE})
# send query/send telegram and return answer
def comm(query,data=nil)
telegram = Telegram.new(query,data)
puts("< "+(telegram.pack.bytes.collect{|b| "%02x" % b})*" ") if DEBUG
@serial.write(telegram.pack)
answer = @serial.readpartial(3+16+1+2)
raise "no answer received to query #{query}" if !answer or answer.empty?
puts("> "+(answer.bytes.collect{|b| "%02x" % b})*" ") if DEBUG
telegram = Telegram.parse(answer)
raise "malformed answer" unless telegram
raise telegram.to_s if (telegram.object==0 and telegram.data.length==2 and telegram.data[0]==0xff) or (telegram.object==255 and telegram.data[0]!=0)
return telegram
end
# get the nominal values (voltage, current)
def nominal_values
return [comm(2).data.pack("C*").unpack("g")[0],comm(3).data.pack("C*").unpack("g")[0]]
end
# get actual values (voltage, current)
def actual_values
telegram = comm(71)
voltage = telegram.data[2,2].pack("C*").unpack("n")[0]/25600.0
current = telegram.data[4,2].pack("C*").unpack("n")[0]/25600.0
nominal = nominal_values
return [voltage*nominal_values[0],current*nominal_values[1]]
end
# get protection values (voltage, current)
def protection_values(voltage=nil,current=nil)
return set_values(voltage,current,true)
end
# set values or get set values (voltage, current)
def set_values (voltage=nil,current=nil,protection=false)
# set query obj and limit
query = (protection ? [38,39,1.1] : [50,51,1.0])
nominal = nominal_values
if voltage then
raise "#{voltage} out of voltage range [0-#{query[2]*nominal[0]}]" if voltage<0 or voltage>query[2]*nominal[0]
comm(54,[0x10,0x10]) # enable remote
value = voltage*25600.0/nominal[0]
comm(query[0],[value].pack('n').bytes)
end
if current then
comm(54,[0x10,0x10]) # enable remote
raise "#{current} out of current range [0-#{query[2]*nominal[1]}]" if current<0 or current>query[2]*nominal[1]
value = current*25600.0/nominal[1]
comm(query[1],[value].pack('n').bytes)
end
voltage = comm(query[0]).data.pack("C*").unpack("n")[0]/25600.0
current = comm(query[1]).data.pack("C*").unpack("n")[0]/25600.0
nominal = nominal_values
return [voltage*nominal_values[0],current*nominal_values[1]]
end
# get device information
def device_info
info = []
[8,19,0,6,1,9].each do |query|
info << comm(query).to_s[2..-1]
end
return info
end
# set output
def output(on)
comm(54,[0x10,0x10]) # enable remote
comm(54,[0x01, on ? 0x01: 0x00]) # set on
end
# set output to on
def on
output(true)
end
# set output
def off
output(false)
end
########
# main #
########
# print device information
puts device_info*"\n"
# set to 0 and let the capacitor discharge
puts "setting to 0"
off
set_values(0.0,1.0)
on
sleep 10
puts "increasing voltage"
puts "set voltage (V),actual voltage (V), measured voltage (V),set ampere (A),actual ampere (A),measured ampere (A)"
voltage = 0.0 # start value
while voltage<=84.0 do
set_values(voltage)
sleep 3
actual = actual_values
set = set_values
measured_voltage = `sigrok-cli --driver uni-t-ut61e-ser:conn=/dev/ttyUSB0 --samples 1 -O analog`.split(" ")[1].to_f
measured_ampere = `sigrok-cli --driver uni-t-ut61e:conn=1a86.e008 --samples 1 -O analog`.split(" ")[1].to_f
puts [set[0],actual[0],measured_voltage,set[1],actual[1],measured_ampere]*","
voltage += 0.1
end
off