LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Check if line is free. RS232.

Hi!

I have two devices that communicates each over a energetic line (230V). Communication is on TDA5051(you can imagine two coms connected each over with shorted TX to RX). Bouilded devices works perfect- tested throw HyperTerminal and Docklight.

 

The problem is that I want to make multi-master communication. Exactly I want to write a condition that won't allow to send any bytes until line will be free. I made something like this:

while (n=GetInQLen (COM_PORT))       //check buffer in
{
                FlushInQ (COM_PORT);      //if so, clear buffer
                Delay(0.02);                     //wait 0.02s. Frame have 5 bytes. 1200baud, 1 stop bit
}
//--------------------------------------------------- //Transmit frame //--------------------------------------------------- FlushOutQ (COM_PORT); ComWrt (1, byte, 5);

 I have tested it that:

I run Delight on one device. I was sending byte periodically.

I run program on second device- nevertheless it exit the loop, when line isn't free.

 

The time for Delay I calculate that way:

1200baud<->0.8(3)ms (TDA5051 works only on 1200 baud)

8 bit, one bit stop=10 bit for one byte. 0.8(3)ms*10=8.(3)ms for one byte. I round it to 10ms.

On my mind in 20ms time it should be 2 bytes in buffer in(variable n).

Well the n variable is not constant and it almost always return 0.

 

It works fine when I change Delay from 0.02 to 0.1s but it is waste of band for me. One frame is 8.(3)*5=41 ms. It's not fine for me because I want to have 10 masters in net and each master can have 30 slaves. I won't able to do it with such as transmit Delays.

 

I was thinking that Delight was not perfect and I wrote second program for first device to transmit into line:

while(1)
{
        ComWrt(COM_PORT,buffer,5);
}

 Such code wasn't perfect. I had 100% processor usage and it seems to me that was transmiting frames in different delay times. When I turned off output buffer(ComOpenConfig with -1 parameter) it seems to worked better(processor usage wasn't 100% anymore).

 

Why I can't get number of bytes in Input Quene on real time? I need to delay transmission until line is free and don't waste band. It seems that buffers are not write in real-time. Why transmit functions use 100% usage when I use write buffers(I've 2GHz CPU and transmission is very slow)?

My devices works fine, I chcecked programs on directly connected cables too.

0 Kudos
Message 1 of 9
(4,225 Views)

You might try a scheme using a Com callback rather than a loop on a InQ probe like you have now.

 

You can configure a Com callback function that will be invoked on any of several condtions.  For example, you can have the callback invoked whenever a character arrives in the InQ, or whenever the InQ gets to a certain threshold (i.e. number of chars in the InQ), or whenever a particular char arrives in the InQ.

 

InstallComCallback()  is the function you use.  It will count incoming characters for you so you don't have to do the delay calculation and InQ flush the way you have it now, simplifying things and giving you more flexibility.

 

 

 

 

0 Kudos
Message 2 of 9
(4,221 Views)

Yes.

I tried that function. But how it will help me to detect that the line is free before I transmit frame? If the line is free it should be transmit frame imediatelly, if not wait for freing line.

0 Kudos
Message 3 of 9
(4,219 Views)

I don't think you'll be able to do this on rs-232.

 

Even if you solve the issue of detecting a free line and transmitting without spinlocking, you are essentially trying to implement a multiple access scheme without collision detection.  Even if you think the line is free, another device can send at the same time (it will think the line is free too) or even after you send, since there will be propogation delays depending upon how far away from you another sender is.

 

Ethernet solves this problem through collision detection and delayed re-transmit, with the hardware helping out at a low level by listening for a collision, and with the collision timing bounded by limiting the cable length in a collision domain.

 

 

0 Kudos
Message 4 of 9
(4,217 Views)

Here is info on Carrier Sense, Multiple Access, Collision detection scheme.

 

http://en.wikipedia.org/wiki/Carrier_sense_multiple_access_with_collision_detection

 

From the perspective of a talker, when you check for an empty InQ, that's the "carrier sense" part.  But you have no way of knowing if you are transmitting on top of another talker that started at the same time as you.

 

My apologies if you know all of this, I'm not trying to be obnoxious.  Maybe I misunderstand your scheme.

0 Kudos
Message 5 of 9
(4,216 Views)

In that case I have CRC implemented. Checking if line is free is only extra condition for better work of my transmission system.

0 Kudos
Message 6 of 9
(4,214 Views)

Then you must have to wait for an ACK message of some kind to know that your sent message was received by the listener?

 

You could implement an arbitration scheme (like VME bus) and have one device designated as the arbiter - any device wanting to talk would make a request for the channel to the arbiter, which would grant access to one device at a time.  That way, the contention would be limited to the channel requests, rather than having every device contend for the channel for every character it wants to send.

 

Or you could try a multi-threading scheme - the rs232 library is "thread safe".  You could have the code that's looking for a free line running on a separate thread, that way you could get some parallelism going - most PC's are multi-core nowadays, so you could get true concurrency.  Go ahead and run your InQ check every 100 msec but do it with a separate thread that does only that line check task.   Have it set a thread safe variable (like WinAPI semaphore, mutex, signal, interlocked variable, critical region, etc - there are many mechanisms) and have the code that wants to issue the message simply check the variable to see if it's indicating the line is free - if not, it can go off and do other things and check again later.  That way you get the near-realtime line status you want, but without hanging up your main logic in a busy wait.

 

The com port is a process resource, so multiple threads within a process can all access it.  NI rs-232 library guarantees that individual library function calls run to completion and won't get interrupted by another thread.

 

You can set thread priority so that the line check thread gets preferrence.

 

You could maybe postpone the InQ clear - let the talker send the message and clear the InQ afterwards, unless you want to listen to yourself.  Actually, the ALOHA protocol does exactly this - it listens while sending, and if it receives the message it sent, to some reasonable extent it knows it got through and didn't collide.   If it doesn't receive what it just sent, it knows there was a collision, then it waits some random length of time (to avoid synchronizing collisions inadvertently) and resends.

 

http://en.wikipedia.org/wiki/ALOHAnet#The_ALOHA_protocol

 

Menchar

 

 

 

 

0 Kudos
Message 7 of 9
(4,207 Views)

My code works if I set Delay to 100ms without any multithreading. The problem is that's too lot for me. I will waste a lot of time. I will imlement ALOHA, but It's the same waste of time- it's good for high baud rate.

0 Kudos
Message 8 of 9
(4,202 Views)

I guess I don't understand what you're trying to do well enough.

 

Good luck.

0 Kudos
Message 9 of 9
(4,199 Views)