質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.09%

Milkcocoa・ESP-WROOM-02・Arduino M0の組み合わせでArduino側でon()した時の処理が不安定なので安定させたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,719

umi_kappa

score 12

前提・実現したいこと

以前の質問「 ESP-WROOM-02をWi-FiモジュールとしてArduinoに接続(SoftwareSerial)してMilkcocoa Arduino SDKを使用する方法について」でArduino M0からMilkcocoaへ値をpushすることはできるようになりました。
次のステップとして、スマートフォンのWebブラウザからJavaScriptで数値をMilkcocoaへpushし、Arduino M0のmilkcocoa.on()でスマートフォンからpushされた値を取得したいのですが、Arduino M0が値を取得中にスマートフォンから連続でpushしたりすると、Arduino M0の処理が止まったり、取得した値が古いものが返ってきたりしました。
安定して動作させるためのアドバイスをいただけますと幸いです。
milkcocoa.loop()を実行したタイミングでスマートフォンからpushすると正しい値が取得できます。

ソースコード

#include "ESP8266.h"
#include "Milkcocoa.h"
#include "Client_ESP8266.h"

/************************* WiFi Access Point *********************************/

// Wi-Fi SSID
#define WLAN_SSID       "SSID"
// Wi-Fi PASSWORD
#define WLAN_PASS       "PASSWORD"


/************************* Your Milkcocoa Setup *********************************/

// MilkcocoaのアプリID
#define MILKCOCOA_APP_ID      "APP_ID"
#define MILKCOCOA_DATASTORE   "led"

/************* Milkcocoa Setup (you don't need to change this!) ******************/

#define MILKCOCOA_SERVERPORT  1883

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266Client class to connect to the MQTT server.
ESP8266Client wifi;

const char MQTT_SERVER[] PROGMEM    = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ MILKCOCOA_APP_ID;

Milkcocoa milkcocoa = Milkcocoa(&wifi, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);

int value;

// LEDを接続するピン
const int ledPin = 13;

/**
 * 初期設定
 */
void setup() {
  // デジタル13番ピンを出力として設定
  pinMode(ledPin, OUTPUT);

  SerialUSB.begin(115200);

  Serial5.begin(115200);

  SerialUSB.println("Milkcocoa SDK demo");

  // Connect to WiFi access point.
  SerialUSB.println(); SerialUSB.println();
  SerialUSB.print("Connecting to ");
  SerialUSB.println(WLAN_SSID);

  wifi.begin(Serial5, 115200);

  SerialUSB.print("FW Version:");
  SerialUSB.println(wifi.getVersion().c_str());

  if (wifi.setOprToStation()) {
    SerialUSB.print("to station ok\r\n");
  } else {
    SerialUSB.print("to station err\r\n");
  }

  if (wifi.joinAP(WLAN_SSID, WLAN_PASS)) {
    SerialUSB.print("Join AP success\r\n");
    SerialUSB.print("IP: ");
    SerialUSB.println(wifi.getLocalIP().c_str());
  } else {
    SerialUSB.print("Join AP failure\r\n");
  }

  if (wifi.disableMUX()) {
    SerialUSB.print("single ok\r\n");
  } else {
    SerialUSB.print("single err\r\n");
  }

  if (milkcocoa.on(MILKCOCOA_DATASTORE, "push", onpush)) {
    SerialUSB.println("milkcocoa on sucesss");
  }
  else {
    SerialUSB.println("milkcocoa on failure");
  }

  value = 10;
};

/**
 * ループ処理
 */
void loop() {
  SerialUSB.println("Loop ...");
  // Milkcocoaのループ処理を実行します
  milkcocoa.loop();

  // 1秒処理を止める
  delay(1000);
};

void onpush(DataElement *pelem) {
  SerialUSB.println("onpush");
  //SerialUSB.println(pelem->getInt("state"));

  // 取得した値が1ならば
  if (pelem->getInt("state")) {
    SerialUSB.println("LED ON");
    // LEDを接続しているピンをHIGH状態に変更(点灯)
    digitalWrite(ledPin, HIGH);
  }
  // 取得した値が1以外ならば
  else {
    SerialUSB.println("LED OFF");
    // LEDを接続しているピンをLOW状態に変更(消灯)
    digitalWrite(ledPin, LOW);
  }
};
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

いつもありがとうございます!
Milkcocoa開発チームのkiyopikkoです。

