Strange serial port output problem

Click For Summary

Discussion Overview

The discussion revolves around issues related to serial communication with an embedded system using RS485 and stick parity. Participants explore the reliability of data transmission, timing discrepancies, and potential causes for intermittent communication failures.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Exploratory

Main Points Raised

  • One participant describes a problem with intermittent communication failures, noting that the time between bytes can vary significantly, sometimes reaching 12-15ms.
  • Another participant suggests that the operating system's non-real-time nature may contribute to timing issues, especially when using a USB to RS232 converter.
  • There is a discussion about the implications of using different operating systems (Windows Vista and Windows XP) and their respective timer resolutions on communication reliability.
  • One participant proposes that a dedicated microcontroller could serve as a more reliable interface between the PC and the RS485 network, potentially mitigating OS-related timing issues.
  • Concerns are raised about the effect of the PC's driver mechanisms and UART chip on maintaining baud rate tolerances during communication.
  • Another participant mentions multimedia functions in Windows that could potentially improve timer resolution, but expresses uncertainty about their effectiveness in this context.

Areas of Agreement / Disagreement

Participants express varying opinions on the root cause of the communication issues, with some attributing it to the operating system and others suggesting hardware-related factors. The discussion remains unresolved, with multiple competing views on how to address the problem.

Contextual Notes

There are limitations regarding the assumptions about the operating system's timer resolution and the effects of using a USB to RS232 converter. The discussion also highlights the complexity of interfacing non-real-time systems with real-time communication protocols.

ionlylooklazy
Messages
30
Reaction score
0
Hello,

I've been writing a program to communicate with an embedded system via rs485

The protocol in use utilizes stick parity, where stick parity is defined as the first byte (which corresponds to the address of the device) having its parity bit set to 1, and the rest of a packet have its parity bit set to 0.So, when developing my program, I was having some issues with reliability. I attached an oscilloscope to determine the problem. From this I determined that the address byte was preceding the rest of the packet by about 6-8ms. I assume this is due to the parity shift taking place (going from mark parity on the address byte, to space parity for the rest of the packet). So after some trial and error I found that introducing a 2ms delay in between each byte worked extremely well.

However, I now have an intermittent problem popping up that I can't explain.
Every once and a while , the communications will totally fail, the CPU won't even respond (nack, ack, cancel, busy), so I once again, attach a scope. This time, I see that the time between all bytes sent is around 12-15ms. This problem occurs intermittently, I'll be changing some aspect of my code totally unrelated to communications and when I start it back up, this problem occurs. Sometimes it occurs when I leave my program idle or when I restart my program. There also is nothing I can do to get it back into a working state, I just have to wait until the packets become normally timed, as if by some whim of my computer.

I attached a crude MS paint drawing to illustrate what I am seeing on the scope.

Each spike represents one byte. I'm using a packet with 11 bytes as my guinea pig.
I'm transmitting at 19200 baud. 1 stop bit, stick parity.

The top image shows what the packet looks like when communication is working.
The bottom shows what it looks like when the problem is occurring.

I have tried this on two different computers, and I have the same issue on both. I have ruled out all other hardware except for the computers themselves. (I have scope attached directly to serial port). This problem will occur without any change to code, and then also suddenly start working without any change to code.

Any help would be much appreciated

Thanks,
ioll
 

Attachments

  • waveform_diagram.jpg
    waveform_diagram.jpg
    5.8 KB · Views: 506
Last edited:
Technology news on Phys.org
Here's the packet I'm sending

