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;
}
}
}