2 个不同寄存器的两个相同值 - minimummodbus

问题描述

我已开始使用 AcuRev 2000 的最小 modbus 工作,其寄存器映射位于此链接 https://www.accuenergy.com/support/modbus-map/?modbus-map=acurev-2000-modbus-map 中,我正在读取频率 (8192-8193) 和第 2 行中的电压 (8196-8197)。>

在运行我的程序时,它通常会在这两个参数中给我相同的值,我尝试了一些方法,例如增加读数之间的时间,或者它们之间的小延迟,但似乎没有改善。你认为是什么问题——会不会是 RS-485 适配器?

输出是这样的,有的重复和电压线一样,是问题所在:

2021-2-24-16:57:41 60.021095275878906 127.21097564697266
2021-2-24-16:57:44 127.1023178100586 127.09758758544922
2021-2-24-16:57:47 60.021095275878906 127.18592071533203
2021-2-24-16:57:50 127.1960220336914 127.19416046142578
2021-2-24-16:57:54 127.1761474609375 127.17230224609375
2021-2-24-16:57:57 59.97891616821289 127.0765609741211
2021-2-24-16:58:0 59.97891616821289 126.90221405029297

我的代码是这样的

import minimalmodbus #importamos la libreria
import time
import csv
#declaramos el instrumento
print("Respalda el archivo CSV anterior antes de seguir con el programa")
print("Si ingresas mal los datos puede entrar en un bucle infinito usa ctr+c")
print("Ingrese Puerto de conexion (windows= COMX)")
PORT=input()
print("cuando desees parar los registros usa ctr+c y una Y para que se guarde el archivo,de otra forma se eliminará")
print("Si no aparece inmediatamente la opcion de salir despues de ctr+c espera unos segundos max(30)")
print("ingrese ID de dispositivo")
ID=int(input())
instr = minimalmodbus.Instrument(PORT,ID) #puerto COM10 de conexion y ID dispositivo
instr.serial.baudrate=9600 #modificamos el baud rate
Cabecera=('Tiempo','Frecuencia','Tensión L2')#cual es el nombre de nuestros datos
with open('Datos.csv','w',newline='') as archivocsv:
    archivo=csv.writer(archivocsv)
    archivo.writerow(Cabecera)
    a=0
    while 1:
        try:
            c=0
            b=0
            tiempo=time.localtime()
            c=instr.read_float(8196,3,2,0)#leemos un registro flotante
            time.sleep(0.01)
            b=instr.read_float(8192,0)#leemos un registro flotante
            Timestamp=str(tiempo.tm_year)+"-"+str(tiempo.tm_mon)+"-"+str(tiempo.tm_mday)+"-"+str(tiempo.tm_hour)+":"+str(tiempo.tm_min)+":"+str(tiempo.tm_sec)
            print(Timestamp,b,c)
            DA=[Timestamp,c]
            archivo.writerow(DA)
            a=a+1
            time.sleep(30)
        except IOError:
            a=a
        except KeyboardInterrupt:
            print("Desea Salir? Y/N")
            valor=input()
            if valor=="Y":
                print("Se hicieron "+str(a)+" registros correctos")
                print("guarde su documento en otra ubicacion")
                break
            else:
                continue

解决方法

你可能有一个 16 位的词序问题,一个字节顺序问题。

您使用的库假设读取 16 位字的顺序与实际读取的顺序相反,我不知道该库是否允许在读取 32 位类型时交换 16 位字。

发生这种情况是因为 Modbus 没有定义如何读取 32 位类型,并且一些制造商在开头发送高位字,而其他制造商则相反。

,

我终于没有出现这个错误,我在缓存的错误之间使用了延迟时间,我还更改了记录的顺序,并且程序开始正确读取,但是我认为这不是一个完整的解决方案,因为如果您开始在错误之间等待,您的测量可能会有几秒钟的延迟,如果您想要的是没有延迟的测量,随着时间的推移可能会导致问题。

with open('Datos.csv','w',newline='') as archivocsv:
    archivo=csv.writer(archivocsv)
    archivo.writerow(Cabecera)
    a=0
    while 1:#tiempo,frecuencia,voltaje
        try:
            c=0
            b=0
            tiempo=time.localtime()
            b=instr.read_float(8192,3,2,0)#leemos un registro flotante
            time.sleep(0.01)
            c=instr.read_float(8196,0)#leemos un registro flotante
            Timestamp=str(tiempo.tm_year)+"-"+str(tiempo.tm_mon)+"-"+str(tiempo.tm_mday)+"-"+str(tiempo.tm_hour)+":"+str(tiempo.tm_min)+":"+str(tiempo.tm_sec)
            print(Timestamp,b,c)
            DA=[Timestamp,c]
            archivo.writerow(DA)
            a=a+1
            time.sleep(3)
        except IOError:
            a=a
            time.sleep(0.5)  ***#here is the modification that help***
        except KeyboardInterrupt:
            print("Desea Salir? Y/N")
            valor=input()
            if valor=="Y":
                print("Se hicieron "+str(a)+" registros correctos")
                print("guarde su documento en otra ubicacion")
                break
            else:
                continue