2023年8月11日金曜日

Edisonが故障した一件

 最近またEdisonで遊んでいます。


教育用のデバイスとしてよく出来ているなと思っているEdisonですが、現在3台を所有しています。
最近このうちの1台が調子が悪くなってしましました。具体的にはBeep用のデバイスが壊れたようです。購入時にチェックをしたつもりですが今回久々に音関係のプログラムを作っていたところ音が出なくなっていました。
通常は電源を入れるとBeep音が鳴るのですがこれが出ないのでおかしいなと思って、とりあえずプログラムを作って動かした所やはり音が出ませんでした。

あれ、Blogerのプレビューが動かない!


これはMacBook Airで書いて居るのですが、今までプレビューも問題なく使えていましたが今日は「読み込んでいます」でループして居るようです。
とりあえずiMacに移って続きを書き始めましたが、こちらでは問題無くプレビューできるようです。
私のMacBook AirもEarly 2015と既に8年前の物、最近ではシステムアップデートもできていませんし、バッテリーもお亡くなり寸前の状態です。そろそろ買い替えたいなと考えていますが、今のところ動いているので延び延びになっています。
来年あたりは変えかられるかなぁ〜

閑話休題


早速、サポートに連絡を入れましたがレスポンスも翌日にはあり、その後も丁寧に対応してくれました。非常に好感が持てましたので嬉しくなってアップした次第です。5、6回のやりとりをしましたが、概ね翌日の午前中にはレスポンスがあリました。アーストラリアとは2時間の時差なので、向こうで朝一メールをチェックして対応しているのかなと言う感じでした。

やはり、ブザーデバイスの故障ということになり、保証期間内なので代替品を送ってもらえることになりました。

保証期間は1年間あるのですが、これもしっかりとした物作りができていると言う自信なのでしょうか? Edisonそのものは非常にコンパクトでしっかりとした作りになっています。小さいお子さんも使う前提で小さな部品もほぼ無く(電池カバーのみ)鋭角な部分も少なく安全にも配慮された作りになっていると思います。 LEGOと組み合わせることができるので、レゴを使った場合には小さなお子さんがLEGOブロックを飲み込む危険があるので注意が必要にはなります。
製造は中国で行っているようですが、今まで問題になったのは電池ボックスの蓋のバネが弱くて電池がうまく接触しなかったケースぐらいです。これもバネを少し伸ばしてあげることで問題なく使えるようになりました。

マイナス点としては、電源スイッチが非常に小さいので小さなお子さんでは電源を入れられないかもしれないと言う点。
あとは、電池ボックスの蓋がちょっと癖があるので開け閉めにコツがいることでしょうか。これはホームページのFAQにも対策が書いてありました。

Edisonドキュメントの日本語化を進めています


EdisonはEdBlock(Scratch Jr)、EdScratch(Scratch)、EdPy(Python)と理解に応じた言語が用意されているので年長さんあたりから中学生あたりまで広くプログラミングの学習に使えるなと考えています。
ただ、問題は日本語ドキュメントが無いのがネックになっていると思います。上記3つの言語ツールも全て英語版だけなのでそこが利用する上でのネックになっているのかと思います。
本体は6千円程度で入手できるのでLEGOと比べると購入しやすいと思います。

と言うことで、現在プログラミング学習用ドキュメントの日本語化を進めています。
本家が非常に良質なプログラミング学習用ドキュメントを用意してくれていて、翻訳したいと連絡したら翻訳用キットを送ってもらえました。
現在、鋭意翻訳中ですので終了しましたら公開していきたいと考えています。
1人でやっているので時間がかかりますが、まずは生徒用ドキュメントから翻訳を始めています。

今しばらくお待ちくださいね。

2023年4月7日金曜日

ESP32をW5500で有線LAN接続してmDNSしてみた -2-

前回投稿より1年近くが経ってしまいました。途中、投稿しとこうかと思った事も幾つかあったのですが、ついついコードを書く事が優先して気がつくと何を書こうとしたのかも忘れてしまう有様でした。
そろそろボケが入って来たのかな?

W5500搭載 ATOM PoEキット


現在IoT 関連のプログラムを趣味のように書いていますが、その中でこんな物を見つけたのでWi-Fiが使えない&電源を取るのが難しいという状況でセンサーが使えそうだなということで早速購入して遊んでみました。

W5500については以前ブログにアップしていたので簡単に動くかと思ったのですが・・・

当時のplatformio.iniは