問題を明確にするために以下についてお答え頂けますか...?

  • 「Arduino M0の処理が止まる」というのは止まってしまってそこから何も処理をしなくなってしまうということでしょうか?また、そのときのシリアル出力を貼って頂けますでしょうか? 
  • スマートフォンから連続でpushとは具体的な数値としてはどれくらいの間隔でしょうか?

「取得した値が古いものが返ってきたり」については、現在のSDKの仕様で1000msの間に同時に来たデータは同じタイミングで処理されるようになっています。
これは、用途によってはかなり邪魔な(笑)仕様かと思うので、ユーザー側で指定するように検討中です。

ちなみに、以下も確認頂けると幸いです。

  • Arduino SDKは最新版を使っているか
  • Arduinoのlibraries(home/Documents/Arduino/libraries)にESP8266 SDKとArduino SDKが混在してしまっていないか

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/22 18:45

    kiyopikkoさん
    あれからArduino M0 Proで本質問のスケッチを試してみましたが、Arduino M0と同じ現象(Value変数の件も含めて)が発生しました。
    お手すきの時でかまいませんので、ご確認いただけますと幸いです。

    キャンセル

  • 2016/02/23 22:11

    こちら、M0 Proで同じ現象起こりました。
    ESP8266 SDKではこの問題は起こらなかったので、
    Arduino SDK特有の問題なので、Arduino SDKのIssueにあげますね。

    キャンセル

  • 2016/02/24 09:49

    kiyopikkoさん
    ご確認ありがとうございます!
    この部分がクリアになれば1つネタが完成するので楽しみにお待ちします。

    キャンセル

checkベストアンサー

0

IDE 1.7.8 のM0のライブラリにはバグがあります.以下の変更を適用して試してもらえますででしょうか.

./hardware/arduino/samd/cores/arduino/USB/samd21_device.c : 152行目 メモリリーク修正.

for (i = 0; i < sizeof(usb_endpoint_table)/4; i++) {
    (*(uint32_t *)((uint32_t *)(&usb_endpoint_table[0])+i)) = 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/07 16:42

    ShinyaHondaさん
    返答が遅くなってしまい申し訳ございません。
    samd21_device.cファイルを修正することで「setup内でダミー変数へ代入しないと、MQTTの接続に失敗する」件は解消されました。ありがとうございます。
    on()で取得した値が古い件は解消されませんでした。

    キャンセル

  • 2016/03/07 17:25

    「on()で取得した値が古い」件ですが、
    ./hardware/arduino/samd/cores/arduino/RingBuffer.hのSERIAL_BUFFER_SIZEを256に変更することで解決できました。

    ですが、別の問題が発生しました。
    on()起動から初めてデータを取得したおよそ1分後に、再び同一IDのデータが取得され、その後on()でデータの取得ができなくなりました。

    キャンセル

  • 2016/03/07 21:57

    「on()起動から初めてデータを取得したおよそ1分後に、再び同一IDのデータが取得され、その後on()でデータの取得ができなくなりました。」
    こちらを私の方で調べてみました。
    on()の実行にかかわらず、スケッチを起動後一定時間が経過すると、ESP8266.cppのdataAvailable()の返り値が1となり現象が発生しているようです。

    キャンセル

  • 2016/03/08 21:39 編集

    「on()起動から初めてデータを取得したおよそ1分後に、再び同一IDのデータが取得され、その後on()でデータの取得ができなくなりました。」
    こちらのその後です。
    結論から申し上げると、Arduino M0 Proから一定時間アクセスがないとMilkcocoaが接続をCLOSEDにする仕様になっていそうです(実際に"CLOSED"という文字列を受け取った後にアクセスができなくなりました)。

    接続が切れる前に定期的にダミーデータをsend()すると解決されました。こちらの認識で正しいでしょうか?

    Milkcocoa ESP8266 SDKの方では、Milkcocoa.cpp内のloop()関数のconnect()部分が下記のようになっており、接続が切れると再接続するようです。

    if(!connect(timeout)){
    return false;
    }

    GitHub
    https://github.com/milk-cocoa/Milkcocoa_ESP8266_SDK/commit/52ac4f33b5667588035d036785272586b3ca33cc

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • Arduinoに関する質問
  • Milkcocoa・ESP-WROOM-02・Arduino M0の組み合わせでArduino側でon()した時の処理が不安定なので安定させたい