ゆるく楽しむプログラミング

シリアル通信

RX(D0)-TX(D1)とTX(D1)-TX(D0)を相互に接続する事でシリアル通信が行えます。
※GNDの接続を忘れずに。

シリアル通信はSerialクラスを使用します。
接続された相互で通信速度を合わせておく必要があります。
初期化  Serial.begin(speed)  シリアル通信のデータ転送レートをbps(ビット/秒)で指定
300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200
のレートから1つを選ぶ。 
終了  Serial.end()  シリアル通信を終了し、RX(D0)とTX(D1)を汎用の入出力ピンとして使えるようにする
テキスト送信  Serial.print(data, format)  テキスト(文字)データをシリアルポートへ出力 
テキスト送信(改行)  Serial.println(data, format)  テキストデータの末尾に改行コード("\r\n")付けてシリアルポートへ出力 
バイナリデータ送信  Serial.write(val)
Serial.write(str)
Serial.write(buf, len) 
シリアルポートにバイナリデータを出力
1バイト、または複数バイトの送信が可能 
受信可能バイト数の取得  Serial.available()  シリアルポートの受信バッファに格納されているバイト数を返す
バッファは64バイト 
受信バッファ読み取り  Serial.read()  読み込み可能なデータの最初の1バイトを返す。
データが存在しない場合は-1を返す 

送受信スケッチ例

普段はシリアルモニターに表示している情報を、美咲フォントで作成した回路でOLEDに表示してみます。


ATMega328をつかったOLED SSD1306+EEPROM(美咲フォント)の接続図


ArduinoIDEを使用する場合、漢字はUTF-8で扱われます。
UTF-8は1バイト目で2バイト文字なのか3バイト文字なのかを判別できるので、必ず漢字1文字分は受信してから美咲フォント表示クラスを呼ぶ。
※美咲フォント表示はフォントパターン読み出し時にUTF-8からUTF-16にコード変換を行っているので、正しいUTF-8コードを渡さないとバグります。

SelealMonitor.zip
EEPROM版 美咲フォントROMが必要です。
※ <>を全角<>に置き換えています。コピペの際は注意してください。

// シリアルモニター

#include <Wire.h>
#include "readFont.h"
#include "ssd1306SPI.h"

SSD1306SPI ssd1306spi ;
extern READFONT readFont ;

uint8_t str[68] ;
int inputLen = 0 ;

void setup (void)
{
  Wire.begin() ;        // EEPROM用I2C通信初期化
  ssd1306spi.init( ) ;  // OLEDの初期化

  // シリアル通信初期化:9600bpsに設定
  Serial.begin(9600);
  while(!Serial) ;  // シリアル通信の準備が終わるまでWait

  ssd1306spi.cls( ) ;
  ssd1306spi.Println(">Seleal Monitor") ;

  memset(str,0,sizeof(str)) ;
}

void loop (void) {
  while(Serial.available() > 0) {
    uint8_t charData = Serial.read();
    if (charData == 0x0C) {
      // 画面クリア
      ssd1306spi.cls( ) ;
    } else
    if (charData == '\r') {
      // 改行 CR LF の内、LFは無視する
    } else
    if (charData == '\n') {
      // 改行
      ssd1306spi.Print(str) ;
      ssd1306spi.PrintCR() ;
      inputLen = 0 ;
      str[inputLen] = 0 ;
    } else {
      str[inputLen] = charData ;
      inputLen ++ ;
      str[inputLen] = 0 ;
      // 漢字の場合、2~3バイト目を受信する
      int charLen = readFont.UTF8LEN(str);
      while(charLen > inputLen) {
        if (Serial.available() > 0) {
          charData = Serial.read();
          str[inputLen] = charData ;
          inputLen ++ ;
          str[inputLen] = 0 ;
        }
      }
    }
    if (inputLen >= 60) {
      // ある程度受信したら一回書き出してバッファを空にする
      ssd1306spi.Print(str) ;
      inputLen = 0 ;
      str[inputLen] = 0 ;
    }
  }
}

解説動画