#!/usr/bin/env ruby # encoding: utf-8 # ruby: 1.9 require 'serialport' require './telegram' # print debug info DEBUG = true # connect to PC pc_serial = SerialPort.open("/dev/ttyUSB0",{ baud: 57600, databits: 8, parity: SerialPort::ODD, stop_bit: 1, flow_control: SerialPort::NONE}) # the different baudrates used baudrates = [] baudrates << {baud: 57600, parity: SerialPort::ODD} baudrates << {baud: 115200, parity: SerialPort::ODD} # only used when everything failed # but not fast enough for readpartial #baudrates << {baud: 9600, parity: SerialPort::NONE} baudrate_i = 0 # temporary memeory, in case the PC writes and askes back tmp_memory = [0x00]*8 file = nil while true activities = IO.select([pc_serial]) activities[0].each do |activity| data = activity.readpartial(16+1+5) line = data.unpack("C*").collect { |b| sprintf("%02X ",b) }.join if activity==pc_serial then puts "> "+line if DEBUG begin telegram_in = Telegram.parse(data) if telegram_in then puts "> "+telegram_in.to_s[2..-1] telegram_out = case telegram_in.object when 0 # device type Telegram.new(telegram_in.object,"simulator".bytes.to_a+[0x00],false) when 8 # manufacturer Telegram.new(telegram_in.object,"EA".bytes.to_a+[0x00],false) when 1, 6, 9 # article no., serial no., software version Telegram.new(telegram_in.object,"42".bytes.to_a+[0x00],false) when 2,3,4 # nominal voltage, current, power Telegram.new(telegram_in.object,[42.0].pack("g").bytes.to_a,false) when 19 # device class Telegram.new(telegram_in.object,[0x00,0x10],false) when 54,150,151 # power supply control, unlock code 1, unlock code 2 Telegram.new(0xff,[0x00],false) # no error when 152 # write memory if telegram_in.data.empty? then Telegram.new(telegram_in.object,tmp_memory,false) else tmp_memory = telegram_in.data if telegram_in.data[0]==0x33 then file.close if file and !file.closed? file = File.open(telegram_in.data[1].to_s,"w") elsif telegram_in.data[0]==0x34 then else file.write(telegram_in.data[1..-1].pack("C*")) if file end Telegram.new(0xff,[0x00],false) # no error end else # error: object not defined Telegram.new(0xff,[0x07],false) end if telegram_out then puts "< "+telegram_out.to_s[2..-1] # display message pc_serial.write(telegram_out.pack) # send message end else baudrate_i = (baudrate_i+1)%baudrates.size pc_serial.baud = baudrates[baudrate_i][:baud] pc_serial.parity = baudrates[baudrate_i][:parity] puts "could not parse message: switching baudrate to #{pc_serial.baud} bps" end rescue Exception => e puts e.to_s end else raise "unknown source" end end end