配線チェッカー 試作版 2018/09/16

 2018/09/16 図面修正
 2018/09/08 若干修正
 2018/09/07 初版作成

■コモン線不要で8本の配線をチェックします。

 やっていることはかなり原始的で、短絡している配線を順にチェックしています。
 回路上では、アナログマルチプレクサを2個使い、コモン側、チェック側を順に切り替え、総当たりでチェックしています。

 短絡している配線の番号が送信側の 7SEG LED に順に表示(0~7)されます。
 2本短絡の場合は2つ、3本短絡の場合は3つの番号が表示されます。

 2本をダイオードで短絡すると、電流の方向が一方向になるため、1つの配線番号が表示されます。
 この番号を DTMF に変換後配線に乗せ、受信側で 7SEG LED に表示(1~8)されます。

 一時期 DTMF 用 IC は市場から消えていましたが、最近秋月電子通商で購入可能になったので、それを使っています。
 7SEG ドライバ 74HC4511 は 表示が 0 ~ 9 に限られるため、PIC を使ったほうが自由度があって良さそうです。

 距離の長い配線や、ノイズや誘導電圧がある配線では試していませんが、基本的には合っていると思いますので、公開してみました。
 修正、改善箇所があれば指摘してください。
 
■発信側(配線8本をつなぐ方)



■受信側(配線をチェックする方)


■接続図
 接続図 (PDF) はこちらです。Bricscad + BJ-Electrical で描いています。
 ・2018/09/16 レベル調整用可変抵抗を追加

■基板デザイン(案)
 現状はユニバーサル基板ですが、16 本版作成の時には基板化してみようかと思っています。
 KiCAD 3D ビュアー↓


■PIC ソースコード ( MPLAB X IDE v5.05 + XC8 )

/*
 * WireChecker 3ビット版
 * 8線のチェックが可能
 * PIC16F628A 
 * File:   main.c
 * Author: F.Izawa
 * WireChecker
 * Created on 2018/09/04, 13:13
 * Updated on 2018/09/08
 * DTMF_Rを4ビットに変更したが、送信:0~7、受信:1~8表示はそのまま
 */


#include <xc.h>

// ブラウンアウト(BOD有効)ビットを有効に検出
#pragma config BOREN = OFF     //4VブラウンアウトリセットOFF
// データEEメモリのコードプロテクションビット(データメモリコードプロテクションオフ
#pragma config CPD = OFF       //データーコードプロテクションOFF
// オシレータ選択ビット(HSオシレータ:RA6 / OSC2 / CLKOUTとRA7 / OSC1 / CLKINに高速クリスタル/共振器
#pragma config FOSC = INTOSCIO //内部発振使用
//#pragma config MCLRE = OFF     //マスタークリアー機能OFF(RA5入出力として使用)
// RRA5 / MCLR / VPPピン機能選択ビット(RA5 / MCLR / VPP端子の機能がMCLRです
#pragma config MCLRE = ON

// ウォッチドッグタイマイネーブルビット(無効WDT)
#pragma config WDTE = OFF //ウォッチドッグタイマーOFF
// フラッシュプログラムメモリコードプロテクションビット(コード保護オフ)
#pragma config CP = OFF   //プログラムコードプロテクションOFF
// 低電圧プログラミングイネーブルビット(RB4 / PGMピンはPGM機能を持つ、低電圧プログラミングが有効
#pragma config LVP = OFF  //低電圧プログラム書き込みOFF
// パワーアップタイマイネーブルビット(PWRTが有効)
#pragma config PWRTE = ON //パワーアップタイマーON
// データEEメモリのコードプロテクションビット(データメモリコードプロテクションオフ
#pragma config CPD = OFF

// __delay_ms() に必要
#define _XTAL_FREQ 4000000  // 4MHz

/*
const static unsigned char table_B[8][3] = { // DEC to BIN
	{  0, 0, 0 }, // 0
	{  0, 0, 1 }, // 1
	{  0, 1, 0 }, // 2
	{  0, 1, 1 }, // 3
	{  1, 0, 0 }, // 4 
	{  1, 0, 1 }, // 5
	{  1, 1, 0 }, // 6 
	{  1, 1, 1 }  // 7
};
*/

 // DTMF R1 .. R4
