精华内容
下载资源
问答
  • Modbus寄存器地址规则

    万次阅读 2019-08-09 00:32:31
    Modbus协议定义的寄存器地址是5位十进制地址,即: 线圈(DO)地址:00000~09999 触点(DI)地址:10000~19999 输入寄存器(AI)地址:30000~39999 输出寄存器(AO)地址:40000~49999 由于上述各类地址是...

    Modbus协议定义的寄存器地址是5位十进制地址,即:

    线圈(DO)地址:00001~09999

    触点(DI)地址:10001~19999

    输入寄存器(AI)地址:30001~39999

    输出寄存器(AO)地址:40001~49999

     

    由于上述各类地址是唯一对应的,因此有些资料就以其第一个数字区分各类地址,即:0x代表线圈(DO)类地址,1x代表触点(DI)类地址、 3x代表输入寄存器(AI)类地址、4x代表输出寄存器(AO)类地址。

     

    在实际编程中,由于前缀的区分作用,所以只需说明后4位数,而且需转换为4位十六进制地址。

    展开全文
  • 杰控组态软件MODBUS寄存器地址的设置 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对...

    这样的设置,读的是40001这个寄存器,因为是16位格式,所以如果是SMART200的PLC,应该是VW0这个寄存器。
    这样的设置,读的是40001这个寄存器,因为是16位格式,所以如果是SMART200的PLC,应该是VW0这个寄存器。

    展开全文
  • abview做与信捷仿三菱PLC串口Modbus寄存器发送地址功能码查询 自己测试通过完全适合串口代码,以项目中应用。
  • 寄存器PLC地址寄存器modbus协议地址

    万次阅读 多人点赞 2017-10-24 22:25:28
    寄存器PLC地址指存放于控制器中的地址,这些控制器可以是PLC,也可以使触摸屏,或是文本... 寄存器modbus协议地址指通信时使用的寄存器地址,在实际编程中,由于寄存器PLC地址前缀的区分作用,所以只需说明后4位数...

           寄存器PLC地址指存放于控制器中的地址,这些控制器可以是PLC,也可以使触摸屏,或是文本显示器。PLC地址一般采用10进制描述,共有5位,其中第一位代码寄存器类型。第一位数字和寄存器类型的对应关系如表1所示。PLC地址例如40001、30002等。
           寄存器modbus协议地址指通信时使用的寄存器地址,在实际编程中,由于寄存器PLC地址前缀的区分作用,所以只需说明后4位数,而且需转换为4位十六进制地址。例如PLC地址40001对应寻址地址0x0000,40002对应寻址地址0x0001,寄存器寻址地址一般使用16进制描述。再如,PLC寄存器地址40003对应协议地址0002,PLC寄存器地址30003对应协议地址0002。在实际编程中,由于前缀的区分作用,所以只需说明后4位数,而且需转换为4位十六进制地址。
           支持 Modbus 协议的设备或软件,使用时用户直接设置或看到的应 当是 Modbus 数据地址。Modbus 地址所访问的数据,是通过各种 “功能”读写而来。 功能码是 Modbus 地址的底层。 如果 Modbus 通 信的一方提供的所谓 Modbus 协议只有功能码,则需要注意了解此 功能号与 Modbus 地址间的对应关系。

           使用 modbus 地址时应注意下述问题:

     1)40001~4xxxx 是美国 modicon 公司和 ge 公司 plc 使用的 modbus 地址,它是基于1的地址,即同类元件的首地址为1。西门子 plc 的 modbus 地址是基于0的地址。 

    2)美国的 modbus 地址左起第2位用来表示元件的类型,例如 i0.0的 modbus 地址为010001。 因为数据类型已经包含在功

    展开全文
  • 装置是电能质量表,各项数据大都使用Modbus寄存器存储,现在的工作是需要同时读取该装置的多个通道的Modbus寄存器,同时还要监控每个通道的寄存器值增长是否符合预期。 总的来说就是,同时开多个进程读取寄存器,每...

     装置是电能质量表,各项数据大都使用Modbus寄存器存储,现在的工作是需要同时读取该装置的多个通道的Modbus寄存器,同时还要监控每个通道的寄存器值增长是否符合预期。

    总的来说就是,同时开多个进程读取寄存器,每个进程中又包含一个While循环。结构没啥可赘述的。上代码慢慢解释吧:

    @staticmethod
    	def start_read_energy_counter(ipAddress, uMeas, iMeas, phiMeas, measurand, expectedCounterNumber, q, influenceQuantity, harV_Meas, harI_Meas, networkType):
    		cosPhi = abs(round(math.cos(math.radians(phiMeas)), 2))
    		sinPhi = abs(round(math.sin(math.radians(phiMeas)), 2))
    
    		mbus = ModbusRobot.ModbusRobot()
    		mbus.open_modbus_connection(connectionType='TCP', host=ipAddress)
    
    		pulseQuantity = round(mbus.read_holding_float(MBModbusRegister.PULSEQUALTIY.value), 8)
    
    		if measurand in [MBModbusRegister.ACTIVE_ENERGY_WPA_IMP, MBModbusRegister.ACTIVE_ENERGY_WPB_IMP, MBModbusRegister.ACTIVE_ENERGY_WPC_IMP, MBModbusRegister.ACTIVE_ENERGY_WP_IMP, MBModbusRegister.ACTIVE_ENERGY_WPA_EXP, MBModbusRegister.ACTIVE_ENERGY_WPB_EXP, MBModbusRegister.ACTIVE_ENERGY_WPC_EXP, MBModbusRegister.ACTIVE_ENERGY_WP_EXP]:
    			timeOfOneCounter = 3600 * pulseQuantity / (uMeas * iMeas * cosPhi)
    			if influenceQuantity == MEASInfluenceType.HARMONICS and harV_Meas is not None and harI_Meas is not None:
    				timeOfOneCounter = 3600 * pulseQuantity / (uMeas * iMeas * cosPhi + sum([uMeas * float(harmU[1]) * iMeas * float(harmI[1]) * abs(math.cos(math.radians(int(harmU[0]) * phiMeas + (int(harmI[2]) - int(harmU[2]))))) for harmU, harmI in zip(harV_Meas, harI_Meas)]))
    		elif measurand in [MBModbusRegister.REACTIVE_ENERGY_WQA_CAP, MBModbusRegister.REACTIVE_ENERGY_WQB_CAP, MBModbusRegister.REACTIVE_ENERGY_WQC_CAP, MBModbusRegister.REACTIVE_ENERGY_WQ_CAP, MBModbusRegister.REACTIVE_ENERGY_WQA_IND, MBModbusRegister.REACTIVE_ENERGY_WQB_IND, MBModbusRegister.REACTIVE_ENERGY_WQC_IND, MBModbusRegister.REACTIVE_ENERGY_WQ_IND]:
    			timeOfOneCounter = 3600 * pulseQuantity / (uMeas * iMeas * sinPhi)
    			if influenceQuantity == MEASInfluenceType.HARMONICS and harV_Meas is not None and harI_Meas is not None:
    				timeOfOneCounter = 3600 * pulseQuantity / math.sqrt((math.sqrt(uMeas ** 2 + (uMeas * harV_Meas[0][1]) ** 2) * math.sqrt(iMeas ** 2 + (iMeas * harI_Meas[0][1]) ** 2)) ** 2 - (uMeas * iMeas * cosPhi + (uMeas * harV_Meas[0][1]) * (iMeas * harI_Meas[0][1]) * cosPhi) ** 2)
    		else:
    			timeOfOneCounter = 3600 * pulseQuantity / (uMeas * iMeas)
    
    		initialCount = int(hex(mbus.read_holding_registers(measurand.value, 2)[0]) + '0000', base=16) + mbus.read_holding_registers(measurand.value, 2)[1]
    		expectedCounterNumber = expectedCounterNumber * 3 if measurand in [MBModbusRegister.ACTIVE_ENERGY_WP_IMP, MBModbusRegister.ACTIVE_ENERGY_WP_EXP, MBModbusRegister.REACTIVE_ENERGY_WQ_CAP, MBModbusRegister.REACTIVE_ENERGY_WQ_IND, MBModbusRegister.APPARENT_ENERGY_WS] and networkType not in [ACMNetworkType.SINGLE_PHASE] else expectedCounterNumber
    
    		while True:
    			time.sleep(0.010)
    			firstValidCounter = int(hex(mbus.read_holding_registers(measurand.value, 2)[0]) + '0000', base=16) + mbus.read_holding_registers(measurand.value, 2)[1]
    			firstValidPCTime = round(time.time(), 8)
    
    			if firstValidCounter - initialCount >= 1:
    				break
    
    		while True:
    			time.sleep(0.010)
    			finalValidCounter = int(hex(mbus.read_holding_registers(measurand.value, 2)[0]) + '0000', base=16) + mbus.read_holding_registers(measurand.value, 2)[1]
    			finalValidPCTime = round(time.time(), 8)
    
    			if finalValidCounter - firstValidCounter >= int(expectedCounterNumber):
    				break
    
    		acutalUsedTime = finalValidPCTime - firstValidPCTime
    		actualIncreaseCount = finalValidCounter - firstValidCounter
    
    		if measurand in [MBModbusRegister.ACTIVE_ENERGY_WP_IMP, MBModbusRegister.ACTIVE_ENERGY_WP_EXP, MBModbusRegister.REACTIVE_ENERGY_WQ_IND, MBModbusRegister.REACTIVE_ENERGY_WQ_CAP, MBModbusRegister.APPARENT_ENERGY_WS]:
    			if influenceQuantity == MEASInfluenceType.VOLTAGEUNBALANCE and networkType in [ACMNetworkType.FOUR_WIRE_THREE_PHASE_UNBALANCED, ACMNetworkType.THREE_WIRE_THREE_PHASE_BALANCED, ACMNetworkType.THREE_WIRE_THREE_PHASE_UNBALANCED_2L, ACMNetworkType.THREE_WIRE_THREE_PHASE_UNBALANCED_3L]:
    				acutalUsedTime = acutalUsedTime * 2.9 # For special fixed test points of the influence Quantity is voltage unbalance
    			else:
    				if networkType not in [ACMNetworkType.SINGLE_PHASE]:
    					acutalUsedTime = acutalUsedTime * 3
    
    		data = {
    			'Measurand': measurand,
    			'IncreasedCount': actualIncreaseCount,
    			'ActualUsedTime': acutalUsedTime,
    			'ExpectedUsedTime': timeOfOneCounter * actualIncreaseCount
    		}
    
    		q.put(data)
    
    		mbus.close_modbus_connection()

     首先贴出的是一个基础函数,这是一个读取寄存器的函数(看函数名),其中两个While True循环就是来循环读取该寄存器,比如第一次读取的值是1,循环读取然后sleep,直到该寄存器的值增长到101时,退出循环,同时返回增长这100个数值所需要的时长!

    这里我返回的是一个字典,包含测试通道,实际增长的count数,实际耗时,以及期望耗时时长;该字典会被后面调用的函数中使用。

     

    接下来贴出的是一个验证精度的函数(如下图):

    	def validate_energy_accurancy(self, ipAddress, uMeas, iMeas, phiMeas, measurands, expectedCounterNumber, networkType, expectUncertainty=None, influenceQuantity=None, harV_Meas=None, harI_Meas=None, dataSource=MEASDataSource.MODBUSTCP):
    		uMeas = float(uMeas)
    		iMeas = float(iMeas)
    		phiMeas = float(phiMeas)
    		measurands = [Utils.to_enum(measurand, MBModbusRegister) for measurand in measurands]
    		expectedCounterNumber = int(expectedCounterNumber)
    		networkType = Utils.to_enum(networkType, ACMNetworkType)
    		influenceQuantity = Utils.to_enum(influenceQuantity, MEASInfluenceType) if influenceQuantity is not None else influenceQuantity
    		dataSource = Utils.to_enum(dataSource, MEASDataSource) if dataSource is not None else dataSource
    
    		if dataSource not in [MEASDataSource.MODBUSTCP]:
    			raise ValueError('Not support source: {:s}'.format(dataSource))
    
    		threads = []
    		q = multiprocessing.Queue()
    		isValidMeasurement = True
    
    		for measurand in measurands:
    			t = multiprocessing.Process(target=self.start_read_energy_counter, args=(ipAddress, uMeas, iMeas, phiMeas, measurand, expectedCounterNumber, q, influenceQuantity, harV_Meas, harI_Meas, networkType))
    			threads.append(t)
    		for t in threads:
    			t.start()
    
    		results = [q.get() for t in threads]
    
    		for t in threads:
    			t.terminate()
    
    		for result in results:
    			try:
    				actualUncertainty = abs((1 - round((result['ActualUsedTime'] / result['ExpectedUsedTime']), 6)))
    				allowedError = expectUncertainty * result['ExpectedUsedTime']
    				delta = abs(result['ActualUsedTime'] - result['ExpectedUsedTime'])
    
    				measurandName = Utils.to_enum(result['Measurand'], MBModbusRegister)
    
    				if delta > allowedError:
    					logger.error('{:s} increased {:d} counters used time {:.3f} s, expected to be {:.3f} s, difference of {:.3f} s, exceeds {:.3f} s'.format(measurandName.name, result['IncreasedCount'], result['ActualUsedTime'], result['ExpectedUsedTime'], delta, allowedError))
    					raise AssertionError('Measured {:s} accuracy is: {:.3f} didn\'t match expected accuracy: {:f}'.format(measurandName.name, actualUncertainty, expectUncertainty))
    			except AssertionError as err:
    				logger.info(err)
    				isValidMeasurement = False
    
    			logger.info('Measured {:s} accuracy is: {:f}, it matches expected accuracy: {:f}'.format(measurandName.name, actualUncertainty, expectUncertainty))
    
    		if not isValidMeasurement:
    			raise AssertionError('Measured values didn\'t match expected values')

     这个函数就使用到了python的多进程,因为需求是同时读取,所以只好用多进程来做。

    q = multiprocessing.Queue()   #这里是将多进程中的Que()实例化,然后作为参数带入基础函数
    		for measurand in measurands:
    			t = multiprocessing.Process(target=self.start_read_energy_counter, args=(ipAddress, uMeas, iMeas, phiMeas, measurand, expectedCounterNumber, q, influenceQuantity, harV_Meas, harI_Meas, networkType)) # 这里是定义进程
    			threads.append(t)
    		for t in threads:
    			t.start() # 开始进程
    
    		results = [q.get() for t in threads] # 从进程中获取返回的数据,也就是基础函数中定义的字典
    
    		for t in threads:
    			t.terminate() # 终止进程

    这段代码应该说是核心了,根据measurand测试通道数量来决定定义多少个进程,然后将参数传入要调用的函数;t.start()即开始进程;q.get()即获取基础函数中返回的数据,也就是q.put(data)中的这个data。

    接下来的try....except....部分其实就是对获取的结果进行一个验证,验证误差值是否符合预期,否则将标识位 isValidMeasurement置为False。最终根据标志位来判断验证是否通过!

     

    最后将核心的这个validate_energy_accuracy()核心函数再次封装,封装成RobotFrameWork中可直接使用的关键字:

    	def validate_active_energy_import_accurancy(self, ipAddress, uMeas, iMeas, phiMeas, expectedCounterNumber, measurands=None, networkType=None, iNom=None, iMax=None, influenceQuantity=None, harV_Meas=None, harI_Meas=None, measurementStandard=MEASMeasurementStandard.IEC61557, dataSource=MEASDataSource.MODBUSTCP):
    		cosPhi = abs(round(math.cos(math.radians(float(phiMeas))), 2))
    
    		conf = None
    
    		if networkType is None:
    			conf = self._configuration.get_ac_measurement_configuration()
    
    		networkType = Utils.to_enum(networkType, ACMNetworkType) if networkType is not None else conf.networkType
    
    		if measurands is None:
    			if networkType in [ACMNetworkType.FOUR_WIRE_THREE_PHASE_UNBALANCED, ACMNetworkType.THREE_WIRE_THREE_PHASE_UNBALANCED_3L, ACMNetworkType.THREE_WIRE_THREE_PHASE_UNBALANCED_2L]:
    				measurands = ['ACTIVE_ENERGY_WPA_IMP', 'ACTIVE_ENERGY_WPB_IMP', 'ACTIVE_ENERGY_WPC_IMP', 'ACTIVE_ENERGY_WP_IMP']
    			else:
    				measurands = ['ACTIVE_ENERGY_WPA_IMP', 'ACTIVE_ENERGY_WP_IMP']
    
    		expectUncertainty = self._get_active_energy_uncertainty(iNom, iMax, cosPhi, measurementStandard, influenceQuantity)
    
    		self.validate_energy_accurancy(ipAddress, uMeas, iMeas, phiMeas, measurands, expectedCounterNumber, networkType, expectUncertainty, influenceQuantity, harV_Meas, harI_Meas, dataSource)
    

    validate_active_energy_import_accurancy()这个函数就是验证电能中有功power进度的关键字,还有一些验证无功功率和视在功率的一些函数,在此就不一一列举了,其根本就是将validate_energy_accuracy()函数惊醒各种各样的封装而已。

     

    该文章也算记录一下自己多进程在实际工作中的使用吧,做个笔记,以防忘记!!!!

     

     

    展开全文
  • modbus 寄存器介绍

    2017-11-10 14:06:00
    modbus 的查询命令 命令 地址开始(两个地址) 地址长度(两个地址) 检验 01 xx xx xx xx xx xx xx modbus 设置命令 命令 地址 ...
  • DAKIN空调,485 Modbus-RTU寄存器详细中文说明文档,多联机控制。
  • 寄存器中按位定义数据的方法存在于很多厂家设备的MODBUS数据协议中。区别于线圈状态(RW)和离散输入(RO),寄存器中通过定义组合位数据,更有利于高效传输状态信息和设置开关量。 由于位数据被定义在寄存器中,其...
  • 请教个问题:三相电的电压用一个四位浮点数来表示,用两个相邻的寄存器来保存这个浮点数,通过modus采集到的一个电压为46 21 9A 00,书上说转换为10进制是10342.5伏,这个是怎么算到小数的,这个数值是怎么算出来的。
  • 在这篇文章中,我将逐步介绍Modbus寻址的基础知识,包括偏移如何发挥作用,以及它们如何影响在TOP Server for Wonderware应用程序中使用的地址。  由于在世界各地几乎有同样多的不同设备制...
  • 我现在需要设计一款app,可以读取我的PLC里的寄存器值。 目前我可以通过button 链接到port,并且读取到寄存器数值。但是软件与PLC只链接一会就自动断开了。请问怎么可以实现一直接通,并且循环读取寄存器的值呢—— ...
  • 我需要做一个application,去读取Modbus协议端slave PLC 的寄存器的值。 效果是: Tab1 里面有一个datagridview区显示Holding Register 的值,Tab2 里面有一个datagridview去显示InputRegister的值...就这样一共4个tab...
  • modbus寄存器地址

    千次阅读 2020-06-11 15:08:22
    modbus地址,其实modbus的规范里面写的很明确了,但是最近还有人问我,其实这个很简单的。00001至09999是离散输出(线圈)-----Coil status10001至19999是离散输入(触点)-----Input status30001至39999是输入寄存器...
  • 请问我在组态王6.55环境中定义变量时...遥信1寄存器地址:31.1(3为功能码04减1得到,1为寄存器起始地址加1,1为1位,bit类型,只读) 遥测0地址和变量类型该如何设置???????? 感谢大家了!!!!!!
  • 西门子PLC基于MODBUS RTU通信协议的寄存器地址对应关系及错误代码
  • FreeModbus保持寄存器

    千次阅读 2019-04-08 21:39:22
    保持寄存器的访问属性为读写 对保持寄存器的操作包括:读保持寄存器(0x03)、写...请求PDU说明了起始寄存器地址和寄存器数量。从零开始寻址寄存器。因此,寻址寄存器1-16 为0-15。 将响应报文中的寄存器数据...
  • ModBus协议寄存器

    2020-06-23 10:42:58
    AI: 模拟输入,输入寄存器,一个地址16位数据,用户只能读,不能修改,比如一个电压值的读数。 AO: 模拟输出,保持寄存器,一个地址16位数据,用户可以写,也可以回读,比如一个控制变频器的电流值。 无论这
  • FreeModbus输入寄存器

    千次阅读 2019-04-08 21:22:32
    请求PDU 说明了起始地址寄存器数量。从零开始寻址寄存器。因此,寻址输入寄存器1-16 为0-15。 将响应报文中的寄存器数据分成每个寄存器为两字节,在每个字节中直接地调整二进制内容。对于每个寄存器,第一个字节...
  • Modbus实际应用中,我们对Modbus 3区、4区的地址有的时候会出现混淆,尤其是类似于404097这种表达方式的地址,就更容易乱,因为我们常常会用串口调试,这个就容易难理解。 Modbus 中3区和4区的地址表示含义如下:...
  • 对于modbus寄存器的理解
  • 西门子PLC基于MODBUS RTU通信协议时的寄存器地址对应关系及错误代码 西门子PLC在使用MODBUS RTU通信协议时,寄存器的地址是如何对应的?为什么第一个寄存器地址是40001? 功能码对照表如下:(H为16进制) 由上面...
  • Modbus协议寄存器操作

    千次阅读 2011-04-06 10:47:00
    Modbus协议寄存器操作 Modbus Registers Modbus寄存器 Detailed Description 详细描述 #include "mb.h" The protocol stack does not internally allocate any memory for the registers. This ...
  • MODBUS-寄存器与功能码学习

    千次阅读 2017-09-08 14:11:11
    MODBUS-寄存器与功能码学习 分类 简称 起始地址 结束地址 能够使用的功能码 输出逻辑线圈/(可读写位)/(DI/O)(如继电器开关控制) 0x...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,576
精华内容 1,830
关键字:

modbus寄存器地址