Solved

DanRollins: [Serial Port: Terminate Writes in Progress]

Posted on 2002-05-15
11
192 Views
Last Modified: 2010-04-02
Hi it's me again. I feel kind of stupid now, but after thinking about it, maybe the method you proposed in your answer makes more sense [and is much better?]. I was messing around with your code however i must be doing somthing wrong because it seems to display very unpredictable results. I can't give much detail on these results because to me they seem unpredictable. However I'm offering 250 points if you can sucessfully outline the code you used, in detail (maybe an example). Hopefully this will give me enough information to see where my implementation is lacking. [if i have more troubles i'll add more points]

notice= many times the device displays the same number even when i change the number [in your example it was 375]
0
Comment
Question by:qqqqqqqqq
  • 6
  • 5
11 Comments
 
LVL 49

Accepted Solution

by:
DanRollins earned 250 total points
ID: 7013086
I showed you the simplest variation... It sends the entire one-second's worth in one burst.  So this secret device is probably sampling the data in a way that is a mystery.

I told you there were thousands of way to split it up.  Here is an example that "evens it out" by sending bursts of 1/2 the desired amount in 1/2 the time:

int nDesiredDisplay= 8000;
int nBytesPerSec= nDesiredDisplay/8;
int nIntervals= 2;

DWORD dwTicksPerInterval = 1000 / nIntervals;
int nBytesPerInterval= nBytesPerSec / nIntervals;

while( not wanting to exit )
{
   dwNextIntervalEnd= GetTickCount() + dwTicksPerInterval;
   while( nCntSent < nBytesPerInterval ) {
       Write( *pData, 1 );
       pData++;
       // note: you would need to check for end, and
       // get more data and (perhaps) adjust pData to start
       // to implement a circular buffer
   }
   if ( GetTickCount() > dwNextIntervalEnd ) {
        TRACE("Interval was too big\n");
   }
   else {
       TRACE("sleep gap is %d ms\n", dwNextIntervalEnd -GetTickCount() );
   }
   while( GetTickCount() < dwNextIntervalEnd ) {
       Sleep(1);
       // probably ought to pump message here
       // unless this is running on a worker thread.
   }
}

Now you can vary nIntervals to "even it out"  Try various values 2 to maybe 10 or even more.  At some point, the Write may take longer than the interval.

Of course I did not and cannot test this code.

-- Dan
0
 

Author Comment

by:qqqqqqqqq
ID: 7013274
ok looks good, i'll test this tomorrow [no time tonight], looks like it will work. I'd just like to make a clarification about the pointer pData. It appeared that pData was a BYTE*. Is there anything special i need to do to convert my char* into the BYTE*? I've just been casting it. Also, I'm a little curious as to the functionality of pData. All I want to send to the device is 1 byte (looped). I have no commands, just data or no data. It seems like instead of:
Write( *pData, 1 );
pData++;
I could just do
Write( *pData, 1 );
If pData hold the data to write to the port, then it would just be a string of up to 1000 "1"s or "r"s. Do you understand what i'm saying. It doesn't matter what the data is as long as it's a byte.
Would that work?

And last of all: "// probably ought to pump message here". Pump what message?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7014660
If the actual data that you want to send is unimportant, just, just send a hardcoded liter.  For instance:

    Write("X",1);

BYTE* and char* are the same unless you are doing arthmetic with the variable.  If all you are doing is passing it around, you can coerce one to the other without problem.

-- Dan
0
 

Author Comment

by:qqqqqqqqq
ID: 7015731
ok, i tried out the code. It works in theory but not so well in practice. There's just nothing as smooth as changing the baud rate. The problem is that i can't send data while i'm changing the baud rate because that creates problems. Is there some other way to set the baud rate (that takes less time, because i need to have data being sent to the device almost all the time)? Maybe somthing like a serial port access class that lets me implement a virtual baud rate. This would not actually set the real baud rate but do somthing similar to the code you presented, although just as precise as if the actual baud rate were being changed. Is somthing like this possible?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7015837
>>Maybe somthing like a ...
No.  What you are trying to do is extremely unusual.  I can't make any sense out of it.  Is that device counting 1's only?  or both 1's and zeros?  What is it DOING?

What settings did you try for nIntervals?  If you make that big enough, then the output will be quite even.

