Vol.927 26.Sep.2025

小型家電のリサイクル PIC−PIC間でECAN接続 ネットワーク上のデバイスが表示されない

K 小型家電のリサイクル

by fjk

 「小型家電リサイクル法」は、デジタルカメラやゲーム機等の使用済小型電子機器等の再資源化を促進するため、主務大臣による基本方針の策定及び再資源化事業計画の認定、当該認定を受けた再資源化事業計画に従って行う事業についての廃棄物処理業の許可等に関する特例等について定めた法律です。

・法律の概要
使用済小型電子機器等の再資源化の促進に関する法律(環境省[PDF 48KB])
・施 行
平成25年度4月1日
・目 的
使用済小型電子機器等に利用されている金属その他の有用なものの相当部分が回収されずに廃棄されている状況に鑑み、使用済小型電子機器等の再資源化を促進するための措置を講ずることにより、廃棄物の適正な処理及び資源の有効な利用の確保を図り、もって生活環境の保全及び国民経済の健全な発展に寄与すること

【参考】

環 境 省
(一社)小型家電リサイクル協会
リネット

【富山県の認定事業者】

芥ARITA
豊臣産業


P PICでCAN通信(1) 〜PIC−PIC間でECAN接続

by fjk

 前報(abc926)でCAN通信のおおよそが判ったので、PICでCAN通信の実験を行った。
 参考にさせていただいたのは「PICとPICでECAN通信の実験」(「きむ茶工房ガレージハウス」さん)で、オリジナルから以下の変更を行った。
 (両方ともPIC18F26K80を使用)

