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]