16芯 配線チェッカー試作版 RS-485 バージョン 2020/11/06
配線の端末側から電線を識別する「配線対照機」で、極性なし、コモン線も不要です。
電線 16 本だけでなく、うまく使えば離れたところからケーブル 8 本の識別も可能です。
RS-485 通信を使っているので、数100m 離れたところでも識別可能と思われます。
TTL/RS-485 モジュールは、現場でも安定、安心して使えるように絶縁型を使用しています。
※RS-485 は基本的に「活線挿抜」禁止なので、こういう使い方が大丈夫なのか・・・は不明。
■送信側
配線をチェックする電線(最大 16 本)を接続します。(活線では使用できません)
※写真↑には 4 桁 LED がありますが、速度アップのために省いています。
■受信側
チェックする配線のうち2本を接続します。
識別番号(1~16)が、A+側、B- 側の順で表示されます。同時にブザーがピッと鳴ります。
表示されるタイミングは RS-485 9600bps の場合、1.5 秒に 1 回程度です。
19200bps にすればもう少し速くなります。
■弱点
配線抵抗が 1kΩ程度でも通信できてしまうので、確実につながっているとは判断できない。
また、他の配線と 3kΩ程度以下で接続されている場合、短絡と判断される。
■仕組み
16 本のうちどれか 2 本を選んで RS-485 で識別番号を送信します。これを総当たりで行います。
配線の切り換えは、リードリレー 16 個 × 2 組と I2C I/Oエキスパンダ(16 点用)を使っています。
同じ配線の組み合わせで 2 回チェック(2 回目は極性反転)しているため、時間がかかています。
受信側は、単に RS-485 で受信した識別番号を表示させているだけです。
送信、受信とも非常にシンプルです。
■接続図
接続図(PDF)は、こちらです。
// ********************************* // 送信側 Arduino nano // ********************************* /* 16 芯配線チェッカー RS-485 版 送信側 * I/O エキスパンダ MCP23108 2個を使ってリードリレー16個 × 2 を切り換え、総あたりで線番を RS-485 送信 * 2020/11/06 */ #include "Wire.h"; // MCP23108 No.1 const uint8_t ADDR1 = 0x20; // address 0x20 (ADDR to GND) // MCP23108 No.2 const uint8_t ADDR2 = 0x27; // address 0x27 (ADDR to VCC) #define LED 7 // 動作中点滅 #define DERE 2 // rs-485 ED/~RE void setup() { Serial.begin(9600); // for RS-485 Wire.begin(); // MCP23108 No.1 Wire.beginTransmission(ADDR1); Wire.write(0x00); // port-A i/o direction register Wire.write(0x00); // 0=output, 1=input Wire.endTransmission(); Wire.beginTransmission(ADDR1); Wire.write(0x01); // port-B i/o direction register Wire.write(0x00); // 0=output, 1=input Wire.endTransmission(); // MCP23108 No.2 Wire.beginTransmission(ADDR2); Wire.write(0x00); // port-A i/o direction register Wire.write(0x00); // 0=output, 1=input Wire.endTransmission(); Wire.beginTransmission(ADDR2); Wire.write(0x01); // port-B i/o direction register Wire.write(0x00); // 0=output, 1=input Wire.endTransmission(); pinMode(DERE, OUTPUT); // RS-485 H= 送信,L= 送信 digitalWrite(DERE, HIGH); // RS-485 常に送信 pinMode(LED, OUTPUT); // LED digitalWrite(LED, HIGH); // LED } void loop() { char hex[17] = "0123456789ABCDEF"; int a, b, c, d; // 全数チェック for (int i = 0; i <= 15; i++){ digitalWrite(LED, !digitalRead(LED)); // LED 点滅 if (i < 8){ a = 1 << i; b = 0; } else { a = 0; b = 1 << (i - 8); } // No.1 リレー切替 Wire.beginTransmission(ADDR1); Wire.write(0x12); // NOT(~) で反転: 1 = ON(LOW), 0 = OFF(HIGH) Wire.write(~a); Wire.endTransmission(); // out B Wire.beginTransmission(ADDR1); Wire.write(0x13); //talk to GPIOB register // Active LOW なので NOT(~) で反転: 1 = ON(LOW), 0 = OFF(HIGH) Wire.write(~b); Wire.endTransmission(); for (int j = 0; j <= 15; j++){ if (i != j){ if (j < 8){ c = 1 << j; d = 0; } else { c = 0; d = 1 << (j - 8); } // No.2 リレー切替 Wire.beginTransmission(ADDR2); Wire.write(0x12); // NOT(~) で反転: 1 = ON(LOW), 0 = OFF(HIGH) Wire.write(~c); Wire.endTransmission(); // out B Wire.beginTransmission(ADDR2); Wire.write(0x13); //talk to GPIOB register // NOT(~) で反転:1 = ON(LOW), 0 = OFF(HIGH) Wire.write(~d); Wire.endTransmission(); // リードリレー切替待ち delay(1); // 送信 byte buf[4]; buf[0] = 0x02; // STX buf[1] = hex[i]; buf[2] = hex[j]; buf[3] = 0x03; // ETX // 送信は 1 回のみ Serial.write(buf, 4); Serial.flush(); } } } } // ********************************* // 受信側 Arduino nano // ********************************* /* 16 芯配線チェッカー RS-485 版 受信側 * 2020/11/06 f.izawa */ /* TM1637.cpp の TubeTab[] に マイナス'-' 0b01000000 を追加している * static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71, 0b01000000,0b01000110};//0~9,A,b,C,d,E,F,-,-| */ // 4-Digit LED Display #include "TM1637.h" #define CLK 7 //pins definitions for TM1637 and can be changed to other ports #define DIO 8 TM1637 tm1637(CLK, DIO); #define DERE 2 // rs-485 ED/~RE #define BZ 13 // Buzzer int idx; void setup() { Serial.begin(9600, SERIAL_8N1); Serial.setTimeout(10); pinMode(DERE, OUTPUT); // DE/~RE 受信だけなので、常に LOW digitalWrite(DERE, LOW); tm1637.init(); // BRIGHT_TYPICAL = 2, BRIGHT_DARKEST = 0, BRIGHTEST = 7; tm1637.set(BRIGHT_TYPICAL); } void loop() { byte res[4]; tm1637.clearDisplay(); while (Serial.available() > 0){ byte b = Serial.read(); if (b == 0x02){ // STX idx = 0; res[0] = 0x02; } else if (b == 0x03){ // ETX if (res[0] == 0x02){ // LED 表示 int i; if (res[1] <= 0x39) i = res[1] - 0x30; // 0..9 else i = res[1] - 0x41 + 10; // A..F i++; if (i < 10){ tm1637.display(1, i); } else{ tm1637.display(0, 1); tm1637.display(1, i - 10); } if (res[2] <= 0x39) i = res[2] - 0x30; else i = res[2] - 0x41 + 10; i++; if (i < 10){ tm1637.display(2, 16); // '-' tm1637.display(3, i); } else{ tm1637.display(2, 1); //tm1637.display(2, 17); // '-|' tm1637.display(3, i - 10); } tone(BZ, 1200, 100) ; // ブザー //delay(200); //tone(BZ, 1200, 100) ; delay(500); } } else{ idx ++; if (idx <= 2) res[idx] = b; } } }