Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Ruby implementation of KORAD KA series power supplies communication protocol. Verified on KA3005P only, but should work also with all supplies of series, including multichannel ones.
require 'rubygems'
require 'serialport'
class Korad
def initialize(port="/dev/ttyACM0", baud=9600)
@serial = SerialPort::open(port,baud)
@serial.read_timeout = 100
end
def get_status
command("STATUS?")
@serial.read(1).ord.to_s(2)
end
def get_idn
return feedback_command("*IDN?")
end
def turn_on
command("OUT1")
end
def turn_off
command("OUT0")
end
def recall_memory(bank)
command("RCL#{bank}")
end
def save_memory(bank)
command("SAV#{bank}")
end
def turn_on_OCP
command("OCP1")
end
def turn_off_OCP
command("OCP0")
end
def turn_on_OVP
command("OVP1")
end
def turn_off_OVP
command("OVP0")
end
def set_tracking_mode(value = :independent)
mode = [:independent, :series, :parallel].index(value)
mode ? command("TRACK#{mode}") : raise(Exception.new("UnknownModeException"))
end
def set_current(channel, value)
command("ISET#{channel}:#{value}")
end
def set_voltage(channel, value)
command("VSET#{channel}:#{value}")
end
def get_stored_current(channel)
return feedback_command("ISET#{channel}?")
end
def get_stored_voltage(channel)
return feedback_command("VSET#{channel}?")
end
def get_output_current(channel)
return feedback_command("IOUT#{channel}?")
end
def get_output_voltage(channel)
return feedback_command("VOUT#{channel}?")
end
private
def feedback_command(text)
command(text)
filtered_output
end
def command(text)
@serial.write(text)
end
def filtered_output
result = @serial.read(200)
result ? result.each_byte.reject{|i| i== 1}.map{|a| a.chr}.join : result
end
end
#example:
korad = Korad.new
puts korad.set_voltage(1,7)
sleep(0.1)
puts korad.get_idn
@k-nowicki

This comment has been minimized.

Copy link
Owner Author

@k-nowicki k-nowicki commented Apr 16, 2013

This is not a gem yet, but will be soon I hope.

To use this lib you need Ruby with rubygems, and serialport gem.

You should also be able to use it on Windows, just change port in line 5 (for example: port="COM1").
Look also at http://rubyinstaller.org/ if that applies to you.

Released under the MIT License.

@quetzalcoatl

This comment has been minimized.

Copy link

@quetzalcoatl quetzalcoatl commented Jun 7, 2013

Hi there. I stumbled onto your code snipped while searching for any information about 'programmable power supply' that I recently bought. Within 3 hours of use, I got totally irritated by Chineese malfunctioning software included with it and after some digging I've found that my Axiomet AX-6002P is probably just rebranded KORAD-6002P - and even software from KA6002P worker with my device :) The devices look almost identical, but at the first sight their protocol does not match what you wrote here - my one seems to use simple binary protocol over virtual comport over usb. That's a bit strange, but it is possible that actually these devices support two parallel protocols: ascii and binary. Binary packets seem to always start with 0xAA byte which is outside normal ascii charset. Anyways, as just 2 months passed since you published it, I'm just writing to let you know that I'll be digging in the same subject.

@vitiral

This comment has been minimized.

Copy link

@vitiral vitiral commented Sep 12, 2014

Hey, do you have a link to the programming guide where you got these commands? I can't find it anywhere!

@keesj

This comment has been minimized.

Copy link

@keesj keesj commented Nov 18, 2014

A "python" version also Released under the MIT License.

#!/usr/bin/env python
import serial
from time import sleep

class Korad:
  def __init__(self,port):
     self.ser =serial.Serial(port, 9600, timeout=1)

  def get_status(self):
    self.command("STATUS?")
    return ord(self.ser.read(1))

  def get_idn(self):
    return self.feedback_command("*IDN?")

  def turn_on(self):
    self.command("OUT1")

  def turn_off(self):
    self.command("OUT0")

  def recall_memory(self,bank):
    self.command("RCL%s" % bank)

  def save_memory(self,bank):
    self.command("SAV%s" % bank)

  def turn_on_OCP(self):
    self.command("OCP1")

  def turn_off_OCP(self):
    self.command("OCP0")

  def turn_on_OVP(self):
    self.command("OVP1")

  def turn_off_OVP(self):
    self.command("OVP0")

#  def set_tracking_mode(value = :independent)
#    mode = [:independent, :series, :parallel].index(value)
#    mode ? command("TRACK#{mode}") : raise(Exception.new("UnknownModeException"))
#  end

  def set_current(self,channel,value):
    self.command("ISET%s:%s" % ( channel, value))

  def set_voltage(self,channel, value):
    self.command("VSET%s:%s" % ( channel, value))

  def get_stored_current(self,channel):
    return feedback_command("ISET%s?" % channel)

  def get_stored_voltage(self,channel):
    return feedback_command("VSET%s?" % channel)

  def get_output_current(self,channel):
    return feedback_command("IOUT%s?" % channel)

  def get_output_voltage(self,channel):
    return feedback_command("VOUT%?" % channel)

  def feedback_command(self,text):
      self.command(text)
      return self.filtered_output()

  def command(self,text):
    sleep(0.1)
    self.ser.write(text)

  def filtered_output(self):
    return self.ser.read(200)

# example 
korad =  Korad('/dev/ttyACM0')
korad.set_voltage(1,7)
print korad.get_idn()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment