Microsecond timer
-
Hi... I have a program to read data from serial port,and I want to repeat the program every 1 microsecond. this is my program, but I just can repeat every 1 milisecond
void CStripDlg::OnTimer(UINT nIDEvent)
{
int dcount=0;
CString data[4];
VARIANT in_dat;{ in\_dat = m\_comm.GetInput(); // read port CString strInput(in\_dat.bstrVal); m\_input.Format("%s", strInput); // show data m\_comm.SetInBufferCount(0); // clear buffer } } UpdateData(FALSE); CDialog::OnTimer(nIDEvent);
void CStripDlg::OnStart()
{
SetTimer(1,1,NULL); // set data 1 milisecond
}
}thx
Clock granularity on Windows is about 9 milliseconds. And thats if you are lucky. It is not a real time OS, so even that is not guaranteed. Especially form user mode. If you have any kind of hardware activity your user mode thread is going to get slung off the CPU. Even in the kernel you cant get this kind of timing, the granularity is the same, and although their threads have higher priority than user mode, any kind of interrupt or dispatch level activity is also gong to suspend your thread. It is quesitonable whether you want 1 microsoecond timing; the clock rate of the UART is probably not that fast (thnik 115200 bps), and that's per bit. The UART is going to asemble those into bytes, dividing the speed by at least 8 (depending on start and stop bits), and pack them in a buffer (if the UART hasnt got a receive buffer its a really shonky piece of HW). FFIOs are normally 8 bytes minimum so your rate of needing to service the receive data on the UART is divided by another 8. What is the problem you are trying to solve here? Perhaps if you told us that we can offer some advice.
============================== Nothing to say.
-
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
-
You 'millisecond' timer is already (as David already suggested) an illusion: Windows doesn't provide millisecond accuracy. In any case you shouldn't need microsecond time-scale for dealing with serial port communications.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
Clock granularity on Windows is about 9 milliseconds. And thats if you are lucky. It is not a real time OS, so even that is not guaranteed. Especially form user mode. If you have any kind of hardware activity your user mode thread is going to get slung off the CPU. Even in the kernel you cant get this kind of timing, the granularity is the same, and although their threads have higher priority than user mode, any kind of interrupt or dispatch level activity is also gong to suspend your thread. It is quesitonable whether you want 1 microsoecond timing; the clock rate of the UART is probably not that fast (thnik 115200 bps), and that's per bit. The UART is going to asemble those into bytes, dividing the speed by at least 8 (depending on start and stop bits), and pack them in a buffer (if the UART hasnt got a receive buffer its a really shonky piece of HW). FFIOs are normally 8 bytes minimum so your rate of needing to service the receive data on the UART is divided by another 8. What is the problem you are trying to solve here? Perhaps if you told us that we can offer some advice.
============================== Nothing to say.
-
Hi... I have a program to read data from serial port,and I want to repeat the program every 1 microsecond. this is my program, but I just can repeat every 1 milisecond
void CStripDlg::OnTimer(UINT nIDEvent)
{
int dcount=0;
CString data[4];
VARIANT in_dat;{ in\_dat = m\_comm.GetInput(); // read port CString strInput(in\_dat.bstrVal); m\_input.Format("%s", strInput); // show data m\_comm.SetInBufferCount(0); // clear buffer } } UpdateData(FALSE); CDialog::OnTimer(nIDEvent);
void CStripDlg::OnStart()
{
SetTimer(1,1,NULL); // set data 1 milisecond
}
}thx
microcontroller send data every 2 ms, my problem when the microcontroller gets the input, the program can not display the data directly, but must read the entire remainder of the data in the buffer. this is setting port, and recevied data. I use Microsoft Communication Control
TRY { m\_comm.SetCommPort(12); // use port 12 m\_comm.SetSettings("9600,N,8,1"); // setting port m\_comm.SetInputLen(1); // read 1 character m\_comm.SetRTSEnable(FALSE); m\_comm.SetRThreshold(0); m\_comm.SetPortOpen(true); // open port UpdateData(FALSE); MessageBox("Port opened successfully"); } CATCH(CException, e) { MessageBox("Error opening port"); } END\_CATCH
so I use the clear buffer to clear the buffer. but rather the execution time becomes slow and missing data
m\_comm.SetInBufferCount(0); // clear buffer }
can you offer some advice?
-
microcontroller send data every 2 ms, my problem when the microcontroller gets the input, the program can not display the data directly, but must read the entire remainder of the data in the buffer. this is setting port, and recevied data. I use Microsoft Communication Control
TRY { m\_comm.SetCommPort(12); // use port 12 m\_comm.SetSettings("9600,N,8,1"); // setting port m\_comm.SetInputLen(1); // read 1 character m\_comm.SetRTSEnable(FALSE); m\_comm.SetRThreshold(0); m\_comm.SetPortOpen(true); // open port UpdateData(FALSE); MessageBox("Port opened successfully"); } CATCH(CException, e) { MessageBox("Error opening port"); } END\_CATCH
so I use the clear buffer to clear the buffer. but rather the execution time becomes slow and missing data
m\_comm.SetInBufferCount(0); // clear buffer }
can you offer some advice?
What sort of HW is it, Who makes it? Doesnt it come with a proper driver or some other interface to the system? I cant believe any firm can sell HW that is pumping data that quick to a com port, it just isnt going to get serviced in windows. Is there perhaps a configuraiton to the device whereby you can increase the receive buffer or some such?
============================== Nothing to say.
-
Hi... I have a program to read data from serial port,and I want to repeat the program every 1 microsecond. this is my program, but I just can repeat every 1 milisecond
void CStripDlg::OnTimer(UINT nIDEvent)
{
int dcount=0;
CString data[4];
VARIANT in_dat;{ in\_dat = m\_comm.GetInput(); // read port CString strInput(in\_dat.bstrVal); m\_input.Format("%s", strInput); // show data m\_comm.SetInBufferCount(0); // clear buffer } } UpdateData(FALSE); CDialog::OnTimer(nIDEvent);
void CStripDlg::OnStart()
{
SetTimer(1,1,NULL); // set data 1 milisecond
}
}thx
You need to do the following. 1. Determine the actual baud rate. In your other code you suggested 9600. Presumably that is correct. 2. Create a thread. 3. That thread does the following and NOTHING else. a. Block on the serial port. (You don't use a timer but rather you wait until data is available.) b. Read one byte c. Add that byte to a thread safe queue. d. Go back to a. 4. In your GUI code (or wherever) you read data from the queue and do whatever you want with it. Note that this occurs in a different thread.
-
You need to do the following. 1. Determine the actual baud rate. In your other code you suggested 9600. Presumably that is correct. 2. Create a thread. 3. That thread does the following and NOTHING else. a. Block on the serial port. (You don't use a timer but rather you wait until data is available.) b. Read one byte c. Add that byte to a thread safe queue. d. Go back to a. 4. In your GUI code (or wherever) you read data from the queue and do whatever you want with it. Note that this occurs in a different thread.
-
You need to do the following. 1. Determine the actual baud rate. In your other code you suggested 9600. Presumably that is correct. 2. Create a thread. 3. That thread does the following and NOTHING else. a. Block on the serial port. (You don't use a timer but rather you wait until data is available.) b. Read one byte c. Add that byte to a thread safe queue. d. Go back to a. 4. In your GUI code (or wherever) you read data from the queue and do whatever you want with it. Note that this occurs in a different thread.
jschell wrote:
b. Read one byte
You want to read the FIFO taking out as many bytes at a time as you can. It is only for special control characters that you need to read individual bytes, such as DTR RTS CTS etc etc etc and you set those in the 'wait on mask'.
============================== Nothing to say.
modified on Tuesday, September 13, 2011 3:16 AM
-
jschell wrote:
b. Read one byte
You want to read the FIFO taking out as many bytes at a time as you can. It is only for special control characters that you need to read individual bytes, such as DTR RTS CTS etc etc etc and you set those in the 'wait on mask'.
============================== Nothing to say.
modified on Tuesday, September 13, 2011 3:16 AM
Few months back I was having the same issue of Microsecond. Windows does not provide granularity of 1 microsecond. For this reason we have used Real Time OS which is an extension to Microsoft Windows . The Timer granularity is well handled by RTOS ( provides upto 1 Microsecond , which can further modified by modifying the value of 'Ticks' of clock using some API of that RTOS.
-
Few months back I was having the same issue of Microsecond. Windows does not provide granularity of 1 microsecond. For this reason we have used Real Time OS which is an extension to Microsoft Windows . The Timer granularity is well handled by RTOS ( provides upto 1 Microsecond , which can further modified by modifying the value of 'Ticks' of clock using some API of that RTOS.
-
jschell wrote:
b. Read one byte
You want to read the FIFO taking out as many bytes at a time as you can. It is only for special control characters that you need to read individual bytes, such as DTR RTS CTS etc etc etc and you set those in the 'wait on mask'.
============================== Nothing to say.
modified on Tuesday, September 13, 2011 3:16 AM
Fat__Eric wrote:
You want to read the FIFO taking out as many bytes at a time as you can
I presume my answer wasn't clear. If you block on a read and there is in fact data available then you do not block. So many bytes are read. And a serial port is a single byte stream. So excluding an intermediate buffer mechanism it is only going to read one byte at a time. But if the API supports a buffered read then using that is certainly an option.
-
You need to do the following. 1. Determine the actual baud rate. In your other code you suggested 9600. Presumably that is correct. 2. Create a thread. 3. That thread does the following and NOTHING else. a. Block on the serial port. (You don't use a timer but rather you wait until data is available.) b. Read one byte c. Add that byte to a thread safe queue. d. Go back to a. 4. In your GUI code (or wherever) you read data from the queue and do whatever you want with it. Note that this occurs in a different thread.
-
Fat__Eric wrote:
You want to read the FIFO taking out as many bytes at a time as you can
I presume my answer wasn't clear. If you block on a read and there is in fact data available then you do not block. So many bytes are read. And a serial port is a single byte stream. So excluding an intermediate buffer mechanism it is only going to read one byte at a time. But if the API supports a buffered read then using that is certainly an option.
-
jschell wrote:
b. Read one byte
You want to read the FIFO taking out as many bytes at a time as you can. It is only for special control characters that you need to read individual bytes, such as DTR RTS CTS etc etc etc and you set those in the 'wait on mask'.
============================== Nothing to say.
modified on Tuesday, September 13, 2011 3:16 AM
-
Fat__Eric wrote:
You want to read the FIFO taking out as many bytes at a time as you can
I presume my answer wasn't clear. If you block on a read and there is in fact data available then you do not block. So many bytes are read. And a serial port is a single byte stream. So excluding an intermediate buffer mechanism it is only going to read one byte at a time. But if the API supports a buffered read then using that is certainly an option.
jschell wrote:
And a serial port is a single byte stream. So
Very very few are. As stated a single byte rcv buffer UART is a very shonky piece of hardware. The stock (what is it, 82530 or some such compatible UART on most PCs) has an 8 byte RX FIFO. Better quality UARTs on serial PCI cards will have far bigger FIFOs.
============================== Nothing to say.