Strange serial port output problem

AI Thread Summary
The discussion revolves around issues encountered while developing a program to communicate with an embedded system via RS485 using a stick parity protocol. The user initially faced reliability problems, which were partially resolved by introducing a 2ms delay between bytes. However, an intermittent issue emerged where communication would fail, with byte transmission times increasing to 12-15ms, seemingly without any changes to the code or system state. The user has tested the setup on different computers and ruled out hardware issues, leading to speculation about operating system limitations. The conversation highlights the challenges of using non-real-time operating systems for real-time communication, particularly the impact of OS jitter on serial communication. Suggestions include using a dedicated microcontroller as a gateway to manage data transmission more effectively and adjusting the system's timer resolution or thread priority to improve timing accuracy. The complexities of the communication path, including the use of USB to RS232 converters, were also discussed, emphasizing the need for real-time capabilities at all connection points.
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: 479
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.
 
Dear Peeps I have posted a few questions about programing on this sectio of the PF forum. I want to ask you veterans how you folks learn program in assembly and about computer architecture for the x86 family. In addition to finish learning C, I am also reading the book From bits to Gates to C and Beyond. In the book, it uses the mini LC3 assembly language. I also have books on assembly programming and computer architecture. The few famous ones i have are Computer Organization and...
I have a quick questions. I am going through a book on C programming on my own. Afterwards, I plan to go through something call data structures and algorithms on my own also in C. I also need to learn C++, Matlab and for personal interest Haskell. For the two topic of data structures and algorithms, I understand there are standard ones across all programming languages. After learning it through C, what would be the biggest issue when trying to implement the same data...
Back
Top