|
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]
|
|
|
|
|
thank you, for your suggestions
|
|
|
|
|
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.
|
|
|
|
|
thank you, for your suggestions
|
|
|
|
|
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);
m_comm.SetSettings("9600,N,8,1");
m_comm.SetInputLen(1);
m_comm.SetRTSEnable(FALSE);
m_comm.SetRThreshold(0);
m_comm.SetPortOpen(true);
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);
}
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.
|
|
|
|
|
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.
|
|
|
|
|
Where's the 'Great Answer' button?
My 5.
|
|
|
|
|
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.
|
|
|
|
|
you have any articles or sample programs?and Can I ask articles or sample program?
|
|
|
|
|
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.
|
|
|
|
|
okey, thanks
do you have sample program?
modified on Wednesday, September 14, 2011 1:17 AM
|
|
|
|
|
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.
|
|
|
|
|
|
okey... thank's. i will try your suggest...
|
|
|
|
|
Hi,
It's been a while since I've posted in here.
A friend and I have a problem with MFC,
We're trying to get the handle of a PictureBox in MFC,
but the code we use keeps returning null.
Here is a code snippet we're using
CStatic* pCStatic = (CStatic*) GetDlgItem(IDC_STATIC1);
HWND hWnd = pCStatic->m_hWnd;
We're trying to get the handle of the PictureBox so we put a DirectX into the control.
Many Thanks
Tom
|
|
|
|
|
Tom,
Make sure that you are calling GetDlgItem(int) from the parent window of the CStatic because the MFC wrapper auto-populates the first HWND parameter with this->m_hWnd. You could also use the global namespace function ::GetDlgItem(HWND,int) if you want to call this function from outside the window class.
I would actually recommend that you avoid using GetDlgItem and instead use a control variable. In some cases the GetDlgItem function will return a pointer to a CTempWnd object. Another reason to void GetDlgItem is because of performance reasons... GetDlgItem causes the MFC framework to iterate through an internal handle map in an attempt at finding a permanent object. In some projects this map could contain several hundred or more handles. So if an engineer is using a function such as GetDlgItem from WM_PAINT handler or perhaps WM_TIMER they could potentially be iterating needlessly through this map dozens of times per second or more.
Best Wishes,
-David Delaune
|
|
|
|
|
hi,everyone.
When using the Windows FileOpen dialog with multiple selection do you ever wonder how much memory you have to allocate for the buffer. Is one kilobyte going to be enough? Or should you make it ten? How about one Megabyte just to be safe?
It seems that no matter what you choose, you are either going to waste a whole bunch of memory just to be safe, or your user is going to select a bunch of files only to find their selection didn't work because your buffer was too small.
one way is Derive the CFileDialog class , the article as follow introduce it:
Multiple Selection in a File Dialog
but I have the other method: use the hook function of CFileDialog. I write some code as follow:
UINT_PTR CALLBACK MyOFNHookProc( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
int nResult = FALSE;
if (hdlg == NULL)
return 0;
#ifdef _DEBUG
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_pAlternateWndInit != NULL)
pThreadState->m_pAlternateWndInit = NULL;
#endif
switch(uiMsg)
{
case WM_NOTIFY:
{
LPOFNOTIFY pOfn = (LPOFNOTIFY)lParam;
switch(pOfn->hdr.code)
{
case CDN_SELCHANGE:
{
TCHAR dummy_buffer;
HWND hOwner = GetParent(hdlg);
HWND hParent = GetParent(hOwner);
UINT nfiles = CommDlg_OpenSave_GetSpec(hOwner, &dummy_buffer, 1);
int cbLength = CommDlg_OpenSave_GetSpec(GetParent(hdlg), NULL, 0);
cbLength += _MAX_PATH;
if(cbLength>(pOfn->lpOFN)->nMaxFile)
{
if((pOfn->lpOFN)->lpstrFile)
HeapFree(GetProcessHeap(),
0,
(pOfn->lpOFN)->lpstrFile);
(pOfn->lpOFN)->lpstrFile = (LPTSTR) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
cbLength);
(pOfn->lpOFN)->nMaxFile = cbLength;
}
nResult = TRUE;
break;
}
default:
break;
}
break;
}
default:
break;
}
return nResult;
}
void CMultiSelectDlg::OnButton1()
{
#define NAMEBUF 1024
TCHAR szFilters[]= _T("MyType Files (*.doc)|*.doc||");
CFileDialog fileDlg(TRUE, _T("doc"), _T("*.doc"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT, szFilters);
fileDlg.m_ofn.lpstrFile= (LPTSTR) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
NAMEBUF);
fileDlg.m_ofn.nMaxFile = NAMEBUF; fileDlg.m_ofn.lpfnHook = (LPOFNHOOKPROC)MyOFNHookProc;
INT_PTR ret = fileDlg.DoModal();
if (ret == IDOK)
{
int width = 0;
CString str;
CDC *pDC = m_listbox.GetDC();
int saved = pDC->SaveDC();
pDC->SelectObject(GetFont());
UINT count = 0;
POSITION pos = fileDlg.GetStartPosition();
while (pos)
{
str = fileDlg.GetNextPathName(pos);
m_listbox.AddString(str);
CSize size(0, 0);
size = pDC->GetTextExtent(str);
width = width > size.cx ? width : size.cx;
++count;
}
pDC->RestoreDC(saved);
ReleaseDC(pDC);
m_listbox.SetHorizontalExtent(width + 5);
str.Format(_T("%u files selected"), count);
m_static.SetWindowText(str);
}
DWORD dwCode = CommDlgExtendedError();
if (FNERR_BUFFERTOOSMALL==dwCode)
{
int i =0;
}
HeapFree(GetProcessHeap(),0,
(fileDlg.m_ofn.lpstrFile));
}
the code Reference the article as follow :
How To Handle FNERR_BUFFERTOOSMALL in Windows
but I found when the file names buffer is enough large , it run successly; but when when the file names buffer is not enough large (it means the program will enter if(cbLength>(pOfn->lpOFN)->nMaxFile) ), when after run INT_PTR ret = fileDlg.DoModal(); the value of ret is IDCANCEL. I catch the error code, it is FNERR_BUFFERTOOSMALL . In the end even I allocate a enough large memory ,the error code still is FNERR_BUFFERTOOSMALL . Why???
|
|
|
|
|
Well, for most application, if your buffer is something like 10 KB, then it would be a good compromise as it is not much memory on today computers and it would allows few hundreds of files to be selected with relatively long names.
In some very rare case, it might be usefull to be almost "illimited"...
Philippe Mori
|
|
|
|
|
I need to embed a logo on a live video stream. Where to start? where to end? thanks for the bullets.
|
|
|
|
|
Smith# wrote: Where to start?
Here[^] would be a good place.
|
|
|
|
|
if you're using windows and dshow, this is quite easy to do with an in-place transform filter; I've used it to put timecode and DOGs on video
|
|
|
|
|
I'm having some problems with my rather old codebase in VS2010 again. I have a MDI program where the child windows have a tabbed layout; This worked nicely up to VS2008, but in VS2010 the background of the tab bar is broken, see here. Any idea what could be causing this? Note that the tab bar looks perfectly OK when using the Win2k theme in Win7, it only looks like this with Aero enabled.
Somehow I think it could be related to the fact that the child windows are using a splitter pane with a top and a bottom pane, but the upper pane appears to be a CDialog - I have been told that this should actually not be possible at all, but somehow the previous developer of this app got it to work...
|
|
|
|
|
It looks like your tab control is inside an MDI window? If so, then the horizontal scrollbar is likely from the MDI window. With Aero enabled, controls and windows, and window components may have different sizes. You may have hard-coded some of these items.
In any case, the reason for the horizontal scroll bar is because the tab control is bigger than it's container (CDialog or MDI window).
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|