-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

When transmitting via UDP to a PLC, I run into a strange problem
where socket.sendto returns double the number of characters sent in the
datagram.  I thought this was an error and used Wireshark to sniff the
connection and discovered that it did, in fact, include two copies of
the string I am transmitting in the same packet.  The only
thing differentiating this string from prior commands is its length.
The functional ones are between 5 & 7 bytes (with 16 byte responses
received successfully) but transmitting a 66-byte message actually
results in 132 bytes being sent!  

I am running 2.6.6 on Windows XP, which I understand has a default
minimum buffersize of 576 bytes which I would think is sufficient.

Apologies if this is somewhat incoherent, I'm cross-eyed from staring
at this!

- - Todd

- -- code --
def PLC_Functions(command, argument):
    """ 
        Command is one of:  GetTray, Status, SetText
        Argument is one of: tray number (as string), None, message (as string)
        
    The PC transmits and receives on socket 2260 (pcSocket)
    The PLC transmits and receives on socket 2002
    The protocol used is UDP
    """
    MegaMatPLC = 
(config.get('megamat','plcip'),int(config.get('megamat','targetport')))
    # at some point it will be necessary to wrap these in TRY/EXCEPT to handle 
the socket errors
    # create UDP socket 
    pcSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 
socket.IPPROTO_UDP)
    # bind it
    
pcSocket.bind((config.get('megamat','pcip'),int(config.get('megamat','sourceport'))))
    # make them blocking (i/o is 'fire-and-forget' to a PLC that may or may not 
respond in a given time.)
    # non-blocking fails and raises windows exceptions for some reason 
(20-Oct-2010)
    pcSocket.setblocking(True)
    
    if command == 'CallTray':
        # frame 1 (see docs for frame sequence)
        print 'Received call tray command for tray %s' %(argument)
        getReadyMsg = '0145\r'
        totalsent = 0
        while totalsent < len(getReadyMsg):
            sent = pcSocket.sendto(getReadyMsg[totalsent:],MegaMatPLC)
            if sent == 0:
                raise RunTimeError('Transmission failure.  Please confirm 
MegaMat settings in megapy.ini')
            totalsent = totalsent + sent
        # Frame 2
        response = ''
        while response.find('\r') < 0:
            response = pcSocket.recv(17)
            if response == '':
                raise RunTimeError('PLC did not respond') 
            #this should be changed.  The MIF software will wait until it 
receives a response or timeout, not ABEND
        print response
            
        if response[0:4] == '0135':
            print 'Drive ready received.'
            #Frame 3
            getReadyMsg2 = '016040\r'
            totalsent = 0
            while totalsent < len(getReadyMsg2):
                sent = pcSocket.sendto(getReadyMsg2[totalsent:],MegaMatPLC)
                if sent == 0:
                    raise RunTimeError('Transmission failure.  Please confirm 
MegaMat settings in megapy.ini')
                totalsent = totalsent + sent
            # Frame 4
            response = ''
            while response.find('\r') < 0:
                response = pcSocket.recv(16)
                if response == '':
                    raise RunTimeError('PLC did not respond') 
                    #this should be changed.  The MIF software will wait until 
it receives a response or timeout, not ABEND
            print response
            
            if response[0:4] == '0130':        
                # Frame 5
                # Transmit tray request 
                if int(argument) < 10:
                    shelfPrefix = '0000'
                else:
                    shelfPrefix = '000'
                    
                shelf = shelfPrefix + argument
                unit = '001'
                stack = '01'
                """
                There is a 10 digit number plus 40 blanks spaces after the 
shelf description built above.
                It is possible this is for storing shelf descriptions and 
barcodes on the PLC.  We will
                follow the example of the MIF software and put a phony b/c and 
blank description.
                X is a field terminator and \r is the end of transmission 
(EoT.) 
                """
                fakeBarcode = '1234567890'
                fortySpacesField = ' '*40 + 'X\r'
                getShelfMsg = '0105' + shelf + unit + stack + fakeBarcode + 
fortySpacesField
                print 'Transmitting shelf request as follows: \n' + getShelfMsg
                print 'Get shelf length %i' % (len(getShelfMsg))
                totalsent = 0
                while totalsent < len(getShelfMsg):
                    sent = pcSocket.sendto(getShelfMsg[totalsent:],MegaMatPLC)
                    print sent, totalsent, len(getShelfMsg)
                    if sent == 0:
                        raise RunTimeError('Transmission failure.  Please 
confirm MegaMat settings in megapy.ini')
                    totalsent = totalsent + sent
                '''
                 listen for success code here; not really necessary as the PLC 
either does it or doesn't (due to the safety
                 interlocks the PC doesn't control squat.  Given that the 
control PC is currently sitting next to it a more
                 practical form of feedback is whether or not the damn shelf 
shows up in the doorway.  There is a door-open command
                 available but it isn't really useful for our purposes.
                '''
                
                #Frame 6
                response = ''
                while response.find('\r') == -1:
                    response = pcSocket.recv(16)
                    if response == '':
                        raise RunTimeError('PLC did not respond') 
                        #this should be changed.  The MIF software will wait 
until it receives a response or timeout, not ABEND
                print response
                if response[0:4] == '0130':    
                # Frame 7
                    LCDLine3 = '01613' + '    ThetaMegaMat    ' + '\r'
                    totalsent = 0
                    while totalsent < len(LCDLine3):
                        sent = pcSocket.sendto(LCDLine3[totalsent:],MegaMatPLC)
                        if sent == 0:
                            raise RunTimeError('Transmission failure.  Please 
confirm MegaMat settings in megapy.ini')
                        totalsent = totalsent + sent    
                    # Frame 8
                    response = ''
                    while response.find('\r') == -1:
                        response = pcSocket.recv(16)
                        if response == '':
                            raise RunTimeError('PLC did not respond') 
                            #this should be changed.  The MIF software will 
wait until it receives a response or timeout, not ABEND
                    print response
                    if response[0:4] == '0130':
                        # Frame 9 - Final transmission
                        LCDLine4 = "Shelf " + shelf
                        totalsent = 0
                        while totalsent < len(LCDLine4):
                            sent = 
pcSocket.sendto(LCDLine4[totalsent:],MegaMatPLC)
                            if sent == 0:
                                raise RunTimeError('Transmission failure.  
Please confirm MegaMat settings in megapy.ini')
                            totalsent = totalsent + sent
                        # Frame 10 - Final response, final frame
                        response = ''
                        while response.find('\r') == -1:
                            response = pcSocket.recv(16)
                            if response == '':
                                raise RunTimeError('PLC did not respond') 
                                #this should be changed.  The MIF software will 
wait until it receives a response or timeout, not ABEND
                        print response
                        
            pcSocket.close()
        
    if command == 'Status':
        print 'Received command for PLC status'
        
    if command == 'SetText':
        print 'Received command to set display text as: \n\n %s' %(argument)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.16 (GNU/Linux)

iEYEARECAAYFAky/TxoACgkQwnknPuQqPIOVkQCfUfYMnOfFVYH+H7X3CnI19UvT
vFUAnjuUHO+oikUQrwvYfLsRkszynY1s
=jthz
-----END PGP SIGNATURE-----
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to