UART-Rx() function

Hello, I have a problem with the UART-Rx() function.

I am currently receiving a string, which i am sending myself.
image
This is what I am sending myself.
image
And this is my UARTRx() function.
My problem is, that the UART receives the string not in one piece, it is allways received in two pieces.
It looks like the interrupt is always called up twice.
image
Can somebody help me to solve this problem?

Kind regards

this beavior is quite normal for streaming API’s such as any serial port. you need to re-assamble your “data package” from the streaming bytes coming in from the line.

to solve this you need the following measures:

  1. expand your data with some package delimiter character(s). at minimum you need some “end of package” char (for example \n or ETX). *) **)
  2. treat the RX function to receive chunks of serial data - e.g. parse them character by character to an intermediate package buffer. handover to a package processor when “end of package” character is detected.

*) you may replace the “end of package” with some special inter-frame timing. but this is more complicate to implement, and typically slows down communication due to long idle timeslots between frames.
**) a good design will also introduce a “begin of package” character (for example STX) and some checksum. just adressing may not be a thing on a RS232 point2point connection.

for your convenience i published a library adressing your needs.

add the library “serial-frame-rcvrs” to your project.
image

use some code like that:

/* =======================================================================
    SERIAL-FRAME-RECEIVER DEMO
==========================================================================
    +++ requires pin uart0.txd connected to uart0.rxd +++
======================================================================= */
new fcb[Tsframe];
new fbuf{20};

#callback onUartRx( chunk{}, len) {
    #log( "~chunk rxd [%d] '%s", len, chunk);
    // serialize the chunk and send it to frame receiver
    for( new j=0; j<len; j++) {
        new r= sframeRx( fcb, chunk{j}, fbuf);
        if (r<0) #log("?error %d, overflow %d times", r, fcb.overflows);
        if (r>0) #log( "frame received, %d chars '%s'", r, fbuf);
    }
}

#callback appLoop() {
    new frame{}= "^123,45,67$"; // ^=SOF, $=EOF
    rM2M_UartWrite( 0, frame, strlen( frame));
}

#callback appInit() {
    sframeInit( fcb, '$', '^');
    catch( rM2M_UartInit( 0, 19200, RM2M_UART_1_STOPBIT|RM2M_UART_PARITY_NONE|RM2M_UART_8_DATABIT, onUartRx));
    setInterval( appLoop, 2000);
}

main(){
    // enable extended debug interface, increase console buffer, say hello
    salve( appInit);
}

When adding your own function to process the received frame, consider to use packed “{}” strings (and not unpacked “[]” ones).

Extend the previous sample code like that:

myFrameReceivedFunction( fbuf{}, flen) {
    #log( "frame received, %d chars %s'", flen, fbuf);
    for( new j=0; j<flen; j++) {
        // address your frame's characters using ** fbuf{j} **
        #log( "~    char #%d = 0x%02x'", j, fbuf{j});
    }
}

#callback onUartRx( chunk{}, len) {
    for( new j=0; j<len; j++) {
        new r= sframeRx( fcb, chunk{j}, fbuf);
        if (r<0) #log("?error %d, overflow %d times", r, fcb.overflows);

        // call your own function when the frame has been completely received
        if (r>0) myFrameReceivedFunction( fbuf, r);
    }
}

[/quote]