@ CANトランシーバーをMCP2561からMCP2562に変更(終端抵抗は120Ω)
A ノード1のLCD表示プログラムはオリジナル「lcd_lib.c」(abc765参照)を使用
B ノード1のAQM0802Aをバックライト付きに変更(#109422
C ノード2にFT234X+USARTを使ってUSBでパソコンと通信(動作確認、ADデータ表示)を追加
D ノード2のAD変換、CAN通信はTMR0の割込で1秒ごとに実施。

ノード2のVRつまみを回すと、ノード1のLCDにアナログ電圧値が表示され、CAN通信が正常に行われていることが確認できた。


CAN 通信の実験風景(各デバイスには0.1μFのパスコンを追加)

≪≪ ノード1 ≫≫

ノード1の回路図(リモート要求SW付)


ノード1の pinモジュール(IDE6.15)


ノード1のI2Cモジュール


ノード1のECANモジュール(MCC5.4.1)



≪≪ ノード1・2共通 ≫≫

systemモジュール(ノード1・2とも同じ)
≪≪ ノード2 ≫≫

ノード2の回路図(モード切替SW付)


ノード2の pinモジュール(IDE6.15)


ノード2のTMR0モジュール


ノード2のEUSARTモジュール


ノード2のADCモジュール


ノード2のECANモジュール(MCC5.5.0)

ノード1、ノード2のプログラムリスト

【おまけ】
 参考にしたページでは、データとリモートの2種類のフレーム使用例が別々に紹介されているが、両方の機能を同じハードで行えるよう、以下の機能を追加した(前述の回路図は機能追加を考慮したもの)。

@ ノード1に、リモート送出用にプッシュスイッチをRC2に追加(要プルアップ抵抗)。
・スイッチの検出とリモートフレーム送信用プログラムを追加。
・ノード1の受信は、データ/リモートのどちらのフレームにもそのまま対応。
A ノード2に、モード切り替え用にスライドスイッチをRA2に追加(要プルアップ抵抗)。
・リモートフレーム受信用プログラムを追加
・ノード2はスライドスイッチの位置により、データ/リモートのモードが切り替わる。
  • データモードでは、ノード2のAD変換データがノード1のLCDに自動で表示される。
  • リモートモードでは、ノード1のスイッチを押すと、ノード2でAD変換を開始し、その結果をノード1に送信し、LCDに表示。

「データ/リモート兼用」のプログラムリスト


おまけ実行例(ツイストペア線使用)


W Windows11でネットワーク上のデバイスが表示されない

by fjk

 Windowsでネットワーク上にあるパソコンやプリンタを共有することができるが、Windows10(22H2)ではNAS(LS-XL89D)も含めて、問題なくアクセスできていたのに、Windows11(24H2)では、デバイスのアイコンも表示されなくなった。
 これは、PCの故障ではなく、ネットワーク検索など、Windowsの設定(仕様)が変更されたためで、特に古い規格であるSMB1.0は、デフォルトで使用できなくなっている。
 他にも、変更された所が幾つかあるようで、以下を参照に、設定を変更してみた。

@ 「ネットワーク上の共有PCやプリンタが表示されない」
A 「ネットワーク上のデバイスが表示されない原因と対処法」
B 「パソコンのインターネット接続が不安定なときに試してほしいネットワークのリセット方法」
C 「Windowsのファイルとフォルダの共有設定」

 この様な症状時の対策は、

・ネットワーク探索を有効にする
・ファイルとプリンターの共有を有効にする
・ネットワークをプライベートネットワークに変更する
・WindowsDefenderファイアウォールでネットワークの探索を許可する
・SMB1.0を有効にする

 @で指摘のあった、上記の設定を全て確認・変更を行って、PCを再起動してみたが、それでも、デバイスのアイコンが表示されなかった。
 そこで、Aに記載の「ネットワークの設定をリセットする」(詳細はBを参照)を実行し、PCを再起動したところ、ネット接続中のPCのアイコンは表示されるようになった。しかし、古いNAS(LS-XL89D)のアイコンはSMB1.0を有効にしても表示されなかった。
 さらに、windows11では、共有アクセス時に資格情報(ユーザー名/パスワード)を要求する仕様が強化されたようで、「ユーザーアカウント」→「資格情報マネージャー」からLS-XL89Dの資格情報を設定してみたが・・、アイコンは表示されなかった。
 SMB2/3対応のNASに変更するしか無いのかな・・・。

「共有フォルダにアクセスできない原因と対処法」
「共有フォルダにアクセスできない:資格情報が求められるときの対処法」

 ここまでで、一応、他のPCのアイコンが「ネットワーク画面」に表示されるようになったので、Cを参照に、「ファイルの共用」を設定すると、2つのPC間でファイルの共用が出来るようにはなった。

  • Windows10でもabc771で紹介したようにNAS接続エラーの例があったので、ワークグループの設定でグループ名も合わせてみたが、Windows11のネットワークではLS-XL89Dのアイコンは表示されなかった。
  • Windows11の「ネットワーク」ではLS-XL89Dを検出できなかったが、BuffaloのNAS_Navigater2をインストールすると、Windows11でLS-XL89Dがチャンと認識され、ファイルの共用が可能となった。
     ・NAS_Navigater2入手先

 LS-XL89Dはかなり古いので、今後の故障等を考慮して、新しいNASとしてLS710D040を入手した。

  • LS710D040とLS-XL89Dを同じネットワークに繋ぐと、Windows11ではどちらのNASのアイコンもネットワーク画面に表示されなかったが、NAS_Navigater2では両方のアイコンが表示された。
  • LS-XL89Dはアイコンのクリックで共有できたが、LS710D040のアイコンをクリックしても応答無く、接続できなかった。
    これは、Windows11ではネットワーク資格情報が強化され、SMB署名が必要になったためで、ゲストログオンでは、SMB署名を利用できないため、共有フォルダーを開くことができなくなった。
  • そこで、LS710D040のアイコンを右クリックし、「Web設定画面」から、「ユ−ザ−設定」で「作成」をクリックし、新規にユーザ名とパスワードを設定。
  • さらに、「ファイル共有」「SMB」「ネットワーク資格情報」で「資格情報の入力画面を表示する」に設定。
  • そして、NAS_Navigator2画面でLS710D040のアイコンをクリックすると、ユーザー名とパスワード入力画面が表示され、必要な情報を入力すると、共有フォルダーに接続でき、ファイル共有が出来るようになった。
  • なお、LS-XL89Dは資格情報の入力が必要なく、アイコンをクリックするだけで、ファイルの共有ができた。

NAS Navigator2 画面

ファイル共有/ユーザー 設定画面

ファイル共有/SMB 設定画面


≪≪ ノード1 ≫≫
abc927-26k80-1.zip
  ≪≪ ノード2 ≫≫
abc927-26k80-2.zip

/**********************(abc927-26K80-1.c)************
 *     ECAN テスト  ノード1   (PIC18F26K80)
 *****************************************************/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/ecan.h"
#include "i2c_LCD_lib.h"

//------  共通変数の宣言
uCAN_MSG rxMessage ;                // 受信メッセージバッファ

//------  受信の処理
void processRxMessage(void) {
     union {
          unsigned char c[2] ;
          unsigned int  i ;
     } data ;
     char buf[12] ;
     
      // 標準の識別子IDか?
     if (rxMessage.frame.idType == dSTANDARD_CAN_MSG_ID_2_0B) {
          switch (rxMessage.frame.id) {
            case 0x123 :
                data.c[0] = rxMessage.frame.data0 ;
                data.c[1] = rxMessage.frame.data1 ;
                sprintf(buf,"%8d",data.i) ;
                LCD_cursor(0,1) ;    // LCDの2行目に表示
                LCD_str(buf) ;
                break ;
            default :
                LCD_cursor(0,1) ;
                LCD_str("Unknown ") ;
                break ;
          }
     }
}

/***********************************************
 *   Main application
 ************************************************/
void main(void)
{
    uint8_t rc;

    SYSTEM_Initialize();
    LCD_init();

    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();

    LCD_str("ECAN");
    LCD_cursor(0,1); LCD_str("   TEST");
    
    while (1)    {
        if ( CAN_receive(&rxMessage)) {
               // 受信したら処理を行う
               processRxMessage() ;
          }
    }
}

/******* End of File ********/
  

/**********************(abc927-26K80-2.c)************
  *     ECAN テスト  ノード2   (PIC18F26K80)
 ***************************************************/
#include "mcc_generated_files/mcc.h"

#define EU_BFSIZE  120
#define DBF_SIZE    512                 // File/Memory用BFサイズ
#define MBF_SIZE    64                  // メッセージ用BFサイズ

/***** グローバル変数 ***************************/
//--- タイマー用変数
    uint8_t TFlg;                       // タイマーフラグ
//-----  EUSARTシリアル用
    char    RBuf[EU_BFSIZE];            // 受信文字Buffer
    uint8_t SFlg;                       // 受信フラグ
    static uint8_t sIdx = 0;            // 受信文字列Index
//---- 汎用データ処理用
    char    Msg[MBF_SIZE];              // コメント等送信用文字列
//---- CANデータ処理用
    uCAN_MSG txAdcResult ;              // 送信メッセージバッファ

/************************************************
  *  タイマ0 Callback関数 (1秒周期割り込み)      *
 ************************************************/
void TMR0_Process(void){
    TFlg = 1;                           // タイマーフラグセット
}

/*=== Eusart受信割り込みハンドラー =============*
 *    eusrt.cのEUSART_Recive_ISRに追加すること  *
 *---------------------------------------------*/
void myEusart(void){
    char ch;
    ch = (char)EUSART1_Read();
    #if ECHO == ON
        EUSART1_Write(ch);
    #endif
    if((ch == 0x0a)||(ch == 0x0d)){     // 改行処理
        RBuf[sIdx] = 0;
        sIdx = 0;
        SFlg = 1;
    }else if((ch == 0x08)&&(sIdx > 0)){ // BS処理
        sIdx--;
    }else{
        if(sIdx < EU_BFSIZE) RBuf[sIdx++] = ch;
    }
}

 uint16_t ad_conv(void){    
    ADCON0bits.GO_nDONE = 1;            // Start the conversion
    while (ADCON0bits.GO_nDONE); 
    return ((uint16_t)((ADRESH << 8) + ADRESL));
 }

/***********************************************
 *   Main application
 ***********************************************/
void main(void){
    union {	unsigned char c[2] ;
          	unsigned int  i ;	} data ;
     
    SYSTEM_Initialize();
    TMR0_SetInterruptHandler(TMR0_Process); // Timer0 Callback関数
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    IO_RC2_SetHigh();
    puts("--- start ---\n");
    __delay_ms(3000);
    
    while (1)  {
        if(TFlg){
            IO_RC2_Toggle();           
            TFlg = 0;
            data.i = ad_conv();
            printf("%d\n",data.i);
            txAdcResult.frame.idType = dSTANDARD_CAN_MSG_ID_2_0B ;
            txAdcResult.frame.id     = 0x123 ;
            txAdcResult.frame.dlc    = 2 ;
            txAdcResult.frame.data0  = data.c[0] ;
            txAdcResult.frame.data1  = data.c[1] ;
            CAN_transmit(&txAdcResult) ;    // メッセージデータを送信
        }
        if(SFlg){
            printf("%s\n",RBuf);
        }
        SFlg = 0;
    }
}

/******* End of File ********/
 

<< ECAN設定時のレジスタ値(参考) >>
/********************(ecan.c)************/
	・・・
void ECAN_Initialize(void)
{
    CANCON  = 0x80;
    ECANCON = 0x00;
    CIOCON  = 0x20;            // MCCでは0x00となることがある
    BRGCON1 = 0x07;
    BRGCON2 = 0xA8;
    BRGCON3 = 0x01;
	・・・

<< ノード2用EUSART.C >> (赤字を追加)
/*******************(usart1.c)*******/

void myEusart(void);
	・・・

void EUSART1_Receive_ISR(void)
{
	・・・
    myEusart();
}


   【おまけ】(デ−タ+リモート)

≪≪ ノード1 ≫≫(一部を抜粋)
abc927-26k80-1R.zip
  ≪≪ ノード2 ≫≫(一部を抜粋)
abc927-26k80-2R.zip

/**********************(abc927-26K80-1R.c)************
  *     ECAN テスト
 *****************************************************/
   	・・・・・

// 共通変数の宣言
uCAN_MSG txAdcResult ;              // 送信メッセージバッファ
uCAN_MSG rxMessage ;                // 受信メッセージバッファ

   	・・・・・

char msg[8];

// 受信の処理
   	・・・・・


/***********************************
 *      Main application
 ************************************/
void main(void){
  uint8_t rc;

  SYSTEM_Initialize();
  LCD_init();

  INTERRUPT_GlobalInterruptEnable();
  INTERRUPT_PeripheralInterruptEnable();

  LCD_str("ECAN");
  LCD_cursor(0,1); LCD_str("   TEST");
    
  while (1)   {
    // スイッチが押されたらリモートフレームをを送信する
    if (RC2_GetValue()  == 0) {
      __delay_ms(100);              // チャタリング防止に1秒程待つ
      // 送信メッセージデータを作成する
      txAdcResult.frame.idType = dSTANDARD_CAN_MSG_ID_2_0B ;
      txAdcResult.frame.id     = 0x123 ;
      txAdcResult.frame.dlc    = 0x40 ;  // リモートフレーム送信要求
      CAN_transmit(&txAdcResult) ;  // メッセージデータを送信する
    }
    if ( CAN_receive(&rxMessage)) { // 受信したら処理を行う
      processRxMessage() ;
    }
  }
}
/*************** End of File  ******************/
 

/**********************(abc927-26K80-2R.c)************
  *     ECAN テスト
 *****************************************************/
   	・・・・・
// 共通変数の宣言
uCAN_MSG txAdcResult ;              // 送信メッセージバッファ
uCAN_MSG rxMessage ;                // 受信メッセージバッファ
   	・・・・・
// 受信の処理
void processRxMessage(void) {
  union {
    unsigned char c[2] ;
    unsigned int  i ;
  } data ;

  // 標準の識別子IDか?
  if (rxMessage.frame.idType == dSTANDARD_CAN_MSG_ID_2_0B) {
    // リモートフレームの送信要求か?
    if ((rxMessage.frame.dlc & 0x40) == 0x40) {
      switch (rxMessage.frame.id) {
        case 0x123 :
          // 半固定抵抗の値を読み込む
          data.i = ad_conv() ;
          // 送信メッセージデータを作成する
          txAdcResult.frame.idType = dSTANDARD_CAN_MSG_ID_2_0B ;
          txAdcResult.frame.id     = 0x123 ;
          txAdcResult.frame.dlc    = 2 ;
          txAdcResult.frame.data0  = data.c[0] ;
          txAdcResult.frame.data1  = data.c[1] ;
          // メッセージデータを送信する
          CAN_transmit(&txAdcResult) ;
          break ;
        default :
          break ;
      }
    }
  }
}

/***********************************
 *      Main application
 ************************************/
void main(void){
   	・・・・・
  while (1)    {
    if (CAN_receive(&rxMessage)) {
      // 受信したら処理を行う
      processRxMessage() ;
    }
   	・・・・・
}
/*************** End of File  ******************/

★もし、delaey関数がC99でエラーとなる場合、以下のマクロ記述を追加


/******  Delay Macros  **************************
 *      NOTE:  C99 requires macro declarations  *
 ************************************************/
#define __delay_us(x) _delay((uint32_t)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((uint32_t)((x)*(_XTAL_FREQ/4000.0)))


※プログラムのリストをハイライト付きのスタイルで見る場合はここをクリック


※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。


小型家電のリサイクル PIC−PIC間でECAN接続 ネットワーク上のデバイスが表示されない