Author Topic: [SOLVED] Uart0Receive() Read  (Read 404 times)

kristofferis

  • Sr. Member
  • ****
  • Posts: 287
  • Location: Sweden
    • View Profile
[SOLVED] Uart0Receive() Read
« on: June 18, 2016, 08:30:57 am »
Hello.
I am having some issues with the Uart Read function. As it is today .Read() Reads one character as byte so if i just send one byte then there is no issue. But let's say that something is sending
Code: [Select]
0x65 0x00 0x02 0x01 0xff 0xff 0xff
Then .Read() reads the first character and then i could loop until it gives me -1 so for the above example it will loop 7 times and if i run that in debug with breakpoints then everything is ok but as soon as i removes the breakpoint then the code misses several of the characters and it is different every time so it is some kind of timing issue.

But if it is possible I would like you to add a functions to read all the bytes that is in Uart0Receive read buffer at once maybe in a ListOfByte
« Last Edit: June 23, 2016, 11:03:58 pm by mc-Abe »

Share on Facebook Share on Twitter


mc-John

  • Global Moderator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Uart0Receive() Read
« Reply #1 on: June 18, 2016, 09:51:14 am »
That is strange. What is the baud rate you are using?

kristofferis

  • Sr. Member
  • ****
  • Posts: 287
  • Location: Sweden
    • View Profile
Re: Uart0Receive() Read
« Reply #2 on: June 18, 2016, 09:59:39 am »
I am using 9600.
I could run some more tests so that I have some more information about this.

I noticed this when I did my connection to touch screen, but I did a quick fix and changed the information sent from the screen to only one byte.
But that is not a solution  :)

kristofferis

  • Sr. Member
  • ****
  • Posts: 287
  • Location: Sweden
    • View Profile
Re: Uart0Receive() Read
« Reply #3 on: June 18, 2016, 12:42:32 pm »
I have made a simple test with my touchscreen and mcModule

The screen is sending 01 02 03
And there is a simple calculation 1+2+3-1 so the result should be 5 as you could see in the provided movie the result is 5 every time i debug the code and when i let it go by it self then this time the result was 4.

So what do you think about this?

https://youtu.be/gTFz461KB1Q

By the way this might be the most boring movie that you ever have seen but maybe it provides some good information to this case.  ;)

Code: [Select]
Class UartExample
    Shared serial As Uart
    Shared Event Boot()
        // Enable serial communication
        serial = Uart.Create(9600, Pin.Pin3, Pin.Pin1)
    End Event
   
   
    Shared Event Uart0Receive()
        Dim chr As Integer = serial.Read
        Dim test As Integer = chr
       
        While chr >= 0
           
            chr = serial.Read()
            test = test + chr
        End While
    End Event
End Class

mc-John

  • Global Moderator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Uart0Receive() Read
« Reply #4 on: June 18, 2016, 01:12:42 pm »
We had previous problems with 1000000 baud where it lost characters but we have a large application with 115200 and that works fine. Just watched your video and it looks like that you don't handle the -1 correctly. The event is not related to the fact that there is one character in the queue, it just indicates that there "could" be something in the queue. So you should always filter the -1 out. Placing the characters in a ListOfByte provides you with "readable information" See example below:
Code: [Select]
    Shared Event Uart0Receive()
        Dim chr As Integer = ser.Read
       
        While chr >= 0
           
            serBuf.Add(chr.ToByte)
           
            'check To see If end of message ("OK\r\n")
            If serBuf.Count> 20 Then
                If serBuf(serBuf.Count- 1) = 0x0a And serBuf(serBuf.Count- 2) = 0x0d And serBuf(serBuf.Count- 3) = 0x4b And serBuf(serBuf.Count- 4) = 0x4f Then
                    'If serBuf(serBuf.Count- 1) = 0x4f Then
                    Dim serString As String = serBuf.ToString()
                    serBuf.Clear()
                    ParseAndSendLapMessage(serString)
                    'increment message group
                    gMessageGroup = gMessageGroup + 1
                    If gMessageGroup > 3 Then
                        '2 bit number, if 3 then roll over to 0
                        gMessageGroup = 0
                    End If
                    'turn off ESP and Sigfox radio
                    rf_pwr_on = False
                    wifi_en = False
                    wifi_rst = False
                   
                End If
            End If
           
            chr = ser.Read()
        End While
       
    End Event
 