Try changing Sleep(1) to Sleep(0).

-- Dan
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:qqqqqqqqq
ID: 7018503
the device counts what ever it gets. each "character" it recieves counts the same as any other character. sending: "111111" is the same as sending "k*(s0]". I modified the code a little bit, and got it to work, almost. I now have gotten the code to accuratly display the number supplied in the nDesiredDisplay variable.

Here's the problem though. When i put a low number in nIntervals the results are jumpy (for the device to continually display my data it needs to be recieving it continuously). When i put a high number in nIntervals the results are not accurate (the number is too low, maybe the math gets off when it's divided by a high number?)

Think about the device as if it were an LCD that displays a 4 digit number. (although it is programmed much differently).
When nIntervals is low, the number displayed is correct, but it flashes on the screen (the number is there when it recieves data but goes away when no data is there).
When nIntervals is high, the number displayed is incorrect, but it is continuously displayed on the screen.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7018570
Have you ever noticed that in some of my posts I ask you a question and that about one in three times you bother to reply to it?  It's an interesting statistic.  If it applies to the rest of your life, you can stop wondering why people don't always help you.  That's the reason.

>>When i put a high number in nIntervals the results are not accurate (the number is too low,

It could be due to how often your thread gets a timeslice of it might be the number of bits (9 vs 8) that the device is counting.  In a way, it really doesn't matter.

Take the pragmatic approach.  Add a 'fudge factor' to nBytesPerInterval so that the number displayed comes out to match nDesiredDisplay.

-- Dan
0
 

Author Comment

by:qqqqqqqqq
ID: 7018614
first: what questions have i not answered? i apologize if i have been neglecting any questions you've asked.

second: when i say the numbers are innacurate, they are really inaccurate.

With nIntervals set to 1 and a nDesiredDisplay number of 4000 the device displays 8000.
With nIntervals set to 15 and a nDesiredDisplay number of 4000 the device displays 4000.
With nIntervals set to 22.5 and a nDesiredDisplay number of 4000 the device displays 3000.
With nIntervals set to 30 and a nDesiredDisplay number of 4000 the device displays 2000.

Almost looks like a little pattern (but: examine the jump between 1 and 15). Wouldn't you say? However to get these results I changed the line reading:
int nBytesPerSec = nDesiredDisplay/8;
to
int nBytesPerSec = nDesiredDisplay/80;
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7018712
LOL.  Let me paraphrase what you just wrote:

?> Your code doesn't work as advertised!  What is wrong
?> with your stinking code???  By the way I changed one of
?> your variables by an order to magnitude.

I suggest that you write a little GUI with some input boxes or sliders that control the various settings.  Then you can interactively change some values to see -- in real time -- what effect each change has on the device.

-- Dan
0
 

Author Comment

by:qqqqqqqqq
ID: 7018858
ok, i''l make the GUI today. Just to let you know, if i changed one of your variables by 1 order of magnitude,the correct variables were displayed. If I left it as it was, no matter which value i instructed it to display, it displayed a value larger than the device was capable of displaying (like when a 2 digit counter displays 99 because it can't go higher). Looking at that, I really don't think that my change was so laughable.

Note: you didn't answer my question either. If you feel there is a situation, maybe giving me more information about our communication problem, would help me answer your questions better.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7019466
>>What settings did you try for nIntervals?  
You did not answer that question until the next post.  I did not point it out to you because I assumed you would re-read the post (which you did).

But just as mportant is what I have *not* asked you that I would expect you to volunteer.  For instance, there are debug window messages that will provide feedback that I can't see but you can.  

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Another way to smooth out the data would be to set and maintain a lower baud rate.  That would tend to even out the data so you could use fewer intervals with smaller gaps between the bursts.

>> With nIntervals set to 15 and a nDesiredDisplay number of 4000 the device displays 4000.

If the display is correct at this constellation of settings, then you are done.  You don't need to keep trying different settings, just different values for nDesiredDisplay.

I don't understand why you need to use
  int nBytesPerSec = nDesiredDisplay/80;
unless the device is displaying bytes per 1/10th-of-a-second.  Otherwise the than does not work.  Are you sure of its settings?

Keep an eye on the Debug window.  Those TRACE messages will help you diagnose the situation.

-- Dan
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now