I noticed some real severe flaws in the Chinglish interpretation going in both directions - they misinterpreted the near-standard they were copying, and...then documented it in a way no one would "get".
Otherwise, these look like nice supplies at a reasonable price.
There is a fairly serious flaw here, and in fixing it, there might wind up being a lot more to this thread than the usual "here's the review and my code".
USB things, serial emulators specifically, are supposed to report a unique name when the opsys picks them up. In linux, this shows up under /dev/Serial/by-name/.
Now one can write software that looks for a particular piece of gear by name, and it'll always get the right one, or fail. No chance of sending commands to the wrong thing - like windows com ports for example, that can be re-mapped just by replugging a device - it was com2, now it's com11 say. Linux has that functionality too for brain dead coders - in this case serial things are also mapped to ttyUSB# (the # being whatever number) but I and other Linux users are getting spoiled with its superior handling of most things like this.
The TP3005 supplies all report the exact same "unique" ID, which evidently is just the factory one for the USB chip they reverse engineered and stole IP from.
In this case, I got two supplies which will be driving two very different things and sending the commands to the wrong one means smoke and danger. This isn't a cute little oversight on their part.
They all report as: usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 under /dev/serial/, and I'm not yet sure what linux is going to do with two identical file names, probably add (1) at the end of one of them. But that wouldn't tell me which is which, and it matters. This could change depending on what machine it's hooked to, which one powers up first, and any number of other uncontrolled variables.
If I have to use a raspberry pi or ESP8266 for each one to be sure I'm talking to the right one, I'll do that and just build it into the supply itself. Kinda galling to spend that money because some Chinese guy couldn't read or didn't care (this would likely mess up windows too...).
That other mistake is laughable. Anyone who writes any code knows that \n stands for newline, not the two characters slash and enn. This is standard in just about every language, from C to Java, to python, to perl...the slash means "next character should use a special interpretation". Guess what? Where the standard format used by tektronix, GW Insek and others shows a command followed by \n, they mean newline, no programmer needs that explained. Except the guys at Tekpower, evidently. I couldn't get it going from a terminal emulator at first, till I really looked at the python code written by a third party and shared and noticed \\n - which means "escape the slash and in this case send it literally" and of course, now the n is just an n. Yup, that's what this brain-dead thinks is the command delimiter - not the new line, but a literal '\n'!
I'm writing a nice little perl gui, but if I can't come up with a software fix for the "don't know which unit" problem, it may go much further, as it really matters here, and no, I can't afford another few minutes of setup on every run especially if it requires physical presence to do it.
Here's some python contributed by a guy who goes by Circumflex designs:
http://www.circumflex.systems/
- Code: Select all
# Circumflex Designs 2017
#
# init_comm(port_name) Opens named com port and initializes comm
# end_comm() Closes comm port
#
# output_state(out_on) If state is < 1 then output is turned off. Otherwise, it is turned on.
#
# volts_setpoint_set(volts) Sets output voltage to volts
# volts_setpoint_get() Returns voltage setpoint from power supply
# volts_meas() Returns the output voltage measurement from the power supply
#
# amps_setpoint_set(amps) Sets output current (limit) to amps
# volts_setpoint_get() Returns current setpoint from power supply
# volts_meas() Returns the output current measurement from the power supply
#
# status_get() Returns the power supply status flags
#
import serial
import time
#Create the global serial object
ser1 = serial.Serial()
#Time delay - should instead use time.sleep()
def delay(secs):
start = time.time()
while ((time.time() - start) < secs):
continue
#Initiate comm with PS
def init_comm(port):
global ser1
ser1 = serial.Serial(port, 9600, timeout=1)
print(ser1.name)
print ("Serial Port is Open: %d\n" % ser1.is_open)
ser1.reset_input_buffer()
ser1.reset_output_buffer()
time.sleep(1)
print (status_get())
time.sleep(0.1)
def end_comm():
ser1.close()
def output_state(out_on):
time.sleep(0.05)
if out_on >= 1:
cmd = b'OUTPUT1:\\r\\n'
print("Output On")
else:
cmd = b'OUTPUT0\\r\\n'
print ("Output Off")
ser1.write(cmd)
#print (cmd)
#print (out_on)
time.sleep(0.05)
def volts_setpoint_set(volts):
time.sleep(0.05)
cmd = b'VSET1:' #b'VSET1:07.00\\r\\n'
cmd = cmd + format(volts, "=05.2F").encode('ascii')
cmd = cmd + b'\\r\\n'
ser1.write(cmd)
#print(cmd)
def volts_setpoint_get():
time.sleep(0.05)
cmd = b'VSET1?\\r\\n'
ser1.write(cmd)
line = ser1.readline()
#print("Response: %s" % line)
volts = float(line.decode('utf8'))
return volts
def volts_meas():
time.sleep(0.05)
cmd = b'VOUT1?\\r\\n'
ser1.write(cmd)
line = ser1.readline()
#print("Response: %s" % line)
volts = float(line.decode('utf8'))
return volts
def amps_setpoint_set(amps):
time.sleep(0.05)
cmd = b'ISET1:' #b'ISET1:2.500\\r\\n'
cmd = cmd + format(amps, "=05.3F").encode('ascii')
cmd = cmd + b'\\r\\n'
ser1.write(cmd)
#print(cmd)
def amps_setpoint_get():
time.sleep(0.05)
cmd = b'ISET1?\\r\\n'
ser1.write(cmd)
line = ser1.readline()
#print("Response: %s" % line)
amps = float(line.decode('utf8'))
return amps
def amps_meas():
time.sleep(0.05)
cmd = b'IOUT1?\\r\\n'
ser1.write(cmd)
line = ser1.readline()
#print("Response: %s" % line)
amps = float(line.decode('utf8'))
return amps
def status_get():
time.sleep(0.05)
cmd = b'STATUS?\\r\\n'
ser1.write(cmd)
line = ser1.readline()
#print("Response: %s" % line)
status = int(line.decode('utf8'))
return status
# Test Program
def test():
init_comm("Com4")
volts_setpoint_set(5.5)
amps_setpoint_set(0.50)
output_state(1)
time.sleep(1)
print ("Setpoints")
print (volts_setpoint_get())
print (amps_setpoint_get())
print ()
for i in range(5):
volts_setpoint_set((i+1) * 1)
time.sleep(0.5)
print (volts_meas())
print (amps_meas())
print()
print (status_get())
output_state(0)
print (status_get())
end_comm()
print("Done\n")
#test()
Displaying TP3005P.py.
Which I presume he meant to share - and as I messaged him, he should point out at least that last killer error as most troubleshooting technique would have issues finding that bug.
I'm coming up with a cute little GUI for this, but as mentioned, it might have to be in an ESP8266 web page and need one of those per supply to be safe for remote control.
For reference the manual - no programmer I know would have read this as putting in a literal /n.
More soon, I hope.