const static unsigned char table_R[16][4] = {
	{ 1, 0, 0, 0 }, // 1
	{ 1, 0, 0, 0 }, // 2
	{ 1, 0, 0, 0 }, // 3
	{ 0, 1, 0, 0 }, // 4
	{ 0, 1, 0, 0 }, // 5
	{ 0, 1, 0, 0 }, // 6
	{ 0, 0, 1, 0 }, // 7
	{ 0, 0, 1, 0 }, // 8
	{ 0, 0, 1, 0 }, // 9
	{ 0, 0, 0, 1 }, // 0
	{ 0, 0, 0, 1 }, // *
	{ 0, 0, 0, 1 }, // #
	{ 1, 0, 0, 0 }, // A
	{ 0, 1, 0, 0 }, // B
	{ 0, 0, 1, 0 }, // C
	{ 0, 0, 0, 1 }  // D
};
// DTMF C1 .. C2
const static unsigned char table_C[16][4] = {
	{ 1, 0, 0, 0 }, // 1
	{ 0, 1, 0, 0 }, // 2
	{ 0, 0, 1, 0 }, // 3
	{ 1, 0, 0, 0 }, // 4
	{ 0, 1, 0, 0 }, // 5
	{ 0, 0, 1, 0 }, // 6
	{ 1, 0, 0, 0 }, // 7
	{ 0, 1, 0, 0 }, // 8
	{ 0, 0, 1, 0 }, // 9
	{ 0, 1, 0, 0 }, // 0
	{ 1, 0, 0, 0 }, // *
	{ 0, 0, 1, 0 }, // #
	{ 0, 0, 0, 1 }, // A
	{ 0, 0, 0, 1 }, // B
	{ 0, 0, 0, 1 }, // C
	{ 0, 0, 0, 1 }  // D 
};


void main(void) {
    // 内部クロック 4MHz
    PCON = 0b00001000 ;    
    
    // コンパレータは使用しない(RA0-RA4はデジタルピンで使用)
    // PORTA0..3はコンパレータに割り当てられている
    CMCON = 0b00000111;
    
    // RA2はデジタルピンで使用
    VRCON = 0b00000000 ;
    TRISA = 0b00110000 ; // ピン(RA):(0:出力 1:入力) RA5は入力専用 RA4はオープンドレインのため入力で使用
    TRISB = 0b00000000 ; // ピン(RB):全て出力

	// PORTAを初期化
    PORTA = 0x00;		//
	// PORTBを初期化
    PORTB = 0x00;		//
    int n;
    while (1){
        for (int i = 0; i < 8; i++){
            //RB6 = 1; // チェック禁止
            RA0 = (i & 1) == 1;
            RA1 = (i & 2) == 2;
            RA2 = (i & 4) == 4;            
            for (int j = 0; j < 8; j++){
                if (i == j){
                    __delay_ms(1);
                }
                else {
                    RA3 = (j & 1) == 1;
                    RA6 = (j & 2) == 2;
                    RA7 = (j & 4) == 4;
                    __delay_ms(1);                    
                    for (int k = 0; k < 10; k++){
                        __delay_ms(1);
                        // ANSWER LOW になると検出OK
                        if (RA4 != 1){
                            __delay_ms(1);
                            // RY ON
                            RB7 = 1;
                            __delay_ms(1);
                            /*
                            if (j == 0){
                                n = 9;
                            }
                            else {
                                n = j - 1;
                            }
                            */
                            n = j;
                            // DTMF ON
                            RB0 = table_R[n][0];
                            RB1 = table_R[n][1];
                            RB2 = table_R[n][2];
                            RB6 = table_R[n][3];
                            RB3 = table_C[n][0];
                            RB4 = table_C[n][1];
                            RB5 = table_C[n][2];
                            __delay_ms(500);
                            // DTMF OFF
                            // PORTB すべてOFF
                            RB0 = 0;
                            RB1 = 0;
                            RB2 = 0;
                            RB3 = 0;
                            RB4 = 0;
                            RB5 = 0;
                            RB6 = 0;
                            __delay_ms(1);
                            RB7 = 0;
                            break;
                        }
                    }
                }
            }      
        }
    }   
    return;
}