ATtiny 841 Serial comms baud rate

Hi Guys

Was wondering if anyone could tell me what frequency crystal I should use with an ATtiny841 in order to use one or both the serial ports at 57.6K baud? Or is the internal oscillator at 8MHz accurate enough without the need for an external oscillator?

Bernie

Tattoo this site on the back of your eyelids WormFood's AVR Baud Rate Calculator Ver. 2.1.0 (or just bookmark it - that's good too) - it is incredibly useful when figuring out whether a baud rate and frequency combo "should" work. Use the U2X column.

As you can see, at 8mhz, 57600 is a couple % off, but it'll work (like it would on any 8-bit AVR).

The Internal Oscillator is good enough for serial at 57600 baud at 3.3v. Above 4v, the speed of the internal oscillator swerves skyward, and is closer to 8.1mhz, which is far enough off that it doesn't work. As you probably know I sell ATtiny841 boards on tindie; after bootloading them, I test by programming blink over serial - so far I've yet to find one that wouldn't work at 57600 baud with internal 8mhz at 3.3v. At 5v, though, they will almost never work on internal oscillator - though of course they do with crystal.

For that reason, I usually use a crystal myself, typically 8 or 16mhz (for 3.3 and 5v operation, respectively - of course, with a crystal, everything's fine with 8mhz @ 5v)

If you're picky about the UART clock speed being 0.0% off instead of 1-2% off, you can use a UART clocked crystal, and the latest versions of my cores support the common ones (7.37, 9.216, 11.056, 14.7..., 18.whatever), though microseconds() takes longer to return on weird clock speeds with my core (it gives wrong answers quickly with most Arduino cores). You don't need to use an exotic crystal though, as I said - plain old 8mhz and 16mhz crystals work fine.

Unlike DrAzzy I have only tried one 841. At 5V the default frequency at 20°C was about 8.27MHz. I never measured it at 3.3V but it must have been pretty good because I was running SoftwareSerial at 115200 (TX only) with the internal 8MHz oscillator. (edit: actually I forgot that I had measured it before -- my notes put it almost dead-on at 7.997MHz.

This was a while ago. For some reason I couldn't get hardware serial to work at all. Since software serial worked okay (I was just using it for debugging output) I never went back and figured out why. I was using pin 6 of the IC and the "Serial" object. Is that the wrong pin? The wrong Serial? Just curious.

jboyton:
Unlike DrAzzy I have only tried one 841. At 5V the default frequency at 20°C was about 8.27MHz. I never measured it at 3.3V but it must have been pretty good because I was running SoftwareSerial at 115200 (TX only) with the internal 8MHz oscillator.

This was a while ago. For some reason I couldn't get hardware serial to work at all. Since software serial worked okay (I was just using it for debugging output) I never went back and figured out why. I was using pin 6 of the IC and the "Serial" object. Is that the wrong pin? The wrong Serial? Just curious.

If you were running it at 5V, off internal oscillator, you'll get gibberish, because as you said, it was running at 8.27 mhz, but the code was compiled for 8mhz! As I noted above, that's enough to break UART. At 3.3v, the internal oscillator is quite close to 8.

You were also using the wrong pins

Serial is on arduino pins 8 and 9 (physical pins 11 and 12). Your code can use the remap register to move that to arduino pins 2 and 3 (physical pins 5 and 6), but that is not done by default

Serial1 is on arduino pins 5 and 6, (physical pins 8 and 9).

Thanks. I must have mistaken the blue highlighted pins on the pin map diagram I have for the default choices. Oops.

I dug out the breadboard from my cluttered pile of stuff and plugged it in. At 3.3V it worked with hardware Serial at 115200 in a simple loop back test to the Serial monitor.

It also worked at 5V. So I re-checked the default frequency (with a GPS):

3.3V: 7.990 - 8.000 MHz
5.0V: 8.273 - 8.282 MHz

It’s interesting that it worked for me at 5V/8.3MHz at 115200 baud but that in your tests it stopped working around 8.1MHz. I wonder why.

jboyton:
Thanks. I must have mistaken the blue highlighted pins on the pin map diagram I have for the default choices. Oops.

I dug out the breadboard from my cluttered pile of stuff and plugged it in. At 3.3V it worked with hardware Serial at 115200 in a simple loop back test to the Serial monitor.

It also worked at 5V. So I re-checked the default frequency (with a GPS):

3.3V: 7.990 - 8.000 MHz
5.0V: 8.273 - 8.282 MHz

It's interesting that it worked for me at 5V/8.3MHz at 115200 baud but that in your tests it stopped working around 8.1MHz. I wonder why.

The 8.1mhz speed was not precisely measured, it may well have been faster still.

Actually I only checked the transmit side at 3.3V because I didn’t want to add a level shifter.

When I tried again with 5V, varying the clock by tuning OSCCAL0, I got this pattern with hardware serial:

7.6 - 7.9 MHz – fail
8.0 - 8.2 MHz – TX worked, RX didn’t
8.3 - 8.5 MHz – it worked

I’m not sure what that means. But something is wrong with my test so kindly disregard it.

Many thanks for the advice DrAzzy and jboyton. Looks like I'll add a 16mHz crystal into my next 841 board design. I want it to communicate serially with another board I'm messing around with that'll be based on the Robertsonic Wave Trigger design. I could use SoftSerial I suppose, but as one of the advantages of this chip is the two UARTs, I decided why not use them :slight_smile:

By the way, DrAzzy, there doesn't seem to be a link to the site I need to get tattood :slight_smile:

Bernie

Oops :stuck_out_tongue:

http://wormfood.net/avrbaudcalc.php?u2xmode=1

(that one has u2x shown - by default it isn't shown, but Arduino uses it by default)

I made a little more sense of it. One thing I had forgotten to consider is the inherent imprecision of the baud rate generator. The other is that my serial/usb chip is probably also imprecise.

The closest register setting in the '841 @8MHz for 115200 baud results in an actual rate of 111111 baud (assuming 8.000MHz). That's about 3.5% slow. So at 115.2 kbaud it actually makes sense to tune the clock frequency up by increasing OSCCAL0 a little bit.

The setting for 57600 results in a baud rate of 58824, about 2.1% fast. So at 57.6 you're better off tuning OSCCAL0 down a little.

The datasheet recommends a maximum error of only 1%. That would mean you'd want to be within 0.1MHz of the center value. So for 57600 baud that means you'd ideally want the clock frequency to be 7.75-7.91MHz. That's probably something like OSCCAL0 -= 4. At 3.3V.

1% is very conservative - you can normally get away with 3-4% but the lower the baud rate error the better.

OSCCAL0 is not linear, see the graph of it in the datasheet - it's got a huge discontinuity in the middle (or is that another tiny I'm thinking of?)

properly calibrated internal osc is more accurate and reliable than 16mhz xtl for 115kbaud. autobaud in the serial routines instead of rc calibration make it even more practical. however that discontinuity does cause some issues for both. nothing that a couple more lines of code cant fix though.

DrAzzy:
1% is very conservative - you can normally get away with 3-4% but the lower the baud rate error the better.

I didn’t study the datasheet carefully but I believe it has to do with the way the AVR chip samples the incoming data. Could that be why I was able to transmit over a wider range of frequencies than I was able to receive?

DrAzzy:
OSCCAL0 is not linear, see the graph of it in the datasheet - it’s got a huge discontinuity in the middle (or is that another tiny I’m thinking of?)

Most of the AVR chips have that discontinuity but the '841 doesn’t. And there are two other registers that affect the built-in temperature compensation for the oscillator. I think Atmel exposed the raw elements for us to use and didn’t make it user friendly. Actually tuning one of these is an iterative process because OSCTCAL0A and B affect not only the temperature compensation but also the oscillator frequency.

Try to wrap your mind around this:

If you’re patient it’s possible to calibrate the '841 internal oscillator to within 0.1% over a 50°C range. You can’t do that with most of the AVRs. Even out of the box the '841 has really a pretty good temperature curve. It’s a shame this isn’t standard for all of the AVRs.

john1993:
properly calibrated internal osc is more accurate and reliable than 16mhz xtl for 115kbaud.

I realized that as well, that a 16MHz crystal wouldn't be a panacea. It would guarantee a 0.8% error at 57.6kbaud which is easily beaten by calibrating the internal oscillator. And if you don't want to bother with calibration it's likely you'll be nearly as well off with the '841 (at 3.3V) by using the factory default.

john1993:
autobaud in the serial routines instead of rc calibration make it even more practical.

I don't understand this. What do you mean? Are you talking about software serial or what?

autobaud most useful for soft serial but also possible with uart. just involves some restrictions.

16mhz xtl has big advantages where temperature or voltage change and in that case 56kbaud is a great compromise between speed and accuracy. anything around 1% is fine but when you get up to 3-4% then things start to fall apart. i have seen 115k w/16mhz fail in some setups. dont forget errors in the device you are talking to.

too bad arduino didnt standardize on 14.7456mhz or similar baud friendly clock.

you can normally get away with 3-4%

You can usually get away with 4% TOTAL error, but depending on what you're talking to, there can be errors on the other side as well. For example, an ATmega328 Arduino with a 16MHz crystal will be either 3.6% or 2.1% off, depending on whether you use the U2X doublespeed BRG setting. This shows up IRL on the Atmel Xplained Mini boards if you try to run Arduino SW on them. The xx8 target AVR runs with U2X, the 32u4 mEDBG chip used for serial/usb doesn't, and 115200bps fails to work.

Autobaud at the higher speeds using the HW uart isn't going to help too much, because the "steps" between adjacent bitrates are too high :frowning:

true. thats where internal rc and oscal come in handy. autobaud can make use of that or divisors with hard or soft serial assuming baud is low enough. then another advantage of soft serial over uart is 1 clk fine tune ability.

westfw:
You can usually get away with 4% TOTAL error, but depending on what you're talking to, there can be errors on the other side as well.

Wouldn't the theoretical total error be ±5% for a 10 bit character?

The '841 (or '328) datasheet puts the limit on total error at ±3.8% for normal speed mode and +3.2/-3.3 for double speed (10 bits). I think it falls short of 5% because of the granularity of the sampling.

When I tested SoftwareSerial by tuning OSCCAL in a 328 and OSCCAL0 in an '841 I found that it worked (as a receiver) over a ±5% frequency range. That was at 9600 baud. At higher baud rates a software serial approach starts to run into other problems.

Hmmmm, my “new” board design is very similar to my original design (I’m lazy and don’t want to reinvent the wheel!) and I’ve just realised that I’m already using pins PB0 and PB1 so an external oscillator won’t be practical. I’m thinking my course of action is now going to either change the voltage regulator and run the chip from 3.3v, or to tune the internal oscillator.

Bearing in mind that I currently have no idea how to tune an oscillator, it would at first seem my best (read easiest) solution would be to run the 841 from 3.3v - but the snag there is an input from a hall sensor and that sensor needs a Vcc of 3.8v to 24v.

My next question might be best asked in the electronics section of the forum, as its “what is the simplest way to drop the supply from 5v to 3.3v just for the 841”. Alternatively, can anyone (DrAzzy? :blush: ) point me to an idiot’s guide (I’m not kidding about the idiot bit) to tuning the oscillator of an ATtiny841 so I can use hardware serial comms?

Finally - do you think perhaps I ought to use software serial instead?

Bernie

P.S. D’oh!
I definitely will have to ask questions in the electronics section. If I supply the hall sensor with 5v and the Tiny841 with 3.3v then I’ll have to level shift the sensor signal.

Atmel has an app note on the subject of calibrating the internal oscillator. It's AVR054. There is also something called TinyTuner.

Probably the simplest approach is to write a script that sets OSCCAL0 and also sends/receives serial data. Adjust OSCCAL0 up and down to find the limits where it works. You could be super simple and just fix the value in the sketch and recompile for each test. There won't be that many choices that work.

If you wanted to get fancy you could also calibrate the temperature compensation registers for the '841. But it's probably not necessary.

SoftwareSerial or a UART at 57600? I'd only choose the former if I was forced to or just needed to spit out a little debug information. YMMV.