Python Forum
[PyQt] Sending 4 bytes Hex data over serial in PyQt
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] Sending 4 bytes Hex data over serial in PyQt
#1
Hi,

I would like to send 4 Bytes of Hex data over serial to a microcontroller which are being received from GUI in PyQt5.
For example, consider the first two bytes received as characters 'a' and 'b' while the remaining two bytes as integers and I would like to send all the 4 bytes as Hex values over serial. Kindly help.

firstByte = 'a'
secondByte = 'b'
thirdByte = 100
fourthByte = 120


Thanks in advance,
gratna
Reply
#2
First of all, you need bytestrings.
You can put everything into one bytestring or a bytearray:
my_bytestring1 = b'abdx' # bytestring
But you can also work with integers in different representation:
my_bytestring2 = bytes([97, 98, 100, 120])
my_bytestring3 = bytes([0x61, 0x62, 0x64, 0x78])
Then you can send the bytestring via serial.write(my_bytestring1)
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
Dear Mr. DeaD_EyE,

Thanks for the reply but I am facing another problem. The first two bytes are always the same which are 'a' and 'b' but the rest of the two bytes are user input integers. So each time I would have a different set of integers ranging from 0 to 127. I am really confused on how to combine the first 2 bytes with the rest of the two bytes and send via serial.

I have tried the following ways but it did not help.

1. thirdByte = 100
fourthByte = 120
my_bytestring3 = bytes([hex(ord('a')), hex(ord('b')), hex(thirdByte), hex(fourthByte)])
serial.write(my_bytestring3)

2. thirdByte = 100
fourthByte = 120
my_bytestring2 = bytes([int(a), int(b), thirdByte, fourthByte])
serial.write(my_bytestring2)

Kindly help me in this regard.

Thanks,
gratna
Reply
#4
Okay I wrestled with this one for a while and finally created the following functions because just sending/receiving "byte" data via a serial port did not work regardless of how I formatted/deformatted that data. I hope this helps you get to where you need to go with this.
# ********************************************************************************* 
# Basic Serial Port Communication Methods
# ********************************************************************************* 
    def SendCommand(self, Packet):
        try:
            if self.LogDiagnostics: 
                self.DiaLog(Packet, 1) # Send Packet
          # We decided to work with a straight list of numbers to represent our
          # data as such a Packet is [255, 255, ...] and we now convert that 
          # into a byte string plus CheckSum that the write command needs
            HexString = ''
            ChkSum = (sum(Packet) & 255)
            ChckPacket = Packet + [ChkSum]
            for digt in ChckPacket:
                HexVal = hex(digt)[2:]
                if len(HexVal) == 1:
                    HexString += '0' + HexVal
                else:
                    HexString += HexVal
        
          # Clear both buffers before sending a command just in case there are any
          # stray values still remaining from previous communiques
            self.serPort.reset_input_buffer()
            self.serPort.reset_output_buffer()
          # Write the Packet to the Serial Device -- note when attempting to send 
          # a binary hex value we had to end up using unhexlify( ) because 
          # everything we sent to the write( ) method was viewed as single values 
          # b'f', b'f' instead of a single byte b'ff'
            self.serPort.write(unhexlify(HexString))
        except Exception as err:
#DJ - Need to log this Data
            print('Send Error :',err)
            print('Packet :',Packet,' : ',HexString)

    def GetResponse(self, Bytes):
      # It was unclear what we got back from this Serial Device Read as 
      # maniuplating the raw data did not do what was expected however if we 
      # hexlify( ) it the results worked fine but then we decided it was just 
      # better to work with a straight list of numbers as our response so the 
      # conversion also takes place here
        try:
            Packet = []
            Bytes += 1 # Add 1 for the CheckSum Value
            BiHexStr = self.serPort.read(Bytes)

            DecList = self.BiHex2DecLst(BiHexStr)
          # Separate the Value(s) from the Check Sum
            DecValues,ChkSum = DecList[:-1],DecList[-1:]
            if ChkSum[0] == (sum(DecValues) & 255):
                Packet = DecValues

            if self.LogDiagnostics:
                self.DiaLog(DecList, 0) # Receive Packet
        except Exception as err:
            print('Receive Error :',err)

        return Packet

    def GetStream(self, Bytes):
      # GetStream is a version of GetResponse that does not do a CheckSum because 
      # the stream of data it is receiving is incomplete and thus does not have a
      # checksum until it receives the final chunk from the controller
        try:
            Packet = []
            BiHexStr = self.serPort.read(Bytes)

            DecList = self.BiHex2DecLst(BiHexStr)
            Packet = DecList

            if self.LogDiagnostics:
                self.DiaLog(DecList, -1) # Receive Partial Packet
        except Exception as err:
            print('Receive Error :',err)

        return Packet

    @staticmethod
    def BiHex2DecLst(BiHex):
          # Convert the Raw Data into a Python Binary Hex String b'ff....'
            FullHexVal = hexlify(BiHex)
          # Convert the Hex Values String into a Decimal List 'ffff' > [255, 255]
            DecList = [int(FullHexVal[idx:idx+2], 16) for idx in range (0, len(FullHexVal), 2)]

            return DecList
Reply
#5
Dear Mr. Denni,

Thank you. The problem has been solved.

With Regards,
Ratna
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Serial Port data readout macellan85 3 7,753 Jun-19-2020, 12:32 PM
Last Post: deanhystad
  Read Data from Serial port PA3040 2 2,923 Feb-25-2020, 04:13 PM
Last Post: Denni

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020