RS485によるマイコン間シリアル通信（調歩同期式）

# 概要
マイコン間でシリアル通信をしようとした場合TTLレベルのUARTだと距離が稼げないため、
RS485を介しての接続をテストしてみました。RS485変換モジュールはAmazonで良さそうな物を
購入。ピンヘッダ取り付けもできます。また、R0を短絡させることで終端抵抗120Ωを

有効化できるようです。今回は短距離でのテストなのでそのまま使用しています。
参考URL:https://amzn.asia/d/gSz5IeJ
　


![スクリーンショット 2023-04-26 110037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611426/06d630f6-aaf6-ddd7-1f1d-f523dc49a720.png)



# 環境
エディタ：VisualStudioCode（拡張機能：PlatformIO IDE）
マスター側マイコン：Waveshare RP2040-LCD-0.96
スレーブ側マイコン：Seeed Studio XIAO RP2040
UART-RS485変換モジュール：Amazonで2個セットで購入　https://amzn.asia/d/4MgxBio


マスター側にはLCD表示関連で2つのライブラリを追加しています。
　1.　U8g2_for_Adafruit_GFX
　2.　Adafruit ST7735 and ST7789 Library

# 回路図
![スクリーンショット 2023-04-26 124406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611426/7f69d4f9-fc2f-da8d-161f-6acfd33cf7ee.png)


# プログラム概要
　1.マスター側でスイッチを押すとスレーブ側へ文字列"ID01"を送信します。
　2.スレーブ側では"ID01"文字列を受信すると文字列"ID01 Count: *"を送信します。
　3.マスター側でスレーブ側より受信した文字列をLCDに表示します。

## マスター側プログラム
``` cpp
#include <Arduino.h>
#include <Adafruit_ST7735.h>
#include <U8g2_for_Adafruit_GFX.h>

  String serial1_data;
  String msg;
  int sw1=2;

  //ディスプレイ設定
  #define TFT_DC      8   // DC
  #define TFT_CS      9   // CS
  #define TFT_SCLK    10  // Clock
  #define TFT_MOSI    11  // MOSI
  #define TFT_RST     12  // Reset 
  Adafruit_ST7735 tft = Adafruit_ST7735(&SPI1, TFT_CS, TFT_DC, TFT_RST);
  U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;


//ディスプレイ表示処理
void disp()
{
  u8g2_for_adafruit_gfx.setCursor(2, 12);
  u8g2_for_adafruit_gfx.print("RS485_SerialTest");
  u8g2_for_adafruit_gfx.setCursor(2, 24);
  u8g2_for_adafruit_gfx.print("recv: "+serial1_data);         
  u8g2_for_adafruit_gfx.setCursor(2, 48);
  u8g2_for_adafruit_gfx.print("msg: "+msg);                       

}

void setup() {
  Serial1.begin(9600); //UART0初期化
  //スイッチ入力ピンセット
  pinMode(sw1,INPUT_PULLUP);//Select

  //LCD初期化
    SPI1.setTX(TFT_MOSI);                       //H/W SPI 設定
    SPI1.setSCK(TFT_SCLK);
    tft.initR(INITR_GREENTAB);
    tft.initR(INITR_MINI160x80);                //Init ST7735S初期化
    tft.invertDisplay(true);
    tft.setRotation(3);
    tft.fillScreen(ST77XX_BLACK);
    u8g2_for_adafruit_gfx.begin(tft);
    //u8g2_for_adafruit_gfx.setFont(u8g2_font_b12_t_japanese1);
    //u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_japanese2);
    u8g2_for_adafruit_gfx.setFont(u8g2_font_t0_14_me);
    u8g2_for_adafruit_gfx.setFontMode(0);                 // use u8g2 none transparent mode
    u8g2_for_adafruit_gfx.setFontDirection(0);            // left to right (this is default)
    u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_YELLOW);      // apply Adafruit GFX color

   disp();//ディスプレイ表示
}

void loop() {
  if(digitalRead(sw1)==0){
    delay(50);//チャタリング防止
    while (digitalRead(sw1)==0){}//SWが離されるのを待つ
    delay(50);//チャタリング防止
    Serial1.println("ID01");
    msg="send";
    disp();
  }

  //スレーブーからのシリアル受信チェック
  if (Serial1.available() > 0) {
    serial1_data = Serial1.readStringUntil('\n'); //デリミタを検出したら終了
    msg="recv";
    disp();//ディスプレイ表示
    
   }
}
```

## スレーブ側プログラム
``` cpp
#include <Arduino.h>

String serial1_data;
int count=0;

void setup() {
  Serial1.begin(9600); //UART0初期化
}

void loop() {
  //マスターからのシリアル受信チェック
  if (Serial1.available() > 0) {
    serial1_data = Serial1.readStringUntil('\n'); //デリミタを検出したら終了
    if(serial1_data="ID01")
    {
      //マスターへデータ送信
      Serial1.println("ID01 Count: "+String(count));
      count++;
    }    
   }
}
```

# 通信速度について

今回購入したボードの説明に「ボーレート：110～256000bps」となっていたので、
レートを変えて送受信に掛かる時間を測定してみました。256kbpsとすることでかなり改善しています。
256kbps以上を設定しても変化が無かったので256kbpsが上限でしょうか。
念のためRS485ボードを除いてマイコン同士をUART接続で確認してみましたが結果は同じ。
ということはマイコンのUART上限が256kbpsということかな・・（ライブラリの制限なのかな？）。

　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611426/58eba877-281a-be57-7f01-365f9b4bd756.png)