Code:
 Dim TX(12) As Byte


        TX(0) = CURRENT_CPU                         ' ADDRESS OF THE CPU
        TX(1) = 9                       ' NUMBER OF BYTES TO FOLLOW
        TX(2) = PURGE_BARS
        TX(3) = PURGE_CONTROL_BYTE                  ' DETERMINES WHICH BARS TO PURGE
        TX(4) = PURGE_TIME_BAR1
        TX(5) = PURGE_TIME_BAR2
        TX(6) = PURGE_TIME_BAR3
        TX(7) = PURGE_TIME_BAR4
        TX(8) = PURGE_TIME_BAR5
        TX(9) = PURGE_TIME_BAR6
        TX(10) = CByte(get_checksum(TX, 10))               'TWO'S COMPLEMENT OF THE SUM OF THE PACKET


        For i As Integer = 0 To 10

       

            If i = 0 Then
  

                sp.Parity = IO.Ports.Parity.Mark

            Else

                System.Threading.Thread.Sleep(2) ' 2mS pause
             
                If Not sp.Parity = IO.Ports.Parity.Space Then
                    sp.Parity = IO.Ports.Parity.Space
                End If
  

            End If
        

            sp.Write(TX, i, 1)

       
            While (sp.BytesToWrite <> 0)
            End While


        Next i
 
Just to clarify, you are sending this somehow from a Windows PC, and the receiving node is an embedded uC?

If so, what operating system are you running on the PC? Most PC OS's are not real-time. What port are you coming out of the PC on? Are you coming out of the RS-232 port and converting that to RS-485 somehow? If so, how? Is your RS-485 network doubly-terminated like it's supposed to be?
 
yeah, mainly I am using my latptop with has windows vista, I am using a usb -> rs232 converter (com4) to convert to to rs232, then to rs485 when I get to the device,

ive also used a desktop with windows XP sp2, using an actual rs232 port (com1)

but the issue occurs even when I am disconnected from the rs485 network



its perhaps a problem with the operating system?
 
ionlylooklazy said:
yeah, mainly I am using my latptop with has windows vista, I am using a usb -> rs232 converter (com4) to convert to to rs232, then to rs485 when I get to the device,

ive also used a desktop with windows XP sp2, using an actual rs232 port (com1)

but the issue occurs even when I am disconnected from the rs485 network

its perhaps a problem with the operating system?

That's a fairly convoluted path for getting out to a real-time network (no offense meant, I'm just saying that it is). In general, for a real-time network (especially if it has an error-detection and retry protocol layered on it), you will need real-time devices at all connection points. The RS-232 serial port out of your PC has its own driver mechanism and UART chip to ensure that the baud rate stays within tolerances. But when you write a program on a PC to send things out ports byte-at-a-time or whatever, then the OS jitter will affect what actually goes out.

The best way for you to do a PC-based interface to the real-time network, would be to make a network interface device that has a microcontroller (uC) in it. You would send the uC the data via the RS-232 serial port or USB port, and the uC would serve as the gateway to get the data out onto the network, and report the replies back up to the PC. Dedicated hardware is the common way to interface PCs (and their non-real-time operating systems) to real-time data communication networks.
 
the time between all bytes sent is around 12-15ms.
Windows XP uses a 64hz ticker, this corresponds to an interval of 15.625ms. A sleep(2) is only guaranteed to provide a 2ms minimum delay, to the next 15.625ms boundary. The multimedia functions, timeBeginPeriod() and timeEndPeriod() are supposed to allow a program to change the "minimum timer resolution" as low as 1ms, but I'm not sure if this is the same timer as the one used for sleep().

An alternative is to bump up thread priority and loop on QueryPerformanceFrequency() (instead of using sleep), which I assume is based on the high frequency timer in a Pentium cpu. Grab an initial value from QueryPerformanceFrequency(), then base all future events by looping on QueryPerformanceFrequency() until it reaches an appropriate difference from the initial captured value. To prevent wrap-around issues, subtract of the original time from the current time, and then compare to a desired delay.
 

Similar threads

  • · Replies 6 ·
Replies
6
Views
3K
Replies
1
Views
1K
  • · Replies 5 ·
Replies
5
Views
8K
Replies
2
Views
4K
Replies
4
Views
5K
  • · Replies 11 ·
Replies
11
Views
4K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 9 ·
Replies
9
Views
4K
  • · Replies 7 ·
Replies
7
Views
4K
  • · Replies 25 ·
Replies
25
Views
4K