フォト
2018年6月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
無料ブログはココログ

« 豊四季Tiny BASIC for micro:bit をV0.07に更新しました | トップページ | 豊四季Tiny BASIC for ArduinoのSRAM消費軽減対応 »

2018年2月 7日 (水)

micro:bitをArduino環境で使う (7) シリアル通信

micro:bitではハードウェアシリアル通信ポートが1つ利用出来ます。

Arduino環境で利用する場合、USB経由のシリアル通信専用に割り付けれています。

具体的にはポート21、22に割り付けられていているのですが、このポートは
外部端子には接続されていせん。

しかし、ハードウェア的にmicro:bitではシリアル通信ポートを任意の外部端子に
割り付けることが出来ます。

Arduino環境でも任意のポートに割り付けられないかとやってみました。
まずは、Serialインスタンスを実装しているUartクラスを使って試してみます。

スケッチ(注意:このスケッチはダメだったケースです)
//
// micro:bit シリアルポートの利用
// 任意のポートを使ってシリアル通信を行う
//

#define Rxpin 12         // シリアル RxDピン(任意指定可能)
#define Txpin 13         // シリアル TxDピン(任意指定可能)
#define baudRate 9216000 // 通信速度(1200 ~ 921600bps)

// Uartインスタンスの生成
Uart Serial2(NRF_UART0, UART0_IRQn, Rxpin, Txpin); 
//extern "C"  void UART0_IRQHandler() {  Serial2.IrqHandler(); };

void setup() {
  Serial2.begin(baudRate); // 通信開始
}

void loop() {
  Serial2.println("Hello,world");
  delay(1000);
}

上記の例では、Uartクラスを使ってデフォルトのSerialオブジェクトとは
別のインスタンスを生成しています。
インスタンス生成時に利用するポートを指定することが出来ます。

外部端子を使う利点として、通信速度に115200以上の指定が可能です。
(USB経由だと115200までしか利用出来ない)

試しに、上限の921600bpsを指定してみると、TeraTermにで問題なく出力できました。
(パソコンに接続にはUSB-Serialモジュールを利用しています)

送信については、任意のポートに割り付けて利用することが出来ました。

01

ところが、受信処理を実装するとデータ受信を行うことが出来ません。
問題点を調べると、
シリアル受信を行うコールバック関数(割り込み処理)が
デフォルトのSerialインスタンスに固定されています。

Uart.cpp
extern "C"

{
  void UART0_IRQHandler()
  {
    Serial.IrqHandler();
  }
}

Arduinoのコア部分で上記のように固定されており、
これを修正することが出来ません。
本来ならば
  Serial.IrqHandler();

  Serial2.IrqHandler();
に変更しないといけません。

IrqHandler()の実体は下記のようになっており、
Serialインスタンスのリングバッファにデータを格納しています。
これでは、後から生成したSerail2インスタンスでのデータ受信を行うことが出来ません。


void Uart::IrqHandler()
{
  if (nrfUart->EVENTS_RXDRDY)
  {
    rxBuffer.store_char(nrfUart->RXD);
    nrfUart->EVENTS_RXDRDY = 0x0UL;
  }
}

この方法は諦めて、Arduino環境のUart.h、Uart.cppに修正を入れることにしました。
ポート設定を行うメンバー関数setPort()を追加しました。

Uart.hの修正:下記の2つのメンバー関数の宣言の追加

// <-- add by Tamakichi 2018/02/07
    void setPort(uint8_t _pinRX, uint8_t _pinTX);
    void setPort(uint8_t _pinRX, uint8_t _pinTX, uint8_t _pinCTS, uint8_t _pinRTS );
// -->>     

Uart.cppの修正:下記の2つのメンバー関数の本体の追加

// <-- add by Tamakichi 2018/02/07
void Uart::setPort(uint8_t _pinRX, uint8_t _pinTX)
{
  uc_pinRX = g_ADigitalPinMap[_pinRX];
  uc_pinTX = g_ADigitalPinMap[_pinTX];
  uc_hwFlow = 0;
}

void Uart::setPort(uint8_t _pinRX, uint8_t _pinTX, uint8_t _pinCTS, uint8_t _pinRTS)
{
  uc_pinRX = g_ADigitalPinMap[_pinRX];
  uc_pinTX = g_ADigitalPinMap[_pinTX];
  uc_pinCTS = g_ADigitalPinMap[_pinCTS];
  uc_pinRTS = g_ADigitalPinMap[_pinRTS];
  uc_hwFlow = 1;
}
// -->>

この追加したメンバー関数を利用したスケッチ

//
// micro:bit シリアルポートの利用
// 任意のポートを使ってシリアル通信を行う
// 本スケッチはArduinoのUart.h、Uart.cppの修正が必要
//

#define Rxpin 12         // シリアル RxDピン(任意指定可能)
#define Txpin 13         // シリアル TxDピン(任意指定可能)
#define baudRate 9216000 // 通信速度(1200 ~ 921600bps)

void setup() {
  Serial.setPort(Rxpin, Txpin);
  Serial.begin(baudRate); // 通信開始
  Serial.println("Hello,world");
}

void loop() {
  if (Serial.available()) {
    Serial.write(Serial.read());
  }
}

実行結果

02

これで、とりあえずは任意のポートを利用した送受信を行うことが出来ました。
ただし、Arduino環境に修正を加える必要があります。

2018/5/11 追記

シリアル通信のためのUart.h、Uart.cppの修正、もっと簡単な方法で修正出来ました。
Uart.hの中で
#define ARDUINO_GENERIC
を追記することで、追加した関数と同等のsetPins()が有効になります。

#include <nrf.h>

#include "HardwareSerial.h"
#include "RingBuffer.h"

#include <cstddef>
// <-- add by Tamakichi 2018/05/06
#define ARDUINO_GENERIC
// -->
class Uart : public HardwareSerial
{
  public:
    Uart(NRF_UART_Type *_nrfUart, IRQn_Type _IRQn, uint8_t _pinRX, uint8_t _pinTX);
    Uart(NRF_UART_Type *_nrfUart, IRQn_Type _IRQn, uint8_t _pinRX, uint8_t _pinTX, uint8_t _pinCTS, uint8_t _pinRTS );
#ifdef ARDUINO_GENERIC
    void setPins(uint8_t _pinRX, uint8_t _pinTX);
    void setPins(uint8_t _pinRX, uint8_t _pinTX, uint8_t _pinCTS, uint8_t _pinRTS);
#endif // ARDUINO_GENERIC

« 豊四季Tiny BASIC for micro:bit をV0.07に更新しました | トップページ | 豊四季Tiny BASIC for ArduinoのSRAM消費軽減対応 »

arduino」カテゴリの記事

ARM」カテゴリの記事

micro:bit」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/66365351

この記事へのトラックバック一覧です: micro:bitをArduino環境で使う (7) シリアル通信:

« 豊四季Tiny BASIC for micro:bit をV0.07に更新しました | トップページ | 豊四季Tiny BASIC for ArduinoのSRAM消費軽減対応 »