Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 199
  • Last Modified:

DanRollins: [Serial Port: Terminate Writes in Progress]

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
qqqqqqqqq
Asked:
qqqqqqqqq
  • 6
  • 5
1 Solution
 
DanRollinsCommented:
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
 
qqqqqqqqqAuthor Commented:
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
 
DanRollinsCommented:
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
qqqqqqqqqAuthor Commented:
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
 
DanRollinsCommented:
>>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
 
qqqqqqqqqAuthor Commented:
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
 
DanRollinsCommented:
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
 
qqqqqqqqqAuthor Commented:
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
 
DanRollinsCommented:
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
 
qqqqqqqqqAuthor Commented:
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
 
DanRollinsCommented:
>>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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now