JUGEMテーマ:電子工作

有線のリモコンとかで使えそうな技術の検証です。
1対1の通信で大丈夫なので、RS485はオーバースペックなんですが、
RS485で実現しておけば、他にも1対多とか多対多とかでも
応用効きそうなので、実験しておきました。
 


今回使用するのはLTC485CN8です。
データシート 
 https://www.mouser.jp/datasheet/2/609/485fm-2955265.pdf

 

 電源電圧は5Vで動く。
 +14V~-14Vまでバスに電圧かかってもOK
 出力はVCCが基準になるって事ですね。
 あと、RS485らしく、終端抵抗の事とか書いてるなー
 
という訳で、ARDUINOとARDUINO互換機の5V版で試験をする。
 
写真
 

 
 
左下がARDUINO-UNOで、これがマスターです。
左上がUNO互換機で、これがスレーブです。
 
で、マスターから送信するときの伝送経路
 UNO→LTC485→LAN線→LTC485→UNO互換機
 
で、マスターが受信するときの伝送経路
 UNO互換機→LTC485→LAN線→LTC485→UNO
 
となり、
シーケンス図を書くとこんな感じです。

 
間にあるLAN線の長さが7メートルになっております。
 
■回路図
 

 
 
UNO→LTC485→LAN線 が2セットになるので、
片方だけ書きましたが、
間の接続はAはAにBはBに接続します。
 
■プログラム
 
プログラムはD13を使ってLTC485のREとDEに接続してあるので、
送信時にHIGHにします。
あとは、普通にSoftSerialですので、
比較的手軽に通信できるみたいです。
 
1対多に対応する場合はマスターを一つ置いておいて、
マスターさんがスレーブさんの送信権管理して、
1本しかない物理ケーブルの時間割をしてあげればいいと思います。
 
多対多に対応する場合はスレーブ同士での通信が必要になると思いますが、
この場合でもやっぱマスターさんがうまく
1本しかない物理ケーブルの時間割をしてあげればいいと思います。
 

□マスター側プログラム


#include <SoftwareSerial.h>
 SoftwareSerial mySerial(2, 3);    // RX,TX
 
 int txden = 13;
 
 void setup(){
   pinMode( txden, OUTPUT );
  
   Serial.begin(115200);
   mySerial.begin(9600);
   digitalWrite(txden, LOW);

   Serial.println("start:");
 
}

int count = 0;

void loop(){
  char buf[256];
  digitalWrite(txden, HIGH);
  sprintf(buf, "com4 write %d¥r¥n", count);
  mySerial.print(buf);
  Serial.println("point : A000");
  delay(10);//送信が終わるまで待つ
  digitalWrite(txden, LOW);
  count++;
  //
  unsigned long t1 = millis();
  while(1){
    unsigned long t2 = millis();
    if((t2-t1)>3000){
      t1 = t2;
      break;
    }
    if(mySerial.available()>0){
      Serial.println("point : A100");
      memset(buf, '¥0', sizeof(buf));
      int i = 0;
      while(mySerial.available()>0){
        char val = mySerial.read();       // 受信したデータを読み込む
        buf[i]=val;
        i=i+1;
        if(val=='¥n'){
          break;
        }
        delay(10);
      }
      Serial.println(buf);
      break;
    }
 }


□スレーブ側プログラム

 

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);    // RX,TX
 
int txden = 13;
 
void setup(){
   pinMode( txden, OUTPUT );
  
   Serial.begin(115200);
   mySerial.begin(9600);            
   digitalWrite(txden, LOW);

   Serial.println("start:");
 
}

 int count = 0;
 unsigned long t1 = 0;
 void loop(){
  int nDataExist = 0;
  if(mySerial.available()>0){
    while(mySerial.available()>0){
     int val = mySerial.read();       // 受信したデータを読み込む
     Serial.write(val);
     nDataExist = 1;
     delay(10);
    }
  }
  //
  if(nDataExist == 1){
    Serial.println("point : 100");
    char buf[256];
    digitalWrite(txden, HIGH);
    sprintf(buf, "ack %d¥r¥n", count);
    mySerial.print(buf);
    delay(10);//送信が終わるまで待つ
    digitalWrite(txden, LOW);
    count++;
  }
}

 

■実験結果
 
オシロで取得した差動信号の模様
 

 
思うようにできているみたいですね。
AとBで±逆側に信号が出ています。
試しに7メートルのケーブルはそのままで、
UARTで直結したところ、まったく通信できませんでしたので、
こんな時はRS485が役に立ってくれそうです。
通信速度ですが、今回9600bps設定にして上のサンプルのままで、
電文が100回往復する時間を測定したところ、24秒かかっておりますので、
1回あたりだと、0.24秒です。
電気のリモコンならボタンを押して電気がつくまで0.24秒かかる事になりますが、
ま、こんなもんなのかな?
通信速度9600bpsを早くしていけばそれなりに速度は上がるとも思いますし、
応用次第ですね。
 
ちなみに、終端抵抗は無しでやってます。
 

 

 


JUGEMテーマ:Arduino