is there a problem on this simple code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jrlen balane

    #1

    is there a problem on this simple code

    basically what the code does is transmit data to a hardware and then
    receive data that the hardware will transmit.

    import serial
    import string
    import time
    from struct import *


    ser = serial.Serial()

    ser.baudrate = 9600
    ser.port = 0
    ser
    ser.close()
    ser.open()

    command = 67
    message_no = 1
    total_data = 2

    item = 12000 #to warm-up the hardware
    hexed = hex(item)
    data_hi, data_lo = divmod(item, 0x100)
    checksum = -(data_hi + data_lo + 0x46) & 0xff
    ser.write(pack( '6B', command, message_no, total_data, data_lo,
    data_hi, checksum)) #serial transmit protocol
    time.sleep(1)

    item = 10000
    no = 0
    for item in range(10000, 30001, 250):
    no = no +1
    hexed = hex(item)
    data_hi, data_lo = divmod(item, 0x100)
    checksum = -(data_hi + data_lo + 0x46) & 0xff
    ser.write(pack( '6B', command, message_no, total_data, data_lo,
    data_hi, checksum))
    data = ser.read(10)
    (command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
    voltage, current, checksum) = unpack('10B', data) #serial receive
    protocol
    print no, command, msg_no, no_databyte, temp1, temp2, pyra1,
    pyra2, voltage, current, checksum
    time.sleep(1)

    ser.close()


    =============== ============
    and here is some result after running the program on Idle Python 2.3
    (enthought ed.)

    1 70 168 6 0 0 0 0 0 0 12
    2 70 2 6 0 0 0 0 0 0 178
    3 70 3 6 0 0 0 0 0 0 177
    4 70 4 6 0 0 0 0 0 0 176
    5 70 5 6 0 0 0 0 0 0 175
    6 70 6 6 0 0 0 0 0 0 174
    7 70 7 6 0 0 0 0 0 0 173
    8 70 8 6 0 0 0 0 0 0 172
    9 70 9 6 0 0 0 0 0 0 171
    10 70 10 6 0 0 0 0 0 0 170
    11 70 11 6 0 0 0 0 0 0 169
    12 70 12 6 0 0 0 0 0 0 168
    13 70 13 6 0 0 0 0 0 0 167
    14 70 14 6 0 0 0 0 0 0 166
    15 70 15 6 0 0 0 0 0 0 165

    =============== ===========

    the result i am expecting is for the data bytes (bytes 4-9) to change
    its value since i am able to control the sensors which the data were
    based. i am just asking for your opinion if there is something wrong
    with this program, otherwise, it could be a hardware problem.

    thanks in advance.
  • Harlin Seritt

    #2
    Re: is there a problem on this simple code

    hah, this code is anything but simple...

    Comment

    • jrlen balane

      #3
      Re: is there a problem on this simple code

      @sir harlin
      so you are saying that there is nothing wrong in this simple program.


      On 12 Mar 2005 07:39:31 -0800, Harlin Seritt <harlinseritt@y ahoo.com> wrote:[color=blue]
      > hah, this code is anything but simple...
      >
      > --
      > http://mail.python.org/mailman/listinfo/python-list
      >[/color]

      Comment

      • mensanator@aol.com

        #4
        Re: is there a problem on this simple code


        jrlen balane wrote:[color=blue]
        > basically what the code does is transmit data to a hardware and then
        > receive data that the hardware will transmit.
        >
        > import serial
        > import string
        > import time
        > from struct import *
        >
        >
        > ser = serial.Serial()
        >
        > ser.baudrate = 9600
        > ser.port = 0
        > ser
        > ser.close()
        > ser.open()
        >
        > command = 67
        > message_no = 1
        > total_data = 2
        >
        > item = 12000 #to warm-up the hardware
        > hexed = hex(item)
        > data_hi, data_lo = divmod(item, 0x100)
        > checksum = -(data_hi + data_lo + 0x46) & 0xff
        > ser.write(pack( '6B', command, message_no, total_data, data_lo,
        > data_hi, checksum)) #serial transmit protocol
        > time.sleep(1)
        >
        > item = 10000
        > no = 0
        > for item in range(10000, 30001, 250):
        > no = no +1
        > hexed = hex(item)
        > data_hi, data_lo = divmod(item, 0x100)
        > checksum = -(data_hi + data_lo + 0x46) & 0xff
        > ser.write(pack( '6B', command, message_no, total_data, data_lo,
        > data_hi, checksum))[/color]

        What actually gets transmitted is "C\x01\x02\x10' \x83".
        That's 18 bytes. Is the command supposed to be the ASCII
        characters \x01 or a single byte whose value is 1?

        [color=blue]
        > data = ser.read(10)
        > (command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
        > voltage, current, checksum) = unpack('10B', data) #serial receive
        > protocol
        > print no, command, msg_no, no_databyte, temp1, temp2, pyra1,
        > pyra2, voltage, current, checksum
        > time.sleep(1)
        >
        > ser.close()
        >
        >
        > =============== ============
        > and here is some result after running the program on Idle Python 2.3
        > (enthought ed.)
        >
        > 1 70 168 6 0 0 0 0 0 0 12
        > 2 70 2 6 0 0 0 0 0 0 178
        > 3 70 3 6 0 0 0 0 0 0 177
        > 4 70 4 6 0 0 0 0 0 0 176
        > 5 70 5 6 0 0 0 0 0 0 175
        > 6 70 6 6 0 0 0 0 0 0 174
        > 7 70 7 6 0 0 0 0 0 0 173
        > 8 70 8 6 0 0 0 0 0 0 172
        > 9 70 9 6 0 0 0 0 0 0 171
        > 10 70 10 6 0 0 0 0 0 0 170
        > 11 70 11 6 0 0 0 0 0 0 169
        > 12 70 12 6 0 0 0 0 0 0 168
        > 13 70 13 6 0 0 0 0 0 0 167
        > 14 70 14 6 0 0 0 0 0 0 166
        > 15 70 15 6 0 0 0 0 0 0 165
        >
        > =============== ===========
        >
        > the result i am expecting is for the data bytes (bytes 4-9) to change
        > its value since i am able to control the sensors which the data were
        > based. i am just asking for your opinion if there is something wrong
        > with this program, otherwise, it could be a hardware problem.
        >
        > thanks in advance.[/color]

        Comment

        • John Machin

          #5
          Re: is there a problem on this simple code

          jrlen balane *TOP-POSTED*:[color=blue]
          > On 12 Mar 2005 07:39:31 -0800, Harlin Seritt <harlinseritt@y ahoo.com>[/color]
          wrote:[color=blue][color=green]
          > > hah, this code is anything but simple...
          > >
          > > --
          > > http://mail.python.org/mailman/listinfo/python-list
          > >[/color]
          > @sir harlin
          > so you are saying that there is nothing wrong in this simple program.[/color]

          No, he is saying that it is not simple IHHO. Neither are your
          explanations IMHO. What does "(enthought ed.)" mean??

          Some observations:

          The variable message_no is set to 1 initially, but thereafter is set to
          the message_no returned from the hardware -- 168 the first time. This
          is at best very confusing. I'd suggest two separate variables,
          to_hw_msg_no and from_hw_msg_no. Does the hardware reject a message
          with a number that is not ((previous msg no + 1) % 256)?

          You have a similar problem with "command"; initially 67 but then is set
          to what comes back from the hardware i.e. 70. Again confusing, maybe
          wrong, use 2 variables to_hw_command and from_hw_command .

          Some suggestions:

          (1) read the manual for the hardware interface

          (2) look at all the variables you have; what are they for? E.g. "hexed"
          is computed but never used. Clean out the irrelevant stuff and it may
          become simple enough for delicate folk like Harlin to be able to read
          it :-)

          (3) are you sure you have the check-sum right? Using a hard-coded 0x46
          (= 67 + 1 + 2) is dangerous! Recall command was 67 but then changes to
          70! What does the manual say happens if the check-sum fails? It would
          be sensible to compute the check-sum from the *ACTUAL* data that is
          being sent: check_sum = 256 - (to_hw_command + to_hw_msg_no +
          total_data + data_lo + data_hi) & 0xff -- but see next point.

          (4) If the program is going to become more complicated, you should get
          some structure into it. For example a function
          bytes_to_hardwa re(command, msg_no, list_or_tuple_o f_ints) would be a
          good idea -- it would compute the data-length and the check_sum and do
          the struct.pack(), ONCE.

          Then you could have another function (say)
          !def item_to_hardwar e(command, msg_no, item):
          ! bytes_to_hardwa re(command, msg_no, divmod(1tem, 256))

          (5) Not only are the data values not changing, they appear to be all
          zero; what does this mean?

          (6) You are not validating the checksum coming back from the hardware;
          the values printed out appear to be OK -- that is, they sum to zero
          modulo 256; check the manual to see if this is the correct expectation!
          -- but the point of having a CHECKsum is that you should CHECK it. It
          may not be OK tomorrow.

          (7) What does command=70 coming back from the hardware mean? Are there
          "commands" that mean (a) invalid command received (b) failure in
          message_number protocol (c) check_sum error in received message? If so,
          augment your program to check for these. If not, or the h/w doesn't
          respond appropriately when you send it a bad message, drop it down the
          great white chute in your bathroom :-)

          Comment

          • John Machin

            #6
            Re: is there a problem on this simple code


            mensanator@aol. com wrote:[color=blue]
            >
            > What actually gets transmitted is "C\x01\x02\x10' \x83".[/color]

            No, that's repr(What actually gets transmitted)
            [color=blue]
            > That's 18 bytes. Is the command supposed to be the ASCII
            > characters \x01 or a single byte whose value is 1?[/color]

            For a start, according to the OP's code, the command ('C' a.k.a. 67) is
            first. The 1 is a meant to be a message number.

            Secondly, the hardware smells like it's got an 8080 or 6502 inside. The
            likelihood that it groks Python/C string representation is minimal.
            Folk just don't send 18 bytes at 9600 bps when 6 bytes will do.

            Comment

            • Bengt Richter

              #7
              Re: is there a problem on this simple code

              On 12 Mar 2005 17:35:50 -0800, "John Machin" <sjmachin@lexic on.net> wrote:
              [color=blue]
              >
              >mensanator@aol .com wrote:[color=green]
              >>
              >> What actually gets transmitted is "C\x01\x02\x10' \x83".[/color]
              >
              >No, that's repr(What actually gets transmitted)[/color]

              If so, that's 6 bytes, not 18:
              [color=blue][color=green][color=darkred]
              >>> "C\x01\x02\x10' \x83"[/color][/color][/color]
              "C\x01\x02\x10' \x83"[color=blue][color=green][color=darkred]
              >>> list("C\x01\x02 \x10'\x83")[/color][/color][/color]
              ['C', '\x01', '\x02', '\x10', "'", '\x83'][color=blue][color=green][color=darkred]
              >>> len("C\x01\x02\ x10'\x83")[/color][/color][/color]
              6

              OTOH,[color=blue][color=green][color=darkred]
              >>> list(r"C\x01\x0 2\x10'\x83")[/color][/color][/color]
              ['C', '\\', 'x', '0', '1', '\\', 'x', '0', '2', '\\', 'x', '1', '0', "'", '\\', 'x', '8', '3'][color=blue][color=green][color=darkred]
              >>> len(r"C\x01\x02 \x10'\x83")[/color][/color][/color]
              18
              [color=blue]
              >[color=green]
              >> That's 18 bytes. Is the command supposed to be the ASCII
              >> characters \x01 or a single byte whose value is 1?[/color]
              >
              >For a start, according to the OP's code, the command ('C' a.k.a. 67) is
              >first. The 1 is a meant to be a message number.
              >
              >Secondly, the hardware smells like it's got an 8080 or 6502 inside. The
              >likelihood that it groks Python/C string representation is minimal.
              >Folk just don't send 18 bytes at 9600 bps when 6 bytes will do.
              >[/color]

              Regards,
              Bengt Richter

              Comment

              • John Machin

                #8
                Re: is there a problem on this simple code


                Bengt Richter wrote:[color=blue]
                > On 12 Mar 2005 17:35:50 -0800, "John Machin" <sjmachin@lexic on.net>[/color]
                wrote:[color=blue]
                >[color=green]
                > >
                > >mensanator@aol .com wrote:[color=darkred]
                > >>
                > >> What actually gets transmitted is "C\x01\x02\x10' \x83".[/color]
                > >
                > >No, that's repr(What actually gets transmitted)[/color]
                >
                > If so, that's 6 bytes, not 18:
                >[color=green][color=darkred]
                > >>> "C\x01\x02\x10' \x83"[/color][/color]
                > "C\x01\x02\x10' \x83"[color=green][color=darkred]
                > >>> list("C\x01\x02 \x10'\x83")[/color][/color]
                > ['C', '\x01', '\x02', '\x10', "'", '\x83'][color=green][color=darkred]
                > >>> len("C\x01\x02\ x10'\x83")[/color][/color]
                > 6
                >
                > OTOH,[color=green][color=darkred]
                > >>> list(r"C\x01\x0 2\x10'\x83")[/color][/color]
                > ['C', '\\', 'x', '0', '1', '\\', 'x', '0', '2', '\\', 'x', '1', '0',[/color]
                "'", '\\', 'x', '8', '3'][color=blue][color=green][color=darkred]
                > >>> len(r"C\x01\x02 \x10'\x83")[/color][/color]
                > 18
                >[color=green]
                > >[color=darkred]
                > >> That's 18 bytes. Is the command supposed to be the ASCII
                > >> characters \x01 or a single byte whose value is 1?[/color]
                > >
                > >For a start, according to the OP's code, the command ('C' a.k.a. 67)[/color][/color]
                is[color=blue][color=green]
                > >first. The 1 is a meant to be a message number.
                > >
                > >Secondly, the hardware smells like it's got an 8080 or 6502 inside.[/color][/color]
                The[color=blue][color=green]
                > >likelihood that it groks Python/C string representation is minimal.
                > >Folk just don't send 18 bytes at 9600 bps when 6 bytes will do.
                > >[/color]
                >
                > Regards,
                > Bengt Richter[/color]

                The number of bytes transmitted is 6. However the length of the visual
                representation of what was sent is 18. Mensator was confused by this,
                as was apparent from his/her question "Is the command supposed to be
                the ASCII characters \x01 or a single byte whose value is 1?". I tried
                to explain this to him/her. However it's not apparent whether your post
                is part of the problem or part of the solution. Enlightenment, please.

                Comment

                • mensanator@aol.com

                  #9
                  Re: is there a problem on this simple code


                  John Machin wrote:[color=blue]
                  > mensanator@aol. com wrote:[color=green]
                  > >
                  > > What actually gets transmitted is "C\x01\x02\x10' \x83".[/color]
                  >
                  > No, that's repr(What actually gets transmitted)[/color]

                  Drat, I always get burned by that.
                  [color=blue]
                  >[color=green]
                  > > That's 18 bytes. Is the command supposed to be the ASCII
                  > > characters \x01 or a single byte whose value is 1?[/color]
                  >
                  > For a start, according to the OP's code, the command ('C' a.k.a. 67)[/color]
                  is[color=blue]
                  > first. The 1 is a meant to be a message number.[/color]

                  Yeah, that's what I meant.
                  [color=blue]
                  >
                  > Secondly, the hardware smells like it's got an 8080 or 6502 inside.[/color]
                  The[color=blue]
                  > likelihood that it groks Python/C string representation is minimal.[/color]

                  That's what I was thinking. And maybe the replies he's seeing
                  from the hardware is an error message because it doesn't
                  understand what it's seeing (which could be due to other things).
                  A datascope would come in handy for this situation.
                  [color=blue]
                  > Folk just don't send 18 bytes at 9600 bps when 6 bytes will do.[/color]

                  Comment

                  • Bengt Richter

                    #10
                    Re: is there a problem on this simple code

                    On 12 Mar 2005 20:12:19 -0800, "John Machin" <sjmachin@lexic on.net> wrote:
                    [color=blue]
                    >
                    >Bengt Richter wrote:[color=green]
                    >> On 12 Mar 2005 17:35:50 -0800, "John Machin" <sjmachin@lexic on.net>[/color]
                    >wrote:[color=green]
                    >>[color=darkred]
                    >> >
                    >> >mensanator@aol .com wrote:
                    >> >>
                    >> >> What actually gets transmitted is "C\x01\x02\x10' \x83".
                    >> >
                    >> >No, that's repr(What actually gets transmitted)[/color]
                    >>
                    >> If so, that's 6 bytes, not 18:
                    >>[color=darkred]
                    >> >>> "C\x01\x02\x10' \x83"[/color]
                    >> "C\x01\x02\x10' \x83"[color=darkred]
                    >> >>> list("C\x01\x02 \x10'\x83")[/color]
                    >> ['C', '\x01', '\x02', '\x10', "'", '\x83'][color=darkred]
                    >> >>> len("C\x01\x02\ x10'\x83")[/color]
                    >> 6
                    >>
                    >> OTOH,[color=darkred]
                    >> >>> list(r"C\x01\x0 2\x10'\x83")[/color]
                    >> ['C', '\\', 'x', '0', '1', '\\', 'x', '0', '2', '\\', 'x', '1', '0',[/color]
                    >"'", '\\', 'x', '8', '3'][color=green][color=darkred]
                    >> >>> len(r"C\x01\x02 \x10'\x83")[/color]
                    >> 18
                    >>[color=darkred]
                    >> >
                    >> >> That's 18 bytes. Is the command supposed to be the ASCII
                    >> >> characters \x01 or a single byte whose value is 1?
                    >> >
                    >> >For a start, according to the OP's code, the command ('C' a.k.a. 67)[/color][/color]
                    >is[color=green][color=darkred]
                    >> >first. The 1 is a meant to be a message number.
                    >> >
                    >> >Secondly, the hardware smells like it's got an 8080 or 6502 inside.[/color][/color]
                    >The[color=green][color=darkred]
                    >> >likelihood that it groks Python/C string representation is minimal.
                    >> >Folk just don't send 18 bytes at 9600 bps when 6 bytes will do.
                    >> >[/color]
                    >>
                    >> Regards,
                    >> Bengt Richter[/color]
                    >
                    >The number of bytes transmitted is 6. However the length of the visual
                    >representati on of what was sent is 18. Mensator was confused by this,
                    >as was apparent from his/her question "Is the command supposed to be
                    >the ASCII characters \x01 or a single byte whose value is 1?". I tried
                    >to explain this to him/her. However it's not apparent whether your post
                    >is part of the problem or part of the solution. Enlightenment, please.
                    >[/color]

                    Sorry for jumping in with a largely irrelevant comment. I didn't look
                    at the code, just sought to illustrate the 6/18 thing further, in a kneejerk reaction.
                    Though BTW FWIW the visual sequence of glyphs representing the data was more a str output
                    than repr, I guess:
                    [color=blue][color=green][color=darkred]
                    >>> repr("C\x01\x02 \x10'\x83")[/color][/color][/color]
                    '"C\\x01\\x02\\ x10\'\\x83"'[color=blue][color=green][color=darkred]
                    >>> str("C\x01\x02\ x10'\x83")[/color][/color][/color]
                    "C\x01\x02\x10' \x83"

                    Sorry, no enlightenment ;-)

                    Regards,
                    Bengt Richter

                    Comment

                    • jrlen balane

                      #11
                      Re: is there a problem on this simple code

                      the hardware is a school project that uses a microcontroller for "light dimming"
                      the message command "67" will tell the microcontroller (PIC16F877) to
                      do a command (to control the intensity of a lamp)
                      the message command "70" should tell the GUI that the microcontroller
                      has started transmitting.
                      the message sent by the GUI is different from the message sent by the
                      microcontroller
                      (but i guess sir John is right, i think i should use different
                      variable for the data transmitted and data received)
                      i am currently developing this part of the project which implements
                      the serial communication
                      i've fixed the command and total_data since i know beforehand that
                      this will be its value.
                      to simplify the program, i have also fixed the message_no since the
                      microcontroller will still accept the transmitted data as long as the
                      checksum == 0.

                      anymore suggestion???.. .
                      =============== =============== =============== =====
                      command = 67
                      message_no = 1
                      total_data = 2
                      item=10000
                      for item in range(10000, 30001, 250):
                      ser.open()
                      data_hi, data_lo = divmod(item, 0x100)
                      checksum = -(data_hi + data_lo + 0x46) & 0xff
                      ser.write(pack( '6B', command, message_no, total_data, data_lo,
                      data_hi, checksum))
                      data = ser.read(10)
                      (command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
                      voltage, current, checksum) = unpack('10B', data) #serial receive
                      protocol
                      print command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
                      voltage, current, checksum
                      ser.flushInput( )
                      ser.close()

                      =============== =============== =====
                      i've rewritten the code and deleted some unnecessary entries, now the
                      problem is :
                      21 6 64 64 192 0 0 0 175 70
                      70 2 6 64 64 192 0 0 0 114
                      70 11 6 64 64 192 0 0 0 105
                      0 0 104 70 2 6 64 64 192 0
                      70 2 6 64 64 192 0 0 0 114
                      128 128 103 70 2 6 64 64 192 0
                      70 2 6 64 64 192 0 0 0 114
                      16 208 246 70 2 6 64 64 192 0
                      70 2 6 64 64 192 0 0 0 114

                      =============== =============== =====
                      the received data does not always start with the command "70",
                      is this ok??? since i can always search first for the command "70"
                      before i read the remaining 9 bytes, then calculate first for the
                      checksum before finally accepting the received data.

                      am i making sense here?! please help me...

                      Comment

                      • jrlen balane

                        #12
                        Re: is there a problem on this simple code

                        this is not working, what is wrong with this code?? what it "should"
                        do is find first the command "70" then read the remaining 9 bytes once
                        the command was found:

                        rx_data1=0
                        while (rx_data1 != 0x46):
                        rx_data1 = ser.read(1)
                        (rx_command) = unpack('1B', rx_data1)

                        rc_data2=ser.re ad(9)
                        (rx_msg_no, rx_no_databyte, temp1, temp2, pyra1, pyra2, voltage,
                        current, rx_checksum) = unpack('9B', data)
                        print rx_command, rx_msg_no, rx_no_databyte, temp1, temp2, pyra1,
                        pyra2, voltage, current, rx_checksum
                        =============== =============== =====

                        this replaces this chunk from the original code:
                        data = ser.read(10)
                        (command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
                        voltage, current, checksum) = unpack('10B', data) #serial receive
                        protocol
                        print command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
                        voltage, current, checksum

                        =============== =============== =====

                        thanks again

                        Comment

                        • Dennis Lee Bieber

                          #13
                          Re: is there a problem on this simple code

                          On Sun, 13 Mar 2005 14:56:55 +0800, jrlen balane <nbbalane@gmail .com>
                          declaimed the following in comp.lang.pytho n:
                          [color=blue]
                          > to simplify the program, i have also fixed the message_no since the
                          > microcontroller will still accept the transmitted data as long as the
                          > checksum == 0.[/color]

                          Ah, but DOES the checksum = 0?

                          I notice you haven't been testing the received data checksum, or
                          you would have noticed that it sums ALL bytes from the command
                          introducer to just before the checksum value.

                          From the middle of your data listing:
                          [color=blue]
                          > 70 2 6 64 64 192 0 0 0 114[/color]
                          [color=blue][color=green][color=darkred]
                          >>> print -(70 + 2 + 6 + 64 + 64 + 192) & 0xFF[/color][/color][/color]
                          114[color=blue][color=green][color=darkred]
                          >>> print -(70 + 2 + 6 + 64 + 64 + 192 + 114) & 0xFF[/color][/color][/color]
                          0[color=blue][color=green][color=darkred]
                          >>>[/color][/color][/color]

                          That would seem to imply that the checksum you should be sending
                          ALSO incorporates all bytes. This time, from your code...
                          [color=blue]
                          > checksum = -(data_hi + data_lo + 0x46) & 0xff
                          > ser.write(pack( '6B', command, message_no, total_data, data_lo,
                          > data_hi, checksum))[/color]

                          You are calculating a checksum that is not including the
                          message_no and total_data fields. What happens if you use:

                          checksum = -(command + message_no, + total_data +
                          data_lo, data_hi) & 0xFF

                          [color=blue]
                          > 21 6 64 64 192 0 0 0 175 70
                          > 70 2 6 64 64 192 0 0 0 114
                          > 70 11 6 64 64 192 0 0 0 105
                          > 0 0 104 70 2 6 64 64 192 0
                          > 70 2 6 64 64 192 0 0 0 114[/color]
                          [color=blue]
                          > the received data does not always start with the command "70",
                          > is this ok??? since i can always search first for the command "70"[/color]

                          Ah, but /can/ you search for the first 70... Notice how your
                          first line of data ENDED with a 70. If you treat that as the
                          command/response introducer, and then read 9 more bytes, you will be
                          reading
                          70 message number
                          2 data length
                          6 data1
                          64 data2
                          64 ?
                          192 ?
                          0 ?
                          0 ?
                          0 checksum

                          Off-hand, I'd have to wonder if you are losing bytes during your
                          processing -- is there any active hardware handshaking on that serial
                          port (9600bps is getting rather fast for no handshaking).
                          [color=blue]
                          > 70 11 6 64 64 192 0 0 0 105
                          > 0 0 104 70 2 6 64 64 192 0
                          > 70 2 6 64 64 192 0 0 0 114[/color]

                          Note how the first line I've quoted is a valid response with message
                          number 11. Then, look at the next line -- "0 0 104", if you assume the
                          104 is a checksum, it would be consistent with a message string of "70
                          12 6 64 64 129 0 0 0 104". Message number of 12, an incrementing
                          sequence, but you've lost 7 bytes. You then have seven bytes that start
                          a response, but are missing the last three, before getting a full line
                          with message number 2 (which seems to be rcvd#+1, if you are sending a
                          constant 1).
                          [color=blue]
                          > before i read the remaining 9 bytes, then calculate first for the
                          > checksum before finally accepting the received data.
                          >
                          > am i making sense here?! please help me...[/color]

                          I have the feeling you should modularize down to a function to
                          retrieve a response that makes use of the data length... In pseudo-code
                          (since I don't know the serial module in use):

                          def getPacket():
                          data = []
                          checksum = 0
                          (message_code, sequence_no, data_length) = serial.read(3)
                          checksum = message_code + sequence_no + data_length
                          for d in range(data_leng th):
                          data.append(ser ial.read(1))
                          checksum += data[d]
                          checksum += serial.read(1)
                          if (-checksum & 0xFF) != 0:
                          #bad packet -- raise an exception?
                          return (message_code, sequence_no, data_length, data)
                          #don't need to return checksum, it has been tested already

                          For completeness, a send probably should be created also...

                          def sendPacket(mess age_code, sequence_no, data=None):
                          #don't need data_length, as that would be computed from the
                          #length of data itself; 0 for [] or None, otherwise len(data)


                          If you are losing data from lack of handshaking and data
                          overrun, you may need to make the getPacket routine into a thread (and
                          maybe another thread for sending), so it can just do continuous reading,
                          and for every valid response sequence put it onto a Queue, where the
                          main thread can extract it when it is ready to process the contents.


                          --[color=blue]
                          > =============== =============== =============== =============== == <
                          > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                          > wulfraed@dm.net | Bestiaria Support Staff <
                          > =============== =============== =============== =============== == <
                          > Home Page: <http://www.dm.net/~wulfraed/> <
                          > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

                          Comment

                          • Dennis Lee Bieber

                            #14
                            Re: is there a problem on this simple code

                            On Sun, 13 Mar 2005 15:12:24 +0800, jrlen balane <nbbalane@gmail .com>
                            declaimed the following in comp.lang.pytho n:
                            [color=blue]
                            > this is not working, what is wrong with this code?? what it "should"[/color]

                            Insufficient data... What is it /doing/ that makes you say it
                            "is not working".
                            [color=blue]
                            > do is find first the command "70" then read the remaining 9 bytes once
                            > the command was found:
                            >[/color]
                            See my prior response, where you had a line ending a 70,
                            followed by a valid line starting with 70... If you were reading for the
                            first 70, and then took 9 more bytes, you were reading garbage -- the
                            code is doing exactly what you asked for.
                            [color=blue]
                            > rx_data1=0
                            > while (rx_data1 != 0x46):
                            > rx_data1 = ser.read(1)
                            > (rx_command) = unpack('1B', rx_data1)[/color]

                            Isn't this unpack rather redundant -- assuming ser.read(1) only
                            reads one byte, then rx_data1 and rx_command would be identical.
                            [color=blue]
                            >
                            > rc_data2=ser.re ad(9)
                            > (rx_msg_no, rx_no_databyte, temp1, temp2, pyra1, pyra2, voltage,
                            > current, rx_checksum) = unpack('9B', data)
                            > print rx_command, rx_msg_no, rx_no_databyte, temp1, temp2, pyra1,
                            > pyra2, voltage, current, rx_checksum[/color]

                            Are your data arguments in the correct order? On your previous
                            message, the slots for voltage and current were coming back as 0, 0
                            while temp1 and temp2 had non-zero values.

                            --[color=blue]
                            > =============== =============== =============== =============== == <
                            > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                            > wulfraed@dm.net | Bestiaria Support Staff <
                            > =============== =============== =============== =============== == <
                            > Home Page: <http://www.dm.net/~wulfraed/> <
                            > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

                            Comment

                            • John Machin

                              #15
                              Re: is there a problem on this simple code


                              jrlen balane wrote:[color=blue]
                              > the hardware is a school project that uses a microcontroller for[/color]
                              "light dimming"[color=blue]
                              > the message command "67" will tell the microcontroller (PIC16F877) to
                              > do a command (to control the intensity of a lamp)
                              > the message command "70" should tell the GUI that the microcontroller
                              > has started transmitting.
                              > the message sent by the GUI is different from the message sent by the
                              > microcontroller
                              > (but i guess sir John is right, i think i should use different
                              > variable for the data transmitted and data received)
                              > i am currently developing this part of the project which implements
                              > the serial communication
                              > i've fixed the command and total_data since i know beforehand that
                              > this will be its value.
                              > to simplify the program, i have also fixed the message_no since the
                              > microcontroller will still accept the transmitted data as long as the
                              > checksum == 0.[/color]

                              (1) But it's NOT zero after the first time around! (2) How do you know
                              what it will accept? Guessing or reading the manual? If the checksum is
                              not zero, then what happens? Please quote the exact section from the
                              manual.
                              [color=blue]
                              >
                              > anymore suggestion???.. .[/color]

                              YES: show the whole program; you have left out the initialisation part.
                              [color=blue]
                              > =============== =============== =============== =====
                              > command = 67
                              > message_no = 1
                              > total_data = 2
                              > item=10000
                              > for item in range(10000, 30001, 250):
                              > ser.open()
                              > data_hi, data_lo = divmod(item, 0x100)
                              > checksum = -(data_hi + data_lo + 0x46) & 0xff
                              > ser.write(pack( '6B', command, message_no, total_data, data_lo,
                              > data_hi, checksum))
                              > data = ser.read(10)
                              > (command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
                              > voltage, current, checksum) = unpack('10B', data) #serial receive
                              > protocol
                              > print command, msg_no, no_databyte, temp1, temp2, pyra1, pyra2,
                              > voltage, current, checksum
                              > ser.flushInput( )
                              > ser.close()
                              >
                              > =============== =============== =====
                              > i've rewritten the code and deleted some unnecessary entries, now the
                              > problem is :
                              > 21 6 64 64 192 0 0 0 175 70
                              > 70 2 6 64 64 192 0 0 0 114
                              > 70 11 6 64 64 192 0 0 0 105
                              > 0 0 104 70 2 6 64 64 192 0
                              > 70 2 6 64 64 192 0 0 0 114
                              > 128 128 103 70 2 6 64 64 192 0
                              > 70 2 6 64 64 192 0 0 0 114
                              > 16 208 246 70 2 6 64 64 192 0
                              > 70 2 6 64 64 192 0 0 0 114
                              >
                              > =============== =============== =====
                              > the received data does not always start with the command "70",
                              > is this ok??? since i can always search first for the command "70"
                              > before i read the remaining 9 bytes, then calculate first for the
                              > checksum before finally accepting the received data.
                              >
                              > am i making sense here?! please help me...[/color]

                              As Dennis has told you, searching is pointless. You are losing data
                              now. Before you weren't losing data. Until you fix that problem,
                              fiddling with anything else is pointless. You have stopped doing
                              sleep() -- why? You are now doing ser.open() and ser.flushInput( ) and
                              ser.close() on *each* time around the loop -- why? I'd strongly suggest
                              you put these back the way they were. THEN do what I told you to do:
                              use a separate tx_command and rx_command. The first time through the
                              loop, command is set to 70 from the received data, and then the second
                              time around, you SEND 70, not 67!!! Fix that, and then show us what you
                              get. DON'T try searching for a 70. Don't thrash around trying multiple
                              changes at once -- make changes one at a time so you can see the
                              effects.

                              Do you have a part number for the manual which describes the 67 and 70
                              "commands" and the check-sum? Is the manual on the internet anywhere?

                              Comment

                              Working...