はじめに
Spresense向けに提供されている、クレスコデジタルテクノロジー製 ELTRESアドオンボードと、ROHM製 Wi-SUN モジュールは、どちらもUARTポートを使用するため、同時に利用することができません。
以上のように、2つのボード/モジュールは同じポート(UART)を利用するため、そのままでは同時に利用することができません。
そのため、ELTRESとWi-SUNを同時にしたものを製作しようとしているため、まず、この2つのボード/モジュールを同時に使用する方法を検討しました。
UART ポートを増やす方法
どちらの基板も、Spresense基板の、GNSS Antenna側のピンを利用します。写真で言う右側のピンは空いています。こちらにある信号で、外部デバイスとの通信に使えるものは、I2Cになります。
I2CをUARTに変換することで、2つのデバイスを同時に使うことができます。
I2CとUARTを変換するデバイスとしてよく使われるものに、SC16IS740 / 750があります。今回はこのデバイスを利用します。
今回は、このデバイスが搭載されている、スイッチサイエンスで販売されている基板を利用します。
次に、ELTRESとWi-SUN どちらをI2C経由にするか、を検討します。
どちらもモジュール/ボードにも、メーカーからライブラリが提供されています。今回作ろうとしている製作品は、ELTRES / Wi-SUN どちらの通信も利用します。ライブラリをどちらがそのままで利用できるか、という観点で比較をしました。Wi-SUNは、通信する内容を多く実装する必要があり、ELTRESはライブラリをそのままで必要な通信が実行できそうです。また、Wi-SUNの通信モジュール BP35C0 は、通信のためのコマンドが公開されています。そのため、Wi-SUN モジュールをI2C経由で操作することとしました。
モジュール間の接続
スイッチサイエンスで販売されている基板は、Spresense側 (MPU側)と、Wi-SUN側 (DEVICE側) どちらも、Groveコネクタで接続することができます。
そのため、Spresense側、Wi-SUNモジュール側 どちらにも、Groveコネクタを設置し、接続に必要となる変換回路を実装しました
SpresenseのI/O電圧は、1.8Vです。I2C - UART基板が3.3Vで動作するため、レベル変換をする必要があります。レベル変換は、秋月電子通商から販売されている、I2Cバス用双方向電圧レベル変換モジュール
を利用しました。
Spresenseに直接接続できるモジュールのため、I/Oの電圧が1.8Vになるように回路が組まれています。そのため、こちらの基板にも、秋月電子通商から販売されている、I2Cバス用双方向電圧レベル変換モジュール
を利用し、信号レベルの変換をしています。また、1.8VのLDOで、通信用電圧のリファレンスを作っています。
この2つの変換基板と、I2C-UART基板を接続します。
SC16IS740の利用方法
SC16IS740は、I2Cデバイスなので、ArduinoのWireライブラリを経由して利用します。
SC16IS740の初期化
#define SC16IS740_ADDR (0x48)
// SC16IS740 Register
const uint8_t THR = (0x00 << 3);
const uint8_t RHR = (0x00 << 3);
const uint8_t FCR = (0x02 << 3);
const uint8_t LCR = (0x03 << 3);
const uint8_t MCR = (0x04 << 3);
const uint8_t LSR = (0x05 << 3);
const uint8_t RXLVL = (0x09 << 3);
// special register set
const uint8_t DLL = (0x00 << 3);
const uint8_t DLH = (0x01 << 3);
// enhanced register set
const uint8_t EFR = (0x02 << 3);
void setup_sc16is740()
{
// Wire.begin(); は、setup()内で事前にしておく
// Initialize SC16IS740
// dividor latch enabled
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(LCR);
Wire.write(0x83);
Wire.endTransmission();
// set Baud Rate
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(DLL); // the least significant part
Wire.write(24);
Wire.endTransmission();
// set Baud Rate
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(DLH); // the most significant part
Wire.write(0x0);
Wire.endTransmission();
// divisor latch disabled
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(LCR);
Wire.write(0x03);
Wire.endTransmission();
// reset TX and RX FIFO, enable the transmit and receive FIFO
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(FCR);
Wire.write(0x07);
Wire.endTransmission();
}
UARTへの送信
void send_to_uart(uint8_t data)
{
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(THR);
Wire.write(data);
Wire.endTransmission();
}
UARTからの受信
String recieve_from_uart()
{
uint8_t i, n, data;
String retValue = "";
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(LSR);
Wire.endTransmission();
Wire.requestFrom(SC16IS740_ADDR, (uint8_t)1);
data = Wire.read();
if (data == 0x61)
{ // at least one character in the RX FIFO
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(RXLVL);
Wire.endTransmission();
Wire.requestFrom(SC16IS740_ADDR, (uint8_t)1);
n = Wire.read(); //読み込むデータの数
Wire.beginTransmission(SC16IS740_ADDR);
Wire.write(RHR);
Wire.endTransmission();
Wire.requestFrom(SC16IS740_ADDR, (uint8_t)n);
for (i = 0; i < n; i++)
{
retValue += Wire.read();
}
}
}
まとめ
UARTデバイス2つを同時にSpresenseから通信することができました。この方法を利用して、製作品の制作を進めようと思います。
-
haruka
さんが
2022/09/23
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する