mc-John

  • Global Moderator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Uart0Receive() Read
« Reply #5 on: June 18, 2016, 01:17:24 pm »
What I forgot to tell you is that the word "could" means that the event could fire while there is nothing in the queue. Also you cannot rely on the 1+2+3-1 because there could be -1 in the middle. The chance that that happens when you debug is much smaller. Also the queue is 256 bytes before it overflows.

« Last Edit: June 18, 2016, 01:20:20 pm by mc-John »

kristofferis

  • Sr. Member
  • ****
  • Posts: 287
  • Location: Sweden
    • View Profile
Re: Uart0Receive() Read
« Reply #6 on: June 18, 2016, 02:33:16 pm »
Thanks for the reply, yes my code was a very simple and not very good code, that i am aware  :)

Even that the code is not handling the -1 the only thing i could think of in my code that gives the wrong number must be that the queue must have been empty before all information was sent from my touchdisplay.
So the mcModule is processing the queue faster that its filling.

And that of course is not a fault in mcModule.

Let me try to explain what i mean.

Touchscreen starts to send command 01 02 03
Uart0Receive() react on incoming data and add to queue
The code starts to process data in queue
the queue has been filled with 01 02 and now the code reads the queue again and now its empty and gives -1 and because the result is -1 then the loop ends and this time i did not receive the 03

Do you agree on this?

And it seems that you have tested this with success so I will have to try again with little more advanced code.

mc-John

  • Global Moderator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Uart0Receive() Read
« Reply #7 on: June 18, 2016, 03:03:18 pm »
Quote
Touchscreen starts to send command 01 02 03
Uart0Receive() react on incoming data and add to queue
The code starts to process data in queue
the queue has been filled with 01 02 and now the code reads the queue again and now its empty and gives -1 and because the result is -1 then the loop ends and this time i did not receive the 03

Do you agree on this?

Yes that is correct. The event will fire again though.

Quote
And it seems that you have tested this with success so I will have to try again with little more advanced code.
Yes but not on exactly the same software and hardware version so it still can be something else.


kristofferis

  • Sr. Member
  • ****
  • Posts: 287
  • Location: Sweden
    • View Profile
Re: Uart0Receive() Read
« Reply #8 on: June 18, 2016, 03:28:34 pm »
Thanks for clearing this out.
I will run some more tests and let you know how it goes.

kristofferis

  • Sr. Member
  • ****
  • Posts: 287
  • Location: Sweden
    • View Profile
Re: Uart0Receive() Read
« Reply #9 on: June 19, 2016, 03:26:45 am »
I have now remade my code and now everything seems to work. Thanks.

Here is my current code, the big difference is that it now handles if the serial.Read gives -1 when you are waiting for more information from the serial port.
And I also added a simple validation to make sure that we have a complete message before we try to do anything with it.

Code: [Select]
Class UartExample
    Shared serial As Uart
    Shared serialBuf As ListOfByte
    Shared Event Boot()
        // Enable serial communication
        serial = Uart.Create(9600, Pin.Pin3, Pin.Pin1)
        serialBuf = New ListOfByte
    End Event
   
    Shared Event Uart0Receive()
        Dim chr As Integer = serial.Read()
       
        While chr >= 0
           
            //message always starts with a(97) and ends with z(122)
           
            If chr = 97 Then
                //start of message
                serialBuf.Clear
                serialBuf.Add(chr.ToByte)
            ElseIf chr = 122 Then
                //end of message
                serialBuf.Add(chr.ToByte)
            Else
                //add message to Buf
                serialBuf.Add(chr.ToByte)
            End If
           
            chr = serial.Read()
        End While
       
        //check if we have a full message
        If serialBuf.Count = 4 Then
            //Right length verify start and stop possition
            If serialBuf(0) = 97 And serialBuf(3) = 122 Then
                //correct message, do something
                LedGreen = Not LedGreen
            End If
        Else           
        End If       
    End Event
End Class
« Last Edit: June 19, 2016, 12:29:19 pm by kristofferis »

mc-John

  • Global Moderator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Uart0Receive() Read
« Reply #10 on: June 19, 2016, 05:00:52 pm »
Glad you solved it ;D