|
Hi,
whatever sleep() function you use, you will get a stand-still for at least the time you specify, however it could be much longer as there are dozens of threads all running on a typical Windows system.
The only scheme that might work to some extent is this:
- assume a multi-core system;
- create a program (or a thread in an existing program) that contains busy loops, so it is simply getting and checking time all the time, then setting the output(s) as required. Of course you need a high-precision timer, maybe the PerformanceCounter stuff.
- make sure to elevate the thread's priority to PRIO_REAL_TIME, so nothing else is likely to steal the core.
WARNING: it is quite a hack, I do not consider this good enough to provide steps to a stepper motor; steps will vary, resulting in horrible noise, and shaky operation. Also, as you are going to move something that may harm humans, you have to provide fail-safes; those cannot be trusted when their function also is based on your Windows app.
|
|
|
|
|
you suggest me to keep my comp busy?
it is not a stabil solution, i think
i will try to connect an oscilator which creates particular frequency pulses.
and write an event handler in my program which sends the motion code to output whenever the input is high
is it possible? (i know it is dangerous, i can break my mainboard down )
--always comes daylight after night-----
|
|
|
|
|
Adnan Merter wrote: you suggest me to keep my comp busy?
that is not my suggestion, it is the only idea that will make a Windows machine do what you want it to do at sub-millisecond levels.
my real suggestion is you add external intelligence (i.e. a micro-controller) that generates (micro-)steps and ramps up and down to a new speed and takes care of safety measures, so all that is left for the PC to do is provide macroscopic commands (say once every second).
|
|
|
|
|
That will probably violate the Shannon theorem.
The pulses will simply get lost when your program is not listening the event handler (just moving the mouse will cause that, not to mention other running processes in the system !)
Windows cannot handle things that are faster than widows itself in doing context switching.
It simply cannot catch them up.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
thanx for warning,
what do you suggest?
i need any kind of idea, i have to do this job whatever it costs
--always comes daylight after night-----
|
|
|
|
|
Until the question remain in theese exact term, there can be no answer:
"I have to go faster than light"
"It is not possible in this universe"
"I have to do it whatever it cost!"
The proper answer is to change the universe!
In your context, it means that motor steps and speed sholud be controller by a different processor (probably a microcontroller) that should have no operating system on it, but must just execute a simple program that manage the steps based on some "variable" you have to set from the extern, and that receive some information fom the "extern" to set those variables.
And the "Extern" can be a PC taking with the microcontroller (may be via serial, or via ethernet) in getting/setting the values the cotroller use as parameters to govern the engine.
Note that windows high resolution timers cannot help, since they exist to measure time, not to control process switching, that is never granted to happen in constant timeslot.
What happens if you open Otlook or Word or Powerpoint while the motor is running ?
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
You can use watiable timers to provide short and fairly deterministic delays. The time is specified in 100 nSec units but I don't know if sub-millisecond timeing is that realistic. I have used them to provide pretty accurate 1mSec delay (unlike sleep which isn't that accurate)
You could give it a go. You will need the following API calls:
CreateWaitableTimer()
SetWaitableTimer()
WaitForSingleObject()
Obviously this needs to be in a worker thread rather than the main thread. If you have any problems using them, let me know as I have some code frags.
Tony
|
|
|
|
|
thanx tony
i will try what you suggest
if i cant do this (most probably ), i will let you know.
--always comes daylight after night-----
|
|
|
|
|
i found this and it works fine, there is no problem so far but i cant how to set the timer less time periods and the ms is accurate ms here?
#include <windows.h>
#include <process.h>
#include <stdio.h>
unsigned __stdcall TF(void* arg) {
HANDLE timer=(HANDLE) arg;
while (1) {
WaitForSingleObject(timer,INFINITE);
printf(".");
}
}
int main(int argc, char* argv[]) {
HANDLE timer = CreateWaitableTimer(
0,
false,
0);
LARGE_INTEGER li;
const int unitsPerSecond=10*1000*1000;
li.QuadPart=-(2*unitsPerSecond);
SetWaitableTimer(
timer,
&li,
750,
0,
0,
false);
_beginthreadex(0,0,TF,(void*) timer,0,0);
while (1) ;
return 0;
}
--always comes daylight after night-----
|
|
|
|
|
If you set the time interval to zero, you can use the waitable timer as a one-shot delay. It this case, the "due time" is in 100nSec intervals (0.1 microsecond). Maybe you could retrigger by calling SetWaitableTimer() again but I suspect that this call could take a microsecond which defeats the object (could be worth a try). If you need a periodic timer with sub-millisecond period then maybe this isnt the thing for you but I thought it would be worth mentioning it, because its better than using Sleep().
Tony
|
|
|
|
|
I would like to do something on a view based on right and left clicks on the status bar of CMainFrame. I was able to do it succesfully using SendMessage command in Pretranslate function, but I noticed that it was breaking standard windows shortcuts like CTRL +F4 and others... Is there a better way of sendng these messages without overriding :::PreTranslate function ?
Thanks
|
|
|
|
|
I'm not sure why you need to override PreTranslate() . Why not just add the SendMessage() or PostMessage() in the code that handles the mouse clicks? Also if you have message conflicts then use one of the values reserved for applications - WM_USER + x .
|
|
|
|
|
great, but why can't I seem to do the left and right click handlers in MainFrame ? It doesn't even hit those handler functions when Left and right clicked. I do have ON_WM_LBUTTONDOWN() defined for example in the Message map as well.
Any ideas what I could be missing there?
|
|
|
|
|
Well this is a totally different issue; your original question suggested that you were capturing the mouse clicks. The comments above imply this is MFC, which is something I haven't used for many years, so I'm afraid I cannot offer much more, apart from suggesting you check all the alternative events that MFC will send to you.
|
|
|
|
|
Thanks, yes it is MFC. Yes, I was able to capture clicks within the PreTranslate function, but OnLButtonDown(UINT nFlags,CPoint point); is whats not working, it isn't even going there.
|
|
|
|
|
Are you sure your PreTranslate() function is returning the correct value so the messages still get dispatched? If you tell the framework that you have already handled the message then they will never get to the relevant event handler elsewhere.
|
|
|
|
|
The following code works, but breaks some of the standard Windows shortcuts for some reason. How do I just implement ONLeftMouse and OnRightMouse handlers to do the equivalent? I tried doing void CMainFrame::OnLButtonDown(UINT Flags,CPoint point) & void CMainFrame::OnRButtonDown(UINT Flags,CPoint point), but It isn't going there. Any ideas?
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
POSITION FirstDoc =theApp.m_pMainDocTemplate->GetFirstDocPosition();
if(FirstDoc !=NULL){
CMYAppDoc* pDoc = (CMYAppDoc*)theApp.m_pMainDocTemplate->GetNextDoc(FirstDoc);
if(pDoc != NULL){
POSITION pos = pDoc->GetFirstViewPosition();
while (pos != NULL){
CView* pActiveView = pDoc->GetNextView(pos);
if(pActiveView->IsKindOf( RUNTIME_CLASS(CRealView)) ){
CRealView *pView = (CRealView*)pActiveView;
if (pMsg->message == WM_LBUTTONDOWN)
pView->SendMessage(WM_LBUTTONDOWN,(WPARAM)0, (LPARAM)0);
else if (pMsg->message == WM_RBUTTONDOWN)
pView->SendMessage(WM_RBUTTONDOWN,(WPARAM)0,(LPARAM)0);
}
}
}
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
|
|
|
|
|
As I said earlier I haven't used MFC for a long time, and I have to admit I am not a great fan. However looking at the above code I am not sure that you should be calling SendMessage() within the PreTranslateMessage() function, as this tries to process the message in the relevant Window before returning. Maybe PostMessage would work as it merely puts the message into the queue for the specified Window. However, I am speculating here as I am not sure how the MFC framework treats this situation.
|
|
|
|
|
Hi,
With much appreciated help from this forum I have finally managed to display a 32 bit bitmap with graded transparency (using the alpha channel).
However, I have noticed that if the bitmap is re-drawn in the same location, the semi-transparent pixels become solid and so the image reverts to having a ragged edge.
Is this normal behavior or have I got a setting wrong?
Thanks
Tony
|
|
|
|
|
Are you clearing the background before redrawing the bitmap ?
|
|
|
|
|
Hi Cedric
Nope I am not and as you are suggesting, if I do this it works. The question then is how to clear the background?
The object containing the transparent bitmap only has access to a DC and not to a window so I cant easily use InvalidateRect().
Perhaps there is another way to clear the backgound. I even thought of copying the background into another bitmap and BitBlt it before drawing the transparent bitmap each time the object is repainted but is this getting a bit complicated?
Perhaps there is an easier way?
Tony
|
|
|
|
|
On which "surface" are you drawing your bitmap ?
|
|
|
|
|
Hi,
I have a window derrived from CWnd and the client area consist of a background bitmap with lots of animated bitmaps overlaid drawn in the Window's DC, mostly in response to WM_PAINT messages.
The background bitmap is redrawn in OnEraseBkgnd() and the OnPaint() handler creates a DC and tells all of the bitmaps to draw themselves.
Does that answer your question?
Thanks for your interest
Tony
|
|
|
|
|
softwaremonkey wrote: I even thought of copying the background into another bitmap and BitBlt it before drawing the transparent bitmap each time the object is repainted but is this getting a bit complicated
That's the right thing to do, because it will always deliver a correct result even if your background has a bitmap on it or is gradiented, and it is just a few lines of code more...
Note: I think you could use InvalidateRect() when could be garanteed that the window was repainted before you draw your bitmap on it. Maybe WaitForInputIdle() can help you with that. [modified] Why doing so difficult: if your background is a solid color why not paint it yourself?
Rozis
|
|
|
|
|
Hey Rozis, thanks for the reply.
You were right, it wasnt too difficult to store the background as a bitmap and redraw it each time and it has fixed the problem. As a side effect, I have been able to reduce the number of Invalidate() and InvalidateRect() calls I make elsewhere which reduces the flicker so its a win-win situation.
It is always good to have a sanity check though, to make sure that I'm not going off at a tangent!
Thanks again!
Tony 
|
|
|
|