Strange serial port output problem

Click For Summary
SUMMARY

The forum discussion addresses a serial communication issue with an embedded system using RS-485 and stick parity. The user experiences intermittent communication failures, with byte transmission delays fluctuating between 2ms and 15ms, which are attributed to the non-real-time nature of Windows operating systems. Recommendations include using a dedicated microcontroller as a gateway for real-time communication and adjusting thread priorities to mitigate timing issues. The discussion highlights the importance of real-time devices in maintaining consistent communication in such protocols.

PREREQUISITES
  • Understanding of RS-485 communication protocols
  • Familiarity with stick parity and its implementation
  • Knowledge of Windows operating system limitations regarding real-time processing
  • Experience with serial communication programming in environments like VB.NET
NEXT STEPS
  • Research the implementation of a microcontroller as a real-time gateway for RS-485 communication
  • Learn about multimedia timer functions in Windows, specifically timeBeginPeriod() and timeEndPeriod()
  • Explore techniques for adjusting thread priorities in .NET applications to improve timing accuracy
  • Investigate the use of QueryPerformanceFrequency() for precise timing control in serial communication
USEFUL FOR

Embedded systems developers, software engineers working with serial communication, and anyone troubleshooting RS-485 communication issues in non-real-time operating systems.

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: 495
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