#!/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