ea-ps_2084-03b/demo.rb

116 lines
3.3 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# encoding: utf-8
# ruby: 1.9
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.to_a.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.to_a.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.to_a)
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.to_a)
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 42V for 10s"
off
set_values(42.0,0.1)
on
sleep 10
off
comm(54,[0x10,0x00])
puts "tracking values"
while true
actual = actual_values
set = set_values
protection = protection_values
puts "voltage (V): #{actual[0].round(2).to_s}/#{set[0].round(2).to_s} (max #{protection[0].round(2).to_s}), current (A): #{actual[1].round(2).to_s}/#{set[1].round(2).to_s} (max #{protection[1].round(2).to_s})"
sleep 1
end