Serial doesn't work after setting prescalar for system clock

Hello

I’m running a 16mhz clock (crystal) on arduino atmega328p revision 3 and i’m trying to get the Serial debug statements i wrote to display in the arduino serial monitor.

If the prescaler is 1 as this one is (factory supplied) then it of course works. I set the baud rate at 9600 and the serial monitor to the same, and it all works great.

When i change the prescaler to use a divisor of 8 then serial just no longer works. I figured since it is running 8 times slower i could perhaps increase 9600 * 8 and it would then spew out at 9600 again.

When that failed i tried the inverse and set to 9600 / 8 just in case i had my sums wrong.

So it doesn’t work at 9600 or at 9600 times or divided by 8.

Anyone experienced this and or know of a solution?

I’m using Arduino 1.0.6 btw

Thanks

J

terraslate:
When i change the prescaler to use a divisor of 8 then serial just no longer works. I figured since it is running 8 times slower i could perhaps increase 9600 * 8 and it would then spew out at 9600 again.

Yes indeed. Should work.

Maybe you are mixing up 8 with 28.
Meaning you want to slow down the CPU by factor 8, but you actually slow it down by factor 28.

Maybe.
Or something else.
Hard to say from your telling.

terraslate:
So it doesn’t work

WHAT doesn’t work?

Show your code!

If you set the prescale to 8 to change the system clock from 16 MHz to 2 MHz you have to multiply the baud rate by 8.

Multiplying 9,600 by 8 gets you 76,800 but the calculation for how many clock cycles per input sample is done in integers:

(16,000,000 / 4 / 76,800 - 1) / 2 -> 25.541666... but in integers it comes out to 25. Running the math backwards to get the actual baud rate results in 78,431 baud which at the lower clock speed comes out to 9,803.875 or about 2% fast. In theory it should work fine if you use 76,800 (or 78,431).

Are you multiplying the baud rate by 8 in your sketch? If so, you are probably overflowing some 16-bit integer math. 32,767 is the largest value a 16-bit integer can hold. You have to do the math in long (or better, unsigned long):

Serial.begin(9600UL * 8UL);  //  9800 baud with a prescale of 8.