Go Down

Topic: Software challenge (Read 7281 times) previous topic - next topic

retrolefty

Jan 22, 2011, 07:12 pm Last Edit: Jan 22, 2011, 07:12 pm by retrolefty Reason: 1
Is there any way a running sketch could determine or calculate what clock rate it was running at?

I don't have a application in mind at the moment, I'm just curious if such a function could be developed? Some clever hack?

Lefty

Coding Badly


Nothing external available that might provide clocking?  Like a serial port?

retrolefty

#2
Jan 22, 2011, 08:18 pm Last Edit: Jan 22, 2011, 08:27 pm by retrolefty Reason: 1
Quote
Nothing external available that might provide clocking?  Like a serial port?


Correct, self contained. However I would allow an external wire from a digital output pin back to a digital input pin. I don't have a clue if it is even possible,  so I'm not offering like a prize or something.  ;D

PS: You have given me an idea for something I should try and write. A general purpose auto-baud rate detector function. Should be simple, just use pulseIn command to get the LOW data bit width from pin 0  and compare that to a look up table of values and then one could start the serial.begin command with?


stimmer

#3
Jan 22, 2011, 08:33 pm Last Edit: Jan 22, 2011, 08:33 pm by stimmer Reason: 1
I was thinking on those lines too, a wire from an output pin to an input pin. Put the output pin high, then count how many clock ticks until the signal appears on the input pin.

Unfortunately the wire would have to be 299792458 metres long  ;D
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

retrolefty

#4
Jan 22, 2011, 08:49 pm Last Edit: Jan 22, 2011, 09:27 pm by retrolefty Reason: 1
Quote
Unfortunately the wire would have to be 299792458 metres long  


That of course that is a fail. However you get points for thinking outside the box, like in 19,000 miles outside the box.  ;D

Lefty

Coding Badly

#5
Jan 22, 2011, 08:50 pm Last Edit: Jan 22, 2011, 08:50 pm by bcook Reason: 1
Quote
so I'm not offering like a prize or something.  

Lunch at your favorite restaurant when/if the winner is in your town?

Any restrictions on processors?  (I suggest you only allow processors you have on hand so you can verify the win)

Quote
PS: You have given me an idea for something I should try and write. A general purpose auto-baud rate detector function. Should be simple, just use pulseIn command to get the LOW data bit width from pin 0  and compare that to a look up table of values and then one could start the serial.begin command with?

The problem with serial data is finding the start / stop bits.  If the serial bits are a continuous stream, it can be surprisingly difficult.  

If you know something about the actual data / protocol (e.g. the data is ASCII from a Toledo balance or ASCII from a barcode reader or always the letter'x') it is much easier to do auto-bauding (which is in no way related to the autobahn).

After having dealt with serial port settings and impatient users I can say that automatic baud detection is a very nice feature.

retrolefty

#6
Jan 22, 2011, 09:09 pm Last Edit: Jan 22, 2011, 09:17 pm by retrolefty Reason: 1
Quote
The problem with serial data is finding the start / stop bits.  If the serial bits are a continuous stream, it can be surprisingly difficult.  


Well is it really? Using the pulseIn() command measuring the first low to high pulse width it sees will either capture the width of the first start bit width or any valid zero data bit width if the stream is already active. A start bit and a data bit have the same width at any given baud rate.

That should be the only info needed to then calculate or lookup the value to then use in the serial.begin function? The only hard decision I see is if to just hang waiting or put a timeout value to signify that it's still waiting for a first character to arrive, possible blink a led while waiting. I think it's simple using the already created pulseIn() function.

What am I missing?

Lefty

retrolefty

#7
Jan 22, 2011, 09:20 pm Last Edit: Jan 22, 2011, 09:24 pm by retrolefty Reason: 1
Quote
Lunch at your favorite restaurant when/if the winner is in your town?


It's worth two free beers at a local bar of my choosing.  ;D

Quote
Any restrictions on processors?  (I suggest you only allow processors you have on hand so you can verify the win)


Must support at least 168/328/1280/2560 arduino boards.

Coding Badly

Quote
Well is it really? Using the pulseIn() command measuring the first low to high pulse width it sees

Ah.  Measuring a single bit.  Good idea.  I got it in my head you'd be measuring an entire byte.  Which is not a good idea.

Quote
will either capture the width of the first start bit width or any valid zero data bit width if the stream is already active. A start bit and a data bit have the same width at any given baud rate.

What if there are two same value bits side-by-side?  Or three bits?

But, you could sample for a while (using pulseIn) and take the lowest reading.  Or, you may be able to collect a few samples and deduce the single bit time.  I think the trick is to determine which timings are for odd numbers of bits or prime numbers of bits.

Quote
What am I missing?

Less than I am.   :D

retrolefty

#9
Jan 22, 2011, 09:33 pm Last Edit: Jan 22, 2011, 09:35 pm by retrolefty Reason: 1
Quote
What if there are two same value bits side-by-side?  Or three bits?

But, you could sample for a while (using pulseIn) and take the lowest reading.  Or, you may be able to collect a few samples and deduce the single bit time.  I think the trick is to determine which timings are for odd numbers of bits or prime numbers of bits.


Good point that multible zero bits in a row is a possiblity, I'll have to think about that.

Graynomad

If you don't know the data being received there's no foolproof way to get the bit rate. However, as CB said, you have to sample for a while (how long? at least a few transitions I would think, even better a few bytes, the longer the better) and use the smallest value.

______
Rob

Rob Gray aka the GRAYnomad www.robgray.com

mmcp42

could you do something like (not sure how) arrange an interrupt to go off every 1 mS
in a loop increment a counter
when the timer ticks
see what the value counter is
save it in an array clear it
rinse & repeat

average the results in the array
:shrugs:
there are only 10 types of people
them that understands binary
and them that doesn't

westfw

You can read in the internal fuse bits.  This will tell you at least whether the chip is using the internal oscillator or an external crystal of some kind.  In theory, there are different values for different ranges of crystal speed as well, athough the ranges are quite wide.

Also, the WDT oscillator is separate from the main clock, so at least in theory you should be able to turn on the WTD as an interrupt and time how long before the interrupt actually happens.  I believe that the WDT oscillator is uncalibrated, but this should be sufficient to distinguish 1MHz from 8MHz from 16MHz...

Go Up