Software challenge

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

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

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?

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

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

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)

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.

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

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

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.

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.

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.

What am I missing?

Less than I am. :smiley:

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.

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

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:

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...