レベル変換 (1) UART その1 初期電圧を調べる

 電子工作で利用するマイコンの電源電圧は5Vが主流でした。現在は3.3Vが主流ですが、業務用などでは1.8Vが使われています。センサの多くは3.3Vと5Vで使えます。しかし、デバイスの開発では、より消費電力を少なくするために3.3V以下が増えています。

 したがって、5Vと3.3Vの信号の行き来は日常的に行われます。検索するとたくさんのレベル変換回路やICが見つかります。ここでは、Arduino UNOを中心にその機能にあった電圧レベル変換を考えて、実験をします。

UART(調歩同期式シリアル通信)

 この十年で、コンピュータの外部との通信のほとんどはシリアル通信になりました。IBM-PC/ATが出たころは、ほとんどがパラレル通信で、シリアル通信はUARTを使った調歩同期式シリアル通信だけでした。S=Synchronous が機能として搭載されているので、USARTという呼び名もあります。物理層はRS-232Cです。この呼称は1990年代の遺物で、あくまでも通称です。IBM-PC/ATが出てくるまではD-SUB 25ピンのコネクタが使われ、その後D-SUB 9ピンのほうが一般的になりました。
 この調歩同期式シリアル通信は、多くはモデムとの接続に利用されていました。送信Txと受信Rx以外に制御信号DTR(データ端末レディ)、DSR(データ・セット・レディ)、RTS( 送信リクエスト)、CTS(送信可)なども併用され、電圧レベルは「マーク」1は-3~-15V、「スペース」0は+3V~+15Vです。

 いま、UARTといったときの電圧レベルはTTLレベルと呼称され、マークが5V、スペースは0Vです。TTLは74xxというロジックICの呼び名ですが、その後3.3Vで動作させるCMOSロジックICもなし崩し的にTTLレベルという表現が多く使われています。

 調歩同期式は非同期式とも呼ばれます。信号はスタート・ビットから始まります。TTLレベルでは0Vです。つまり、マーク状態5V->0Vになった時点でスタート・ビットが送られてきたかどうかをその速度分のパルス幅の中央あたりのレベルを見て判断します。その後の信号は正論理です。通常データは8ビットもしくは7ビットです。そのあとパリティ・ビットがあったりなかったり、最後はストップ・ビットで、5Vにします。この長さが1ビット分もしくは2ビット分あれば1文字を送り終えたことになります。そして、スタート・ビットを待ちます。

 断線を検知する目的かどうかは定かではありませんが、Tx/Rxのデフォルトはマークの5Vに設定します。ここで調べたマイコン・ボードは、すべてがそうではありませんでした。次の表に、初期状態を調べた結果をまとめました。

Arduino UNO SoftwareSerial
10番Rx=5V、11番Tx=5V

Spresense

(I/OはプルアップされているのでデフォルトHigh。リセット直後に約200ms間Lowになる端子もある)

Serial2
5V電源;0番Rx=5V、1番Tx=5V
3.3V電源;0番=3.3V、1番=3.3V
SoftwareSerial
5V電源;10番Rx=5V、11番Tx=5V
3.3V電源;10番=3.3V、11番=3.3V
Raspberry Pi 10番Rx=3.3V、8番Tx=3.3V
Trinket M0 3番Rx=0V、4番Tx=3.3V
ESP32(DevKitC) UART0
RxD0=3.3V、TxD0=3.3V
UART2
16番Rx=0V、17番Tx=3.3V

  (※)電源電圧が5Vは、Arduino UNOとSpresenseを5V設定にしたときの二つです。残りは3.3Vで動作しています。
 (※)Spresenseの拡張ボードに使われているレベル変換ICは5Vトレラントです。電源を3.3Vで使っているときにI/Oに5Vの信号が入っても正常に動作します。ほかのマイコン・ボードはそうではありません。
 (※)受信データを表す記号にRx RxD RXD RDが、送信データを表す記号にTx TxD TXD SDなどが使われます。

Arduino UNOのスケッチ

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
Serial.begin(9600);
Serial.println("Goodnight moon!");
mySerial.begin(9600);
mySerial.println(" Good Morning!");
}

void loop() { // run over and over
mySerial.println("A");
}

Spresenseのスケッチ

void setup() {
Serial.begin(9600);
Serial.println("Goodnight moon!");
Serial2.begin(9600);
Serial2.println(" Good Morning!");
}

void loop() { 
}

Trinket M0のmain.py

import board
import busio
import digitalio
uart = busio.UART(board.TX, board.RX, baudrate=9600)

while True:
print("a")
uart.write("A")

ラズパイ

 カーネルは4.14.72(2018/09/27現在)です。
 メイン・メニューの設定からRaspberry Piの設定-インターフェイスのタブを選び、SerialPortを有効にします。リブート後に/boot/config.txtをsudo nanoで開くと、最下行にenable_uart=1が追加されています。この下の行に、dtoverlay=pi3-miniuart-btを追加して、CTRL+oで書き込み、CTRL+xで抜け、rebootします。

 ラズパイ3、Raspberry Pi Zero WなどではBluetoothが搭載されていて、デフォルトで有効になっている代わりに、GPIO14/15のTxD/RxDが使えなくなっています。/boot/overlay/READMEに書かれているように、デバイス・ドライバpi3-miniuart-btの記述を追加します。Bluetoothは使えなくなり、/dev/ttyAMA0および/dev/serial0のUARTが有効になります。

import serial

con=serial.Serial('/dev/ttyAMA0', 9600, timeout=10)
while 1:
con.write("A")
print (con.read())

ESP32のスケッチ

 デフォルトのUART0はSerial.println()の出力先になります。UART1とUART2が最初から利用できますが、UART1は内部のSPIインターフェースに使われているので、ピンの設定を変えないと使えません。

HardwareSerial mySerial(2); // UART2 16-Rx,17-Tx

void setup() {
Serial.begin(9600);
mySerial.begin(9600);
}

void loop() {
}

コラム Arduino UNOのUART

 0番(Rx;受信端子)、1番(Tx;送信端子)に、マイコンATmega328の周辺モジュールUSARTのピンが直接出ています。この2本のラインは、USB-シリアル変換をするATMEGA16U2につながっているため、シリアルモニタを利用したとき、信号がぶつかります。

 そのため、シリアルモニタに何かを表示しながらUARTと使うときは、SoftwareSerialを使います。10と11番ピンがサンプルで使われていますが、ほかのポートも利用できます。すべてのピンが指定できるわけではないので事前に確認が必要です。

前へ

SpresenseでLチカから始める (21) 距離TFmini

次へ

レベル変換 (2) UART その2 Arduino UNOから送信-1