python - 通过 Python Socket 库向研华 ADAM-6024 发送命令和接收数据
问题描述
我正在尝试使用 Python 向 Advantech 的基于以太网的 ADAM-6024 数据采集和控制模块发送命令和接收数据。我正在使用 MacBook Pro 并通过以太网连接连接到设备。
以下是 ADAM-6000 系列设备的手册:
http://advdownload.advantech.com/productfile/Downloadfile4/1-1M99LTH/ADAM-6000_User_Manaul_Ed_9.pdf
我编写了一个名为 ADAMConnection 的 python 类,其中包含设置与模块的套接字连接然后向其发送命令并请求响应的方法。
我可以建立套接字连接,但没有运气与设备通信。这是我编写的库:
class ADAMConnection:
def __init__(self, host, eth_port):
self.host = host
self.eth_port = eth_port
self.adamsock = None
###############################################################################
# ConnectADAM() method
###############################################################################
def OpenADAMConnection( self ):
self.adamsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.adamsock.settimeout(2)
try:
self.adamsock.connect((self.host,self.eth_port))
#self.adamsock.send(str.encode("*RST\r\n")) #Example of what's done in DAQConn
#TODO: Do we need any initialization commands?
print("ADAM connected..")
time.sleep(0.05)
return True
except socket.timeout:
print('\n*************** ERROR *****************')
print('Attempt to connect to the ADAM timed out. \n' + \
'Make sure it\'s powered on and plugged in.')
print('*************** ERROR *****************\n\n')
return False
except OSError:
print('\n*************** ERROR *****************')
print('Unable to connect to the ADAM. \n' + \
'Make sure it\'s powered on and plugged in.')
print('*************** ERROR *****************\n\n')
return False
def GetModuleName(self,commandString):
#self.adamsock.send(str.encode("ASCII STRING"))
self.adamsock.send(str.encode(commandString,encoding="ascii"))
time.sleep(0.05)
adam_out = self.adamsock.recv(100) #is the 100 needed? Maybe try for now
time.sleep(0.05)
return adam_out
当我导入这个库并尝试建立套接字连接时,我成功了。我试图通过 ASCII 命令与它交谈,所以我使用端口 502。我知道从这个链接使用这个端口:
但是,当我尝试向 ADAM-6024 模块询问其模块名称时,我得到了我不理解的毫无意义的输出。我首先尝试使用我在手册第 112 页(第一个链接)上找到的 ASCII 语法发送命令来读取模块名称,但收到了似乎是垃圾输出的内容。为了确认这一点,我发送了一条我知道对模块没有意义的命令,并收到了类似的输出。
以下是我用来执行上述操作的python代码:
Python 3.8.5 (default, Sep 4 2020, 02:22:02)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ADAMConnection
>>> module1 = ADAMConnection.ADAMConnection("192.168.6.70",502)
>>> module1.OpenADAMConnection()
ADAM connected..
True
>>> module1.GetModuleName("01M0Dh")
b'01M0\x00\x03\x00\x80\x01'
>>> module1.GetModuleName("nonsense")
b'nons\x00\x03s\xe5\x01'
我几乎不精通 Python,对 Modbus/TCP/ASCII/Socket 连接一无所知,所以我不知道我是否遗漏了一些非常明显的东西。任何帮助将不胜感激。
解决方案
您成功发送和接收数据是一个好的开始。但是,我不知道您是如何获得命令字符串的"01M0Dh"
。本用户手册,第7.4 节 ADAM-6000 模块的 ASCII 命令说:
$aaM
名称读取模块名称
描述返回特定模块的名称
语法$aaM(cr)
$ 为分隔符
aa(范围 00~FF)为指定模块的 2 字符十六进制从地址(始终为 01)
M 指读取型号命令
(cr) 是终止字符,回车 (0Dh)
这对应于 Python 字符串"$01M\r"
。
查看您发布的响应数据包以及端口 502,似乎使用了Modbus TCP协议。手册对此有些不清楚,但可能是 ASCII 命令要嵌入到 Modbus TCP 帧中;然后字符串就像 eg "..\0\0\0\5$01M\r"
。但是,我不能排除 ASCII 命令是由 UDP 发送到端口 1025。如果您没有通过这种方式成功,您也可以尝试从浏览器中使用 HTTP,如D.2 REST 资源部分所述亚当,例如。http://host/digitalinput/all/value
推荐阅读
- android - 在 SQLite 中使用“”和“”时出错
- git - 如何在运行时指定 git-branch?
- mongodb - 如何将现有的字符串数组转换为mongodb中的自定义对象数组?
- google-cloud-firestore - Firestore:设置帖子ID
- javascript - Jest/Enzyme w/ React - “目标容器不是 DOM 元素。”
- postgresql - pg_stat_activity 中超过 98% 的连接处于空闲状态并正在运行 SHOW TRANSACTION ISOLATION LEVEL
- sql - 分页的 SQL 查询具有过滤器
- javascript - 具有特定搜索文本的 ngFor 中的 Angular 2/4 过滤下拉列表
- javascript - 如何在图表上进行延迟加载,通过滚动加载更多的水平条
- entity-framework - 实体框架后期模型检查