`(unsigned long)( adc_raw * adc_raw)`

does not give the same result as` (unsigned long) adc_raw * (unsigned long)adc_raw`

I don't know why. It just doesn't on the uno.

It's because the Uno uses 16-bit integers, and the values of

*adc_raw* are bigger than 8 bits, so their product overflows an integer calculation on the Uno.

*adc_raw* is type

*int*, so the calculation is dutifully carried out with integer math. When the result is bigger than 16 bits, the calculation overflows and information is lost. The reason that it doesn't work on the Uno, and might on some other platforms, is that Uno integers are 16 bits, and they're bigger on some other machines.

I'd prefer to cast

*adc_raw* as

*long*, since it clearly takes on negative values. The calculation yields the same result either way, on account of the miracle of two's complement arithmetic, but I'm more comfortable closer to the mathematical realities of the problem.

The other thing that rankles about the original program is the nominal sample rate at 1 per 100 us. A standard analogRead() takes a bit longer than that, so the timing will always be off.