Developer Portal Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    Serial Channel only reads 22 bytes, even though the device sends more

    Serial Channel only reads 22 bytes, even though the device sends more

    MarvinW
    Long-established Member

    Hello,

    I have the following problem with a unit that I programmed for a device connected with RS485.

    I am using an EL6022 and the matching Peripheral version 2.0.5.0. I am only using the first channel and it is configured as RS485 in the OES parameters.

    I open the channel like this:

    _parCfg.iSerialStream.Open(OpconSerialBaudRate.BAUD_9600, OpconSerialDataFrame.FRAME_8E1, OpconSerialHandShakeType.NO_HANDSHAKE);

    I successfully send 14 bytes to the device and the device responds according to its protocol documentation. In order to receive the response, I use:

    _parCfg.iSerialStream.Read(ADR(_receiveBuffer), 23, _bytesRead, _timeout);

    When the Read() method returns OK, the value in _bytesRead is only 22 though, this is my problem. I checked the Input variables of the serial terminal and I can see that the 23rd byte that the device sent me actually sits in the Data In 0 with Input length set to 1. So the device seems to work correctly, the Beckhoff terminal seems to work correctly, but the EL6022 peripheral seems unable to read more than 22 bytes, which is probably because that's how much data the serial terminal catches with its input variables in a single go.

    I tried different handshake mechanisms in the Open() parameter but they seem to have no effect (... are they even used with RS485 in general?). I also made sure that the device's parameters are matching the baud rate and parity settings. But could not get the 23 byte response to work correctly with the Nexeed objects.

    The device supports another protocol that only has a 19 byte response. If I use this one then the message fits into the buffer and the entire communication works. So it does not seem to be a problem of the device and probably not in my application either.

    Are there any known solutions to this problem? I am curious what the root cause is and how to eliminate it, because I really want to use the 23 byte version of the protocol.

    6 REPLIES 6

    Düscha
    Long-established Member

    you must call the method Read() until all data has been read

     

    example:

    _ret := _parCfg.iSerialStream.Read( ADR(_readArray) + _curReadLen, SIZEOF(_readArray) - _curReadLen, _readBytes, _readTimeout );
    
    IF ( _ret <> RUNNING )
    THEN
      IF( _ret = OK )
      THEN
        _curReadLen := _curReadLen + _readBytes;
    
        IF( _readTimeout )
        THEN
          // set detailed error number
        ELSE
          IF ( check end sign )
          THEN
            //end read data
          END_IF
        END_IF
      ELSE
        // get error from socket
        _lastError := _parCfg.iSerialStream.LastError;
      END_IF
    END_IF

    MarvinW
    Long-established Member

    So, I understand that you're saying this behavior is intentional.

    If that is the case then I suggest to update the documentation of the Read() method to make this more clear. There are two points that made me believe that it will read the data contineously:

    MarvinW_0-1639012204017.png

    First of all it says that is reading data from the stream. I understand that a stream is basically a representation of a potentially limitless data source, and since I provide it with a buffer, I can read as much as I want in a single call. If it had said "Read a portion of data from the stream, according to the limit of the packet size (stream implementation specific)" or something like that, I would have been more cautious.

    The second point is the documentation of the DataLen parameters. It is suggesting that it specifies how much data I will read, but in reality it is _only_ the size of the buffer from pData. Or does it serve any other function as well? It certainly is not the exact number of bytes that will be read, which lead to my example.

    Anyway, thanks for clearing it up. I will change my object and give it a try. I am sure it will work since I saw the missing byte already in the IO image. I just didn't feel like this was the right solution haha.

    MarvinW
    Long-established Member

    Does the same logic actually apply to to Write() as well? If yes, how do I know whether a write timeout occured?

    Düscha
    Long-established Member

    For Write() you no need this.

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist