这个周末我要做一个小项目。我得到了一个太阳能电池逆变器(Danfoss ULX 3600i),我将尝试连接到我的linux机器,看看我是否可以从它获取数据,产生了多少能量,例如统计数据。上面有一个用于RJ45连接的输入,但使用的是RS485。
我得到了电缆连接它通过我的通用串行总线端口在电脑和变频器之间的RS485转换器。
然后,我编写了一小段python代码来发出请求。然而,我不知道如何正确地发送数据。
import serial
import struct
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
print(ser.isOpen())
thestring = "7E FF 03 00 01 00 02 0A 01 C8 04 D0 01 02 80 00 00 00 00 8E E7 7E"
data = struct.pack(hex(thestring))
#data = struct.pack(hex, 0x7E, 0xFF, 0x03, 0x00, 0x01, 0x00, 0x02, 0x0A, 0x01, 0xC8, 0x04, 0xD0, 0x01, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x8E, 0xE7, 0x7E)
ser.write(data)
s = ser.read(1)
print(s)
ser.close()
逆变器使用丹佛斯ComLynx协议(在page 26上是我试图发送的数据):
编辑:我现在可以发送一个请求,因为Adam 4520 RS485转换器上的发光二极管指示灯闪烁了一次,但是没有数据返回,但当我在终端中执行CTRL+C时得到以下错误:
dontommy@dtbeast:~/workspace/python_scripting/src$ ./sollar.py
True
^CTraceback (most recent call last):
File "./sollar.py", line 30, in <module>
s = ser.readline().decode('utf-8')
File "/usr/local/lib/python3.2/dist-packages/serial/serialposix.py", line 446, in read
ready,_,_ = select.select([self.fd],[],[], self._timeout)
KeyboardInterrupt
发布于 2013-03-26 17:12:28
将"thestring“重写为
thestring = "\x7E\xFF\x03\x00\x01\x00\x02\x0A\x01\xC8\x04\xD0\x01\x02\x80\x00\x00\x00\x00\x8E\xE7\z7E"
你不需要打包它,你可以说data=thestring然后发送它。仅当文档中的各种is与设备上的is完全匹配时,此操作才有效
您需要弄清楚python “结构”是如何工作的,如何对二进制文件进行编码,以及如何将两个4位值放入一个8位字节中:提示,请参阅>>和<<操作符以及struct pack "B“格式
发布于 2017-11-23 02:10:30
我尝试了许多方案来将我的十六进制字符的命令字符串转换为字节,在UART的远端被识别为十六进制,然后确定下面的方案。我选择一次发送一个字节的字符串,因为远端一次不能处理超过四个字节,所以我不能发送整个字符串。单个hex_byte的格式类似于C中的sprintf。
import time
import serial
import sys
import binascii
import inspect
# This function takes a command string and sends individual bytes.
# It also reports the response.
def send_command(cmd_name, cmd_string):
print ("\ncmd_name:", cmd_name)
print ("cmd_string:", cmd_string)
cmd_bytes = bytearray.fromhex(cmd_string)
for cmd_byte in cmd_bytes:
hex_byte = ("{0:02x}".format(cmd_byte))
#print (hex_byte)
ser.write(bytearray.fromhex(hex_byte))
time.sleep(.100)
# wait an extra 3 seconds for DISP_ON_CMD
if cmd_name == "DISP_ON_CMD":
time.sleep(5.0)
response = ser.read(32)
print ("response:", binascii.hexlify(bytearray(response)))
return
# Code to put processor into factory mode.
comm_init='c4c4'
# Here's the list of command strings, captured as tuples.
# The 16-bit Data and Msg CRCs are calculated via gen_crc.exe.
heart_beat_cmd= ("HEART_BEAT_CMD", 'a5a50a00010000003e1b')
下面是我在Python 3.4.5窗口中看到的内容。
cmd_name: HEART_BEAT_CMD
cmd_string: a5a50a00010000003e1b
返回: b'a5a51a002a0054373031763200000c08201e0a040000e389f86b‘
我从来没有花时间将输出解析成字节,但这将是一个很好的补充。
发布于 2017-03-12 14:48:18
免责声明:我是python和串口编程的新手。我知道这是一个非常古老的问题,可能已经解决了,但我想尽我的一份力(我猜),也许在这个过程中学习!我知道关于KeyboardInterrupt的问题的第二部分的答案(至少我认为我知道)。所以就是这样
KeyboardInterrupt基本上是指用户在程序仍在运行的情况下点击"Control+C“。这使得程序在当时正在执行的任何行的右边停止。因此,
File "./sollar.py", line 30, in <module>
s = ser.readline().decode('utf-8')
File "/usr/local/lib/python3.2/dist-packages/serial/serialposix.py", line 446, in read
ready,_,_ = select.select([self.fd],[],[], self._timeout)
因为这就是它停止的地方(希望我是对的)。为了避免这种情况,您可以使用"try.. except“
while True:
try:
# your main code here
break
except KeyboardInterrupt:
print("User interrupt encountered. Exiting...")
time.sleep(3)
exit()
except:
# for all other kinds of error, but not specifying which one
print("Unknown error...")
time.sleep(3)
exit()
这基本上可以帮助您以一种相当“干净”的方式退出程序。希望这能有所帮助。
https://stackoverflow.com/questions/15570526
复制相似问题