[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
lib_deps = adafruit/Ethernet2@^1.0.4 khoih.prog/MDNS_Generic@^1.0.1

こんな感じだったのですが、既にこのバージョンは古くなって使えなくなっていました。
ならばと最新版でコンパイルするとコンパイルエラーが多発してうまくいきません。
GitHubのサンプルResolvingHostNames.inoを見ると

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include <MDNS_Generic.h>

のようなコメントもありましたが、依存関係を見るとWiFiを参照していたりと本来ネットワーク媒体には非依存で作成すべきなところがだいぶ複雑になっていそうです。
そこでもっと軽いライブラリはないかなと探してみたところ、やはりいました。

ArduinoMDNS


PlatformIOにもありましたので早速使うことにしました。
依存関係も無くすっきりとしたライブラリのようです。

今回のplatformio.iniは

[env:m5stack-atom] platform = espressif32 board = m5stack-atom framework = arduino monitor_speed = 115200 lib_deps = m5stack/M5Atom@^0.1.0 arduino-libraries/Ethernet@^2.0.2 arduino-libraries/ArduinoMDNS@^0.0.0

こんな感じです。

早速テストして見ると、パニックを起こしてしまいます。
どうやらアドレスエラーのようです・・・
前回同様またソースを見ることになるとは(( _ _ ))..zzzZZ

_finishedResolvingNameが原因でした


ソースを見るとどうやら_finishedResolvingNameメソッドでアドレス例外を出しているようです。
void MDNS::_finishedResolvingName(char* name, const byte ipAddr[4])
{   
   if (NULL != this->_nameFoundCallback) {
      if (NULL != name) {
         uint8_t* n = this->_findFirstDotFromRight((const uint8_t*)name);
         *(n-1) = '\0';
      }
      this->_nameFoundCallback((const char*)name, IPAddress(ipAddr));
   }

   my_free(this->_resolveNames[0]);
   this->_resolveNames[0] = NULL;
}

このメソッドは名前解決が出来た時に呼び出されてコールバック関数を呼び出すのですが、ソースを検索すると、名前解決できなかった時も呼び出されているます。但しipAddrがNULLで呼び出されていました!(前回調査時と同じ不具合)ということでその部分を以下のように変更して問題は解決しました。
this->_nameFoundCallback((const char*)name, 
                 (ipAddr == NULL ? INADDR_NONE : IPAddress(ipAddr)));

resolveNameサンプル


ヘッダファイル:
    DNSClient dns;
    EthernetUDP udp;
    MDNS mdns = MDNS(udp);
ソースファイル:
/* ****************************************************************************
 *      DNS
 ******************************************************************************/
IPAddress resolved_ip_address;
void nameFound(const char* name, IPAddress ip) {
    resolved_ip_address = ip;
    Serial.println(ip == INADDR_NONE ? " failed !!!" : " successed !");
}

IPAddress NetworkClientW5500Class::resolveName(const char *name) {
    IPAddress ipAddress;
    boolean rc = ipAddress.fromString(name);
    if(!rc) { // IP指定だった場合は名前解決不要
        if(this->useDNS) {
            int ret = this->dns.getHostByName(name, ipAddress);
            if (ret != 1) {
                // mDNS初期化
                if(!this->beginMDNS) {
                    if (!this->mdns.begin(Ethernet.localIP(), this->client_name)) {
                        // mDNS初期化エラー
                        Serial.println("Error setting up MDNS(W5500) responder!!!");
                        while(true) { 
                            delay(1000);
                            Serial.print(".");
                        }
                    }
                    this->beginMDNS = true;
                    this->mdns.setNameResolvedCallback(nameFound);
                    Serial.println("mdns.begin is success !");
                }
                Serial.print("host(");
                Serial.print(name);
                Serial.print(") IP address resolving ");
                int count = 0;
                resolved_ip_address = INADDR_NONE;
                while(true) {
                    if (!this->mdns.isResolvingName()) {
                        this->mdns.resolveName(name, 5000);
                        count++;
                        if(count > DNS_RETRY_COUNT)
                            break;
                        else if(count > 1)
                            Serial.print("retry resolving ");
                    }
                    Serial.print(".");
                    this->mdns.run();
                    if(resolved_ip_address != INADDR_NONE) {
                        ipAddress = resolved_ip_address;
                        count = 0;
                        break;
                    }
                    delay(100);
                }
                if(count > 0) {
                    // 名前解決できず
                    Serial.println(" was ended in failure!!!");
                    while(true) { 
                        delay(1000);
                        Serial.print(".");
                    }
                }
            }
            Serial.print("host(");
            Serial.print(name);
            Serial.print(") IP address : ");
            Serial.println(ipAddress);
        } else {
            Serial.print("host(");
            Serial.print(name);
            Serial.print(") name resolution failed !!!");
            while(true) {     
                delay(1000);
                Serial.print(".");
            }
        }     
    }
    return ipAddress;
}

Edisonが故障した一件

 最近またEdisonで遊んでいます。 教育用のデバイスとしてよく出来ているなと思っている Edison ですが、現在3台を所有しています。 最近このうちの1台が調子が悪くなってしましました。具体的にはBeep用のデバイスが壊れたようです。購入時にチェックをしたつもりですが今回久...