Unconfigured Ad Widget

Collapse

Who knows Python language? I need help.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Frozenguy
    CGN/CGSSA Contributor
    CGN Contributor
    • Jan 2008
    • 6303

    Who knows Python language? I need help.

    Hey Cagluns,

    I need help with a python script. I had it running on another machine and now I need it running on my current machine but I have run into issues.

    That or I need to convert it to C.

    I get the following error:
    Traceback (most recent call last):
    File "\\[...]\fake_sonar_packet.py", line 156, in <module>
    sonar_port = FakeSonarPacket(0, 115200, 4)
    File "\\[...]\fake_sonar_packet.py", line 11, in __init__
    self.ser.port = port
    File "C:\[...]\AppData\Local\Continuum\anaconda3\lib\site-packages\serial\serialutil.py", line 264, in port
    raise ValueError('"port" must be None or a string, not {}'.format(type(port)))
    ValueError: "port" must be None or a string, not <class 'int'>

    Here is the script:
    Thanks for looking.
    Code:
    import serial
    import os 
    import sys
    from time import sleep
    
    class FakeSonarPacket():
        # basic serial protocol class
        def __init__(self, port, baud, number):
            self.ser = serial.Serial()
            self.ser.baudrate = baud
            self.ser.port = port
            self.ser.timeout = 1
            self.alive = False
            self._receive_state = 'START1'
            self._read_array = bytearray()
            self._read_length = 0
            self.connected = False
            self.num_sonar = number
            
        def open(self):
            if (not self.ser.isOpen()):
                print("opening serial connection")
                self.ser.open()
                self.alive = True
                    
                    
        def close(self):
            if self.alive:
                self.alive = False
            self.ser.close()
    
        def mara_init(self):
            '''Sends appropriate responses to MARA so that it thinks
            a sonar board is connected'''
            while not self.connected:
                data = self.packet_reader(sonar_port)
                if data['cmd'] == 'CHK_ERROR':
                    print("bad checksum")
                    continue
                if data['cmd'] == 0x00:
                    self.send(0)
                    print("alive")
                if data['cmd'] == 0x10:
                    self.send(0x10, [0x07]) #version 7 works with MARA.  Other numbers might work.
                    print("version")
                if data['cmd'] == 0x11:
                    self.send(0x11, [self.num_sonar])
                    print("number")
                if data['cmd'] == 0x13:
                    self.send(0x13, [0x02])
                    print("delay")
                if data['cmd'] == 0x17:
                    if data['args'][0] < self.num_sonar:
                        addr = data['args'][0]
                        self.send(0x17, [addr, 10])
                        print("gain %d" % addr)
                if data['cmd'] == 0x19:
                    if data['args'][0] < self.num_sonar:
                        addr = data['args'][0]
                        self.send(0x19, [addr, 0xff])
                        print("threshold %d" % addr)
                if data['cmd'] == 0x14:
                    if data['args'][0] < self.num_sonar:
                        addr = data['args'][0]
                        self.send(0x14, [addr, 0x17])
                    print("max range")
                if data['cmd'] == 0x22:
                    mask = data['args']
                    print("setmask")
                    print(mask)
                if data['cmd'] == 0x12:
                    self.send(0x12, [0x01, 0x00])
                    print("mask")
                if data['cmd'] == 0x01:
                    self.connected = True
                    print("connected")
    
        def _checksum(self, array):
            chk = 0
            for i in range(0, len(array)-1, 2):
                chk += (array[i]<<8) | array[i+1]  # simple sum of pairs
                chk &= 0xFFFF
            if (len(array) & 0x01):    # if there are an odd number of bytes
                chk = chk ^ array[-1]    # xor the last byte
    
            return chk & 0xFFFF
                
        def send(self, cmd, args=[]):
            
            # build packet
            packet = bytearray([0xfa, 0xf5])
            packet.append(3 + len(args))
            packet.append(cmd)
            packet.extend(args)
            chk = _checksum(packet[3:])
            print(chk)
            packet.append(chk >> 8)
            packet.append(chk & 0xFF)
            # send it out
            print(packet)
            sonar_port.write(packet)
                
        def packet_reader(self):
            self._read_array = bytearray()
            dat = self.ser.read(1)
            print(dat)
            self._receive_state = "START1"
            reading = True
            while reading:
                if self._receive_state == "START1":
                    if ord(dat) == 0xfa:
                        self.receive_state = "START2"
                        self._read_array = bytearray()
                        dat = self.ser.read(1)
                    else:
                        pass
                if self._receive_state == "START2":
                    if ord(dat) == 0xf5:
                        self._receive_state = "LENGTH"
                        dat = self.ser.read(1)
                    else:
                        self._receive_state = 'START1'
                if self._receive_state == "LENGTH":
                    rx_length = ord(dat)
                    dat = self.ser.read(rx_length)
                    self._receive_state = "BODY"
                if self._receive_state == "BODY":
                    self._read_array.extend(bytearray(dat))
                    if len(self._read_array) == rx_length:
                        got = (self._read_array[-2] << 8) | self._read_array[-1]
                        exp = _checksum(self._read_array[:-2])
                        if got == exp: # good checksum, parse packet
                            packet = {'cmd': self._read_array[0]}
                            if len(self._read_array) > 1:
                                packet['args'] = self._read_array[1:-2] 
                                reading = False 
                        else:
                            # bad checksum
                            packet = {'cmd': 'CHK_ERROR',
                                                    'got': got,
                                                    'exp': exp,
                                                    'raw': self._read_array[:]}
                                                    
                        self._receive_state = 'START1'
                else:
                    self._receive_state = "START1"
                  
            return packet   
            
        def send_dist(self, sensor_num, distance): 
            #send distance in mm for one sensor to mara
            sensor_data = bytearray([sensor_num, 0x00, distance % 0x100, distance >> 8])
            self.send(0x01, sensor_data)
                 
    if __name__ == '__main__':
        sonar_port = FakeSonarPacket(0, 115200, 4)
        sonar_port.open()
        sonar_port.mara_init()
        # data = sonar_port.packet_reader()
        # print(data)
    
    
        while True:
            dist = 500 #distance in mm
            if sonar_port.connected:   
                for i in range(sonar_port.num_sonar):
                    sonar_port.send_dist(i, dist)
                sleep(0.05)
  • #2
    tomrkba
    Senior Member
    • Jun 2016
    • 1513

    Declare port as type string, not int. See last line. I would cast it to type string for the scope of that function since it is an int upstream.
    Biden's
    Laptop
    Matters

    Read the Kelly Turnbull novels to see where California is and will go: https://www.amazon.com/s?k=kelly+tur..._2_15_ts-doa-p

    Comment

    • #3
      tomrkba
      Senior Member
      • Jun 2016
      • 1513

      Also, is the new machine using python 3.x? Was this written for python 2.7? This could be the cause as well as the source of bugs you have yet to encounter.
      Biden's
      Laptop
      Matters

      Read the Kelly Turnbull novels to see where California is and will go: https://www.amazon.com/s?k=kelly+tur..._2_15_ts-doa-p

      Comment

      • #4
        tomrkba
        Senior Member
        • Jun 2016
        • 1513

        Also, port should likely not be 0. Likely this is the source of the error. Write some defensive code to verify the port and handle 0 properly.

        sonar_port = FakeSonarPacket(0, 115200, 4)
        Last edited by tomrkba; 06-29-2019, 10:48 AM.
        Biden's
        Laptop
        Matters

        Read the Kelly Turnbull novels to see where California is and will go: https://www.amazon.com/s?k=kelly+tur..._2_15_ts-doa-p

        Comment

        • #5
          Frozenguy
          CGN/CGSSA Contributor
          CGN Contributor
          • Jan 2008
          • 6303

          Originally posted by tomrkba
          Declare port as type string, not int. See last line. I would cast it to type string for the scope of that function since it is an int upstream.
          Hey thanks for taking a look.
          I have good reason to believe this was written on a machine with 2.7. I am running anaconda 3.x.
          python --version returns 3.7.1

          I tried what I thought it was asking but I don't know exactly how to do that. I know you use "" or '' for strings. I'm not even sure what I have the port set to.


          Is the 0 the port number? Make that a string?
          I'm new to python and not had any formal training in coding. Just an engineer that taught himself along the way.


          def __init__(self, port, baud, number):
          [...]
          sonar_port = FakeSonarPacket(0, 115200, 4)

          Comment

          • #6
            Frozenguy
            CGN/CGSSA Contributor
            CGN Contributor
            • Jan 2008
            • 6303

            Originally posted by tomrkba
            Also, port should likely not be 0. Likely this is the source of the error. Write some defensive code to verify the port and handle 0 properly.

            sonar_port = FakeSonarPacket(0, 115200, 4)
            To verify the port? Can I just change it to 1?

            Comment

            • #7
              Fizz
              Senior Member
              • Feb 2012
              • 1473

              Quick review.

              The script you posted isn't the one errored out, but the imported module.

              Line 156 - sonar_port = FakeSonarPacket(0, 115200, 4) is passing 0, 115200, and 4 as integers to the function FakeSonarPacket(), but "port" is expected to be a String, not an int.

              So, you might try modifying Line 156 to FakeSonarPacket("0", "115200", "4") or FakeSonarPacket(str(0, 115200, 4)) <<< this might not be proper

              In Python, variables are dynamically typed, so it is possible to have a variable with no type until the first time it is used. The first time it's used is as INT, so that sticks.

              Comment

              • #8
                zhyla
                Banned
                • Aug 2009
                • 2017

                Originally posted by Frozenguy
                I have good reason to believe this was written on a machine with 2.7. I am running anaconda 3.x.
                python --version returns 3.7.1
                Install and/or point your environment to Python 2.x and it should work fine.

                Comment

                • #9
                  pepsi2451
                  Senior Member
                  • Feb 2006
                  • 1629

                  The serial library you are using expects the serial port as a string and the baud as an int. So for example if you wanted to use COM1 on windows you would use:

                  sonar_port = FakeSonarPacket("COM1", 115200, 4)

                  Comment

                  • #10
                    Fizz
                    Senior Member
                    • Feb 2012
                    • 1473

                    Originally posted by pepsi2451
                    The serial library you are using expects the serial port as a string and the baud as an int. So for example if you wanted to use COM1 on windows you would use:

                    sonar_port = FakeSonarPacket("COM1", 115200, 4)
                    If OP is on a Linux system, the "0" may be correct and automatically prepending the type, referring to ttyS0 or equivalent.

                    Without going through the whole thing, there are various checks for len(), unfortunately len() doesn't work with variable type Int, so if you're looking to to check length of an Int, the variable will need to be type string to start with or converted within a given statement.

                    Comment

                    • #11
                      pepsi2451
                      Senior Member
                      • Feb 2006
                      • 1629

                      Originally posted by Fizz
                      If OP is on a Linux system, the "0" may be correct and automatically prepending the type, referring to ttyS0 or equivalent.

                      Without going through the whole thing, there are various checks for len(), unfortunately len() doesn't work with variable type Int, so if you're looking to to check length of an Int, the variable will need to be type string to start with or converted within a given statement.
                      You are right, I would try "0" as a string first. If that doesn't work I would try the entire address ("/dev/ttys0" or COM0 or whatever)

                      Comment

                      • #12
                        Frozenguy
                        CGN/CGSSA Contributor
                        CGN Contributor
                        • Jan 2008
                        • 6303

                        On a cell phone right now so hard to individually respond but thank you everyone for the feedback.

                        I’m on a windows 10 machine but it’s mildly possible that it was originally written on a Linux or Linux shell for windows.

                        I’ll try “COM1” and then try installing 2.7 if I’m still getting troubles. Should get back here later this evening with a result.

                        Comment

                        • #13
                          71MUSTY
                          Calguns Addict
                          • Mar 2014
                          • 7029

                          Originally posted by 50 yarder
                          That's not what I thought this thread would be about.
                          Exactly I was thinking 357 or 44
                          Last edited by 71MUSTY; 06-29-2019, 5:27 PM.
                          Only slaves don't need guns

                          Originally posted by epilepticninja
                          Americans vs. Democrats
                          We stand for the Anthem, we kneel for the cross


                          We already have the only reasonable Gun Control we need, It's called the Second Amendment and it's the government it controls.


                          What doesn't kill me, better run

                          Comment

                          • #14
                            Frozenguy
                            CGN/CGSSA Contributor
                            CGN Contributor
                            • Jan 2008
                            • 6303

                            Here is the error after typing in "COM1" instead of 0.

                            Traceback (most recent call last):
                            File "C:\Users\peter.bradbury\Desktop\fake_sonar_packet .py", line 157, in <module>
                            sonar_port.open()
                            File "C:\Users\peter.bradbury\Desktop\fake_sonar_packet .py", line 23, in open
                            self.ser.open()
                            File "C:\Users\peter.bradbury\AppData\Local\Continuum\a naconda3\lib\site-packages\serial\serialwin32.py", line 62, in open
                            raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
                            serial.serialutil.SerialException: could not open port 'COM1': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)
                            I'm installing anaconda 2.7 right now to see if that can clear things up..

                            Comment

                            • #15
                              Robotron2k84
                              Senior Member
                              • Sep 2017
                              • 2013

                              Just try "0", for the port. The library may enumerate serial ports attached to the system and just needs a scalar to point to the logical port in an array.

                              Comment

                              Working...
                              UA-8071174-1