I am trying to read energy meter(EM6400
) voltage values in python by using modbus protocol.
But there are issues when I am reading values. I think the issue is with,
I am not reading values in proper way
i.e. in the line ----->
buf = ser.read(11) # reading 11 bytes from energy meter
Here is detailed of my implementation :
Request:
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)
Response:
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)
Values in required register are 43732921
in hex (since obtained values are being read in little endian format) which is 243.16
when converted to floating point using IEEE 754 norms
. Obtained value is a voltage (phase1 to neutral) which is 243.16
Volts.
Here is the code for the same:
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]