|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionWhoever work with standard RS232 components from a .NET environment, and need real, embedded-like RS232 communication, realize in a short time that the component needs to be wrapped, or at least, additionally supported by custom software. I designed this tutorial because I couldn’t find something similar on the web. The code is an excerpt from a huge GPS tracking application, and it proved to work nicely. Just to mention, that there are other methods for RS232 communication such as using hand-shaking protocols, and hardware/software enabled pin control. BackgroundI won’t go in to the details of basic RS232 communication, except that it is a point-to-point communication between two hosts, and they could be computers or embedded devices. My point here will be the software implementation part, using C# in a .NET 2.0 environment to be precise, but the principles are adoptable to any other language and IDE. Also, the type of data I’m going to send/read is string, but with little more effort, the code can be adopted to send/receive any type of serializable data. One more restriction, the demo code is adopted to receive a huge block of data and then process it. Another way is to continually append read data to some FIFO buffer, and do an online parsing of whatever data has arrived at the time (search for delimiters inside the arrived data before the reading ends), for continual receiving of data without any pause between two packets. Methods usedWe will need as few as the following four methods to do the job:
Using the codeThe first thing we need for an RS232 communication is a 1. Blocking methodsWait for the hardware to do the job, and then return to the app, so the read operation waits until the reading is finished (a few methods give us different ways of reading the port).
2. Non-blocking methodsWe don’t wait in a loop for reading the port, we use interrupts, so when the port has something in an input buffer, the Here, we will use event driven communication, because in my belief, this is the only true RS232 robust communication. So, lets begin. Let’s create some private members for our form, like: private System.Timers.Timer timer1;
private StringBuilder recievedB = new StringBuilder();
private string recievedData;
Now, what we first need to do is a basic setup of the component we put on our form, meaning, set the component name (say, private void serialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(AddRecieve));
}
And next, we need to create and code the actual delegate to perform the reading: private void AddRecieve(object s, EventArgs e)
{
string st = serialPort1.ReadExisting();
recievedB.Append(st);
timer1.Interval = 1000;
timer1.Start();
}
Let’s comment this code a bit. First, we call Now, the second part of this method. How do we know that the other side of the communication link finished sending data, so we can process it? Think logically for yourselves… For those who figured it out, yes, we know this when for some time (predefined time) there is nothing to read, meaning the event public Form1()
{
InitializeComponent();
serialPort1.Open();
timer1 = new System.Timers.Timer(1000);
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);
GC.KeepAlive(timer1);
}
The method that will execute on the timer overflow is called void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Stop();
this.Invoke(new EventHandler(ReadData));
}
First, we stop the timer, and second, we do the final receiving of the data. And again, just in case, we call private void ReadData(object s, EventArgs e)
{
recievedData = recievedB.ToString();
int j = recievedB.Length;
if (recievedData.Contains("RMR0" /*some delimiting end*/))
{
labelCard.Text = "Read " + j.ToString() + " bytes...";
// finally we have the data, we need to process it
ProcessData();
}
else
{
DialogResult dr = MessageBox.Show("Bad card data detected!," +
" Read good data?", "Error!",
MessageBoxButtons.YesNo,
MessageBoxIcon.Error);
if (dr == DialogResult.Yes)
{
}
}
}
Of course, the method Points of InterestFinally, I feel I need to explain the whole process again. The communication points are A and B. Both sides open their ports, and side B starts sending bytes over the comm. link. A And again, of course, there are other port signals in RS232 such as CTS, RTS, which are also known as signals for implementing hand-shaking protocols, but we intend not to use them, because not every embedded system has a hand-shaking RS232 port enabled.
|
||||||||||||||||||||||