顯示具有 modbus 標籤的文章。 顯示所有文章
顯示具有 modbus 標籤的文章。 顯示所有文章

2019年3月15日 星期五

Modbus 傳輸資料型態轉換

Modbus 協議傳輸的資料一般只有基本的 U16 型態,但在實際應用上可能因裝置不同而有不同的應用,例如長整數、浮點數,但又因為硬體 CPU/MCU/OS 實際狀況而有位元順序的問題,底下是 python 轉換函式…

def Convert( theType, values  ):
    if( theType == 'FLOAT(ABCD)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[0],tobytes[1],tobytes[2],tobytes[3])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'FLOAT(CDAB)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[2],tobytes[3],tobytes[0],tobytes[1])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'FLOAT(BADC)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[1],tobytes[0],tobytes[3],tobytes[2])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'FLOAT(DCBA)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[3],tobytes[2],tobytes[1],tobytes[0])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'UINT32(ABCD)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[0],tobytes[1],tobytes[2],tobytes[3])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'UINT32(CDAB)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[2],tobytes[3],tobytes[0],tobytes[1])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'UINT32(BADC)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[1],tobytes[0],tobytes[3],tobytes[2])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'UINT32(DCBA)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[3],tobytes[2],tobytes[1],tobytes[0])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'INT32(ABCD)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[0],tobytes[1],tobytes[2],tobytes[3])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'INT32(CDAB)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[2],tobytes[3],tobytes[0],tobytes[1])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'INT32(BADC)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[1],tobytes[0],tobytes[3],tobytes[2])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'INT32(DCBA)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[3],tobytes[2],tobytes[1],tobytes[0])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'UINT16(AB)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[0],tobytes[1])
            set_value = struct.unpack('>H', packit)[0]
    elif( theType == 'UINT16(BA)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[1],tobytes[0])
            set_value = struct.unpack('>H', packit)[0]
    elif( theType == 'INT16(AB)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[0],tobytes[1])
            set_value = struct.unpack('>h', packit)[0]
    elif( theType == 'INT16(BA)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[1],tobytes[0])
            set_value = struct.unpack('>h', packit)[0]
    else:
        set_value = values[0]
    return set_value

#Modbus 讀值可能是 2byte 也可能是 4byte
values = [-4370,-8756]
Convert( 'FLOAT(ABCD)' ,values )
Convert( 'FLOAT(DCBA)' ,values )
Convert( 'FLOAT(BADC)'  ,values )
Convert( 'FLOAT(CDAB)'  ,values )
Convert( 'UINT32(ABCD)'  ,values )
Convert( 'UINT32(DCBA)'  ,values )
Convert( 'UINT32(BADC)'  ,values )
Convert( 'UINT32(CDAB)'  ,values )
Convert( 'INT32(ABCD)'  ,values )
Convert( 'INT32(DCBA)'  ,values )
Convert( 'INT32(BADC)'  ,values )
Convert( 'INT32(CDAB)'  ,values )
Convert( 'UINT16(AB)'  ,values )
Convert( 'INT16(AB)'  ,values )
Convert( 'INT16(BA)'  ,values )
Convert( 'UINT16(BA)'  ,values )

2017年12月21日 星期四

Modbus TCP Slaver using Python modbus-tk lib


https://github.com/ljean/modbus-tk/

install pip…
sudo apt-get install python-pip

install...
download modbus_tk-x.x.x.tar.gz
tar zxvf modbus_tk-x.x.x.tar.gz
python setup.py install

make sure your port is open...
sudo iptables -A INPUT -p tcp --dport 502 -j ACCEPT # for slaver
sudo iptables -A OUTPUT -p tcp --dport 502 -j ACCEPT  # for master

run example as root
a simple example...
import sys
import logging
import threading
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus as modbus
import modbus_tk.modbus_tcp as modbus_tcp
import time

logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
# CREATE server
server = modbus_tcp.TcpServer() #DEFAULT PORT=502
slaver = server.add_slave(1) #ID=1

def setup():
    slaver.add_block("coil", cst.COILS, 0, 16)
    slaver.set_values("coil", 0, 16*[0])
       
def loop():
    logger.info("running...")
    # START
    server.start()
    while True:
        values = slaver.get_values("coil", 0, 8)
        #print values[0]
        str = ''
        for i in range(0, 8):
            if values[i] == 1:
                str = str + '1'
            else:
                str = str + '0'
        print  str
        # DELAY
        time.sleep(1)
        
def destory():
    logger.info("destory")
    # STOP
    server.stop()
       
if __name__ == "__main__":
    setup()
    try:
        loop()
    except KeyboardInterrupt:
        destory()


VirtualBox 空間減肥

sdelete64 -z c: VBoxManage  modifymedium  disk  "/Users/fellow/VirtualBox VMs/Win10/Win10.vdi"  --compact *.vdi 路徑可以在 VirtualBox 儲...