Arduinoのハードウェアシリアルのボーレート誤差

AVR 5V(16MHz)系 (Uno, Mega, Leonardo, Micro, Pro Mini 5V など)

ボーレート設定 実際のボーレート 誤差[%]
9600 9615.4 0.16
19200 19230.8 0.16
38400 38461.5 0.16
57600 58823.5 2.12
115200 117647.1 2.12
230400 222222.2 3.55

基本的には倍速動作で設定されます。倍速動作では8クロックで1ビット、標準動作では16クロックで1ビットとなります。倍速動作は標準動作よりクロックとボーレートの精度要求が厳しいです。

ボーレート57600の場合のみ特別に分周比の計算が異なります。HardwareSerial::begin()のソースのコメントのよると、「Duemilanoveやそれ以前に出荷されたボードのブートローダ、およびUnoやMega 2560上の8U2のファームウェアとの互換性のため」だそうです。倍速動作でボーレート57142.9 (誤差0.79%)に設定可能であるのに、標準動作でボーレート58823.5 (誤差2.12%)に設定しています。

また、ボーレート488以下の場合は倍速動作では設定できないので標準動作で設定されますが、そんな低いボーレートを使うことはあまりないでしょう。

AVR 3.3V(8MHz)系 (Pro Mini 3.3Vなど)

ボーレート設定 実際のボーレート 誤差[%]
9600 9615.4 0.16
19200 19230.8 0.16
38400 38461.5 0.16
57600 58823.5 2.12
115200 111111.1 3.55
230400 250000.0 8.51

AVR 3.3V系はAVR 5V系よりシステムクロック周波数が低いので、通信可能なボーレートの上限も低くなります。ボーレート115200は使えないと言ってよいでしょう。(AVR 3.3V系どうしで通信するなら使えますが。)

基本的には「倍速動作」で設定されます。ボーレート244以下の場合は倍速動作では設定できないので標準動作で設定されますが、そんな低いボーレートを使うことはあまりないでしょう。

SAM(84MHz)系 (DUE)

ボーレート設定 実際のボーレート 誤差[%]
9600 9615.4 0.16
19200 19230.8 0.16
38400 38602.9 0.53
57600 57692.3 0.16
115200 116666.7 1.27
230400 238636.4 3.57

SAM系のHardwareSerial::begin()の実装にはかなり問題があります。ボーレートの分周比が四捨五入でなく切り捨てで計算されているため、誤差が不当に大きくなってしまう場合があります。Arduino SAM Boards バージョン1.6.12で確認しました。

SAMはシステムクロック周波数が高いため、115200以下の一般的なボーレートではほぼ問題になりませんが、115200を超える高いボーレートを設定したい場合には問題になる場合があります。例えば、ボーレート230400に設定したい場合、228260.9(誤差0.93%)に設定できるにもかかわらず、238636.4(誤差3.57%)に設定されてしまいます。

苦し紛れですが、下記のような関数を使って四捨五入計算相当のボーレートを設定することができます。

#include <stdint.h>

uint32_t SAM_BAUD_FIX(uint32_t baud) {
  uint32_t ret = (uint32_t)(
    (double)SystemCoreClock * (double)baud / (double)(SystemCoreClock + 8*baud)
  );
  return ret;
}

void setup() {
  Serial1.begin(SAM_BAUD_FIX(230400));
}