473,322 Members | 1,911 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Polling a device connected to the serial port

I need to poll my machine via serial port.
my code sorta works, I do not use streams or threads.
I have not figured them out yet.
IS there a way to only allow one particular method to run at a time. I think my timer_tick is starting the method a second or more times.

One is there a way to only a method called by a timer_tick to be entered once until that method completes
When the poll is sent with nark parity but the response must be recieved using space parity


Why am I getting multiple lines in the text box from this, should only occur once

I have a program that i am trying to emulate.
in tha program the event only shows up once per occurrance. not many times like my code creates.
I have used a serial port monitor program, for some reason the device is resending the same code again and again even though my app is responding same as the emulated program does.
I am beginning to think that the buffer is not clearing or the parity switching is causing. but when I send commands to the device they work (I have to send the device address (mark) the command with a CRC for all bytes is sent with space parity.

Text box output


$11 door was opened.
$11 door was opened.
$11 door was opened.
$11 door was opened.
$11 door was opened.
$11 door was opened.
$11 door was opened.
$11 door was opened.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.
$12 door was closed.

Expand|Select|Wrap|Line Numbers
  1.  void timer_Tick(object sender, EventArgs e)
  2.         {
  3.             Byte[] GenPoll = { 0x80, 0x81 };
  4.             myserialPort.Parity = Parity.Mark;
  5.             for (int i = 1; i < 50; i++) { } // short delay to allow parity to change
  6.             myserialPort.Write(GenPoll, 0, 2);
  7.             myserialPort.Parity = Parity.Space;
  8.             for (int i = 1; i < 50; i++) { } //short delay to allow parity change
  9.             int bytes;
  10.             string bufferstr; 
  11.             bytes = myserialPort.BytesToRead;
  12.             Byte[] buffer = new byte[bytes];
  13.             myserialPort.Read(buffer, 0, bytes);
  14.             bufferstr = myserialPort.ReadExisting();
  15.             myserialPort.Parity = Parity.Mark;
  16.  
  17.             if (bytes > 0)
  18.             {
  19.  
  20.                     if (buffer[0] == 0)
  21.                     { }
  22.                     if (buffer[0] == 0x01)
  23.                     {
  24.                         textBox1.Text += "$01  Ack\r\n";
  25.                         buffer[0] = 0x00;
  26.                         myserialPort.Parity = Parity.Mark;
  27.                         for (int i = 1; i < 50; i++) { }
  28.                         myserialPort.Write(GenPoll, 0, 2);
  29.                         myserialPort.Parity = Parity.Space;
  30.                         for (int i = 1; i < 50; i++) { }
  31.                     }
  32.                     if (buffer[0] == 0x11)
  33.                     {
  34.                         textBox1.Text += "$11  door was opened.\r\n";
  35.                         buffer[0] = 0x00;
  36.                         myserialPort.Parity = Parity.Mark;
  37.                         for (int i = 1; i < 50; i++) { }
  38.                         myserialPort.Write(GenPoll, 0, 2);
  39.                         myserialPort.Parity = Parity.Space;
  40.                         for (int i = 1; i < 50; i++) { }                       
  41.                     }
  42.                     if (buffer[0] == 0x12)
  43.                     {
  44.                         textBox1.Text += "$12  door was closed.\r\n";
  45.                         buffer[0] = 0x00;
  46.                         myserialPort.Parity = Parity.Mark;
  47.                         for (int i = 1; i < 50; i++) { }
  48.                         myserialPort.Write(GenPoll, 0, 2);
  49.                         myserialPort.Parity = Parity.Space;
  50.                         for (int i = 1; i < 50; i++) { }
  51.                     }
  52.  
Nov 30 '11 #1
4 9176
arie
64
There are three different timer classec in c#, if you use them in a wrong way it can really hurt. This articles explain the differences:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
http://intellitechture.com/System-Wi...-Timers-Timer/

Since your timer has an event called "Tick", I guess its System.Windows.Forms.Timer, which is supposed to be used only for interactions with Forms.

Is using a timet the best choice? Have you thought about using DataReceived event of the SerialPort object?
http://msdn.microsoft.com/en-us/libr...areceived.aspx

Althought its description is not very reasuring (for example "Because the operating system determines whether to raise this event or not, not all parity errors may be reported." and so on...) but once you get it to work, it works.

To detect parity errors, you may also want to subscribe to ErrorReceived event
http://msdn.microsoft.com/en-us/libr...rreceived.aspx

Also, I had never tried to change the port's parity when it was open, so I don't know if it causes problems

About your timer running before the previous finnishes processing.
I suppose you can use locks to ensure your timer's method runs "one at a time". And are you sure you subscribe to your timer's Tick event only once?

Sorry about all this, a bit incoherent, rambling :) Actually I just finnished a project similar to yours, I had to ask serial port for data periodically, receive the responses and process it. I used Elapsed event of System.Timers.Timer object to ask for data (write to the port), DataReceived event of SerialPort to receive answers (read from port, this part was a bit tricky, e.g. I used Thread.Sleep() method to wait for all data to come, which - theoreticaly - I shouldn't do; but it works) and then I did all time consuming data processing (like printing, comunication with databases) using BacgroundWorkers.

About how DataReceived event works: http://social.msdn.microsoft.com/For...-adff82b19e5e/
Nov 30 '11 #2
If I use the DataReceived Event
The machine will not send anything until 5 seconds has elapsed since the last transmission from host computer, at that time it starts sending its address to the host.
It thinks the communications link is broken.

The communications protocol is designed to work with RS485 and Fiber optic as well.

I know the program that I am trying to write my own version, becasue it lacks a database, polls the machine.
I can tell that by the data captured with a serial monitoring program.

I suspec it was done in 2001-2002
I just wish I could figure out what they used to code it and what libaries they used.
Nov 30 '11 #3
arie
64
Are you sure it is not some sort of hardware problem? What kind of connection is it? Do you use RS-485 and some sort of converter or something else?

Do you know what exactly and when exactly is sent/received by your program and at what time? There is virtual serial port emulation software that can intercept your data, so you can see what's going on. (I used it, but it was someone else who installed it so I dont realy remember what was it called).

That's how I found out what was causing my problem: I asked my device for data, then, sometimes, it wasn't responding for few seconds (or even a minute). It turned out my data was sent/received correctly by the device, but the converter1 (connection device <> RS-485 <> converter1 <> LAN <> converter2 <> RS-232 <> host PC) was malfunctioning and it was holding baches of data randomly.

From my experience, DataReceived event usually is received just fine and it's usually something else at fault (programming or hardware problem).

Does your communication protocol include some sort of "end of message" byte/character? If so, I've seen solutions on the Internet that:
- use timer to ask for data
- use DataReceived event and, within its method, Read(buffer, 0, bytes) or ReadExisting() method to receive data and put it into a buffer.
- buffer is a global variable that is processed outside of DataReceived by some sort of queue and BackgroundWorker, or by another thread. Messages are distinguished using "end of message" byte/character.
Dec 1 '11 #4
I was saying the protocol can use R232, RS485 and fibre.
the machine has all 3 available on it's comm board
I have used both Advanced Serial Port Monitor(AGG) and Free Serial Port Monitor (HDD) to watch the port. I have the machine configured to use RS232
The software i am trying to code so I can use my own) warns that it may have communications issue, but it never has that I noticed.

Using the monitor program I noticed it thinks the port is configured 8 data bits and 2 stop bits. I should try running Advanced Serial Port Monitor on it again

The software I am trying to copy sends out 0x80 and (0x80 OR'ed with address) both with wake up bit set) the machine will then send a response no wake up bits set)
If the software has a commmand for the machine it sends the address (0 to 127) with wake up bit sst, then the command/instruction/data and a custom CRC with no wake up bits.

The only time the machine asserts a wake up bit is when it thinks the link is broken, not getting polls from the host.

there is no special end of data character sent (depending on the response the packet size will vary from 1 byte to 16 or so.
the only 1 byte I see is the Ack from the machine for some commands
the host has to send at least 4 bytes out for command/request.
Example
0x01 0x50 0x12 0x24 outbound could be address (wake bit) shutdown and 16 bit CRC these are example bytes the machine responds 0x01 if it got the command no wake up bits.

It is getting framing errors
Default replacement is 3F I changed it to 00, until I can figure out how to make drivers, OS and .NET Framework ignore the framing error, which might solve my issue.
if I get a bad byte oh well, the crc will fail and either the host or machine will re-transmit.
Dec 2 '11 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: dalewz | last post by:
Hi, Could sb kindly answer my following questions: Plan: I am trying to find a language to build a GUI to communicate with our device via serial port. Questions: 1. which language (VC++...
2
by: bernatik | last post by:
hi all I am trying to control special device through serial port from Linux. For that purpose I need to control DTR signal. I am watching the signal on a oscilloscope, so I know exactly what is...
4
by: H J van Rooyen | last post by:
Hi All, I am writing a polling controller for an RS-485 line that has several addressable devices connected. It is a small access control system. All is well- the code runs for anything from...
0
by: usagimys | last post by:
Hi all, i'm very new in serial port communication.. here i got some problem in writing to the serial port.. i have done the connection successfully.. let me explain my situation.. i'm doing a system...
7
by: centurion11 | last post by:
Hi All, Anyone know know to write a C++ program that able to record all the data that send to and receive from device through Serial Port (COM1)?
3
by: srikanth123456 | last post by:
whether windows.h is supported in C language if so how to include it in c library. can u also help me by giving concepts for the interrupt handling phenomenon in C language for a device...
2
by: paridaG | last post by:
Hi Can any one help me ? I have connected a HID reader to my serial port. It is working fine through my c++ program. Is it possible to connect one more device to serial port and need to work...
0
by: dtittle | last post by:
I am working on an app which will run on a hand held device. I am using Terminal Services to access a progarm on a server. This app needs to get accept an input and then send it to the (app) on ...
6
by: terry | last post by:
Hi, I am trying to send a character to '/dev/ttyS0' and expect the same character and upon receipt I want to send another character. I tired with Pyserial but in vain. Test Set up: 1. Send...
4
by: JDS | last post by:
I have an application that interfaces with a USB device using the .Net serial port. The code works fine, displaying live data on the screen; that is until the USB lead is pulled out from the PC...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.