Dificultad para leer valores Aplicación Modbus en Python (Pyserial) On Energy meter (EM6400)

0

Estoy intentando leer los valores de voltaje del medidor de energía ( EM6400 ) en python usando el protocolo modbus. Pero hay problemas cuando estoy leyendo valores. Creo que el problema es con, No estoy leyendo valores de manera adecuada. es decir, en la línea ----- >

buf = ser.read(11) # reading 11 bytes from energy meter

Aquí está detallado de mi implementación:

Solicitud:

01 03 0F56 0002 270F
01: Slave address
03: Function code for read holding registers
0F56: Data Address of the first requested register (address for voltage phase1 to neutral)
(0F56 hex = 3927, +40001 offset = 43928)
0002: Total number of registers requested
270F: CRC (Cyclic Redundancy Check) for error checking (LSB first)

Respuesta:

01 03 04 2921 4373 D2B0
01: Slave address
03: Function code for read holding registers
04: Total number of bytes read
2921: Data in 1st requested register
4373: Data in 2st requested register
D2B0: CRC for error checking (LSB first)

Los valores en el registro requerido son 43732921 en hexadecimal (ya que los valores obtenidos se leen en formato little endian) que es 243.16 cuando se convierten a punto flotante usando IEEE 754 norms . El valor obtenido es un voltaje (fase 1 a neutro) que es 243.16 Volts.

Aquí está el código para el mismo:

import os
import sys
cwd=os.getcwd()
(setpath,Examples)=os.path.split(cwd)
print setpath
sys.path.append(setpath)

from PyArduino import *

import struct


port=locateport()
ser = serial.Serial(port, 9600)

ser.write("\x01\x03\x15\x86\x00\x02\x39\x15")
buf=ser.read(11)

b1=b2=b3=b4=0

a1=buf[3]

if (a1<16):
    b1=1
    a1=int(a1,16)
if (b1):
    a1='0'+str(a1)


a2=buf[4]
if (a2<16):
    b2=1
    a2=int(a2,16)
if (b2):
    a2='0'+str(a2)



a3=buf[5]
if (a3<16):
    b3=1
    a3=int(a3,16)
if (b3):
    a3='0'+str(a3)

a4=buf[6]
if (a4<16):
    b4=1
    a4=int(a4,16)
if (b4):
    a4='0'+str(a4)


a5=[a3,a4,a1,a2];
a6=''.join(a5)


print struct.unpack('!f', a6.decode('hex'))[0]
    
pregunta Geeko

1 respuesta

1

Puedes intentar usar pymodbus en su lugar. Esta es una capa que se encuentra encima de pyserial que maneja las complejidades para usted. Depende de torcido, pero funcionará sin torcer para este caso simple.

from pymodbus.client.sync import ModbusSerialClient as ModbusClient
modbus = ModbusClient(method='rtu', port='/dev/ttyUSB3', baudrate=9600, timeout=1)
modbus.connect()
r = modbus.read_holding_registers(0x0F56, 2, unit=1)

Los datos que estás buscando deberían estar en r.registers[0] y r.registers[1] .

    
respondido por el izak

Lea otras preguntas en las etiquetas