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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

1回答

2525閲覧

M5StackC-Plusに書込んだスケッチの挙動が「書込みに使用したPCにより異なる」原因と対策をご教示願います。

Yasu0421

総合スコア37

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2022/06/09 12:34

質問の内容

先ず、以下のタイミングチャートに従って動作するスケッチを作成してみました。
イメージ説明

①は500mSec毎に定期的にデータが送信されてくるUART(1線式)信号です。
②は①の信号変化(エッジ)を検知したら、割込みを発生する「信号割込み」です。
③は②の信号割込みのタスクとして「1mSec毎のタイマー割込み」を始動します。また、タイマー始動後は②の信号割込みを一旦、停止させます
④は③によるカウンターとなります
⑤は①の500mSec毎の定期通信の合間を狙って、UART信号にWrite信号を重畳させる為に④のカウンタが40になったらイネーブル(ゲートオープン)出力するようにしています
⑥は⑤の信号がイネーブルになった後、④のカウンタ値が41になったらシリアルライトコマンドを発行します。
⑦は⑥によって出力される「ライトデータ信号」で、その出力時間は通信速度とライトするバイト数に依存して変化しますが、ここでは10mSecの時間データが出力されている場合と仮定しています。(つまり、⑦のWriteData信号が出力されている時間分だけ、⑤のゲートを開いておく)

最後に、処理するタスク時間によりカウンタの時間もずれてくるため、約10秒間隔で②の信号割込みを有効化しタイミングの整合性を保持しています。この10秒と言う時間も別カウンターでカウントしたエイヤ的な時間です

発生している問題

さて、作成したスケッチは無事コンパイルも完了し、M5StickCPlusへの書き込みもできたのですが、書き込みに使用したPCに依存して、期待通りの動作を行ってくれるものもあれば、エラーを発生するモノもあるといった少々理解しがたい現象が発生しております。

エラーメッセージ(書込みに使用したPC1の例)

M5StickCPlus initializing.... OK E (633) ledc: freq_hz=0 duty_resolution=13 E (633) ledc: ledc_get_freq(533): LEDC is not initialized

エラーメッセージ(書込みに使用したPC2の例)

21:02:53.370 -> Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1). 21:02:53.417 -> 21:02:53.417 -> Core 1 register dump: 21:02:53.466 -> PC : 0x4008aa30 PS : 0x00060a35 A0 : 0x80089ca2 A1 : 0x3ffbee1c 21:02:53.551 -> A2 : 0x3ffb8a00 A3 : 0x3ffb8890 A4 : 0x00000004 A5 : 0x00060a23 21:02:53.633 -> A6 : 0x00060a23 A7 : 0x00000001 A8 : 0x3ffb8890 A9 : 0x00000018 21:02:53.748 -> A10 : 0x3ffb8890 A11 : 0x00000018 A12 : 0x00000004 A13 : 0x00060a23 21:02:53.832 -> A14 : 0x007bef78 A15 : 0x003fffff SAR : 0x00000007 EXCCAUSE: 0x00000006 21:02:53.917 -> EXCVADDR: 0x00000000 LBEG : 0x40086729 LEND : 0x40086739 LCOUNT : 0xfffffffd 21:02:54.050 -> Core 1 was running in ISR context: 21:02:54.050 -> EPC1 : 0x400dfc1b EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000 21:02:54.136 -> 21:02:54.136 -> 21:02:54.136 -> Backtrace:0x4008aa2d:0x3ffbee1c |<-CORRUPTED 21:02:54.183 -> 21:02:54.183 -> 21:02:54.229 -> Core 0 register dump: 21:02:54.229 -> PC : 0x4008abb1 PS : 0x00060035 A0 : 0x800898cf A1 : 0x3ffbe8cc 21:02:54.324 -> A2 : 0x3ffbef78 A3 ⸮

そして、もう1つのPCでは、期待通りの動作している

実現したいこと

「M5StickCPlusへのスケッチ書き込みに使用するPC」に依存することなく、上記タイミングチャート通りに動作できるようにしたいです。

該当のソースコード

#include <M5StickCPlus.h> hw_timer_t * timer1 = NULL; int onemicro; unsigned long exe_time; int t_count=0; int synchro_count = 0; int loop_count = 0; bool data_flg = false; String hexdata(""); byte cmd[8] = {0xFF,0xFF,0x86,0x04,0x05,0x06,0x07,0x08}; void IRAM_ATTR interrupt(){ data_flg = true; loop_count = 0; detachInterrupt(digitalPinToInterrupt(0)); Serial.println("timerAlarmWrite is started......"); timerAlarmWrite(timer1, 1000, true); //1msec毎に実施 timerAlarmEnable(timer1); } void IRAM_ATTR onTimer() { char buf[16]; //「0xXX」なので終端含めて最低6byte byte get1bytedata; if(synchro_count == 10000){ //10秒毎に同期処理を実行 data_flg = false; loop_count = 0; timerAlarmDisable(timer1); //タイマーを停止する t_count = 0; synchro_count = 0; attachInterrupt(0,interrupt,CHANGE); }else if((t_count == 0)&& (synchro_count != 10000)){ digitalWrite(25, 1);//Writeゲートを閉じる t_count++; synchro_count++; }else if((t_count == 40)&& (synchro_count != 10000)){ digitalWrite(25, 0);//Writeゲートを開く t_count++; synchro_count++; }else if((t_count == 41)&& (synchro_count != 10000)){//Serial1ポートからWriteコマンド発行 Serial1.write(cmd,8); t_count++; synchro_count++; }else if((t_count == 51)&& (synchro_count != 10000)){//Writeデータの終了タイミング digitalWrite(25, 1);//OE off t_count++; synchro_count++; }else if((t_count == 100)&&(synchro_count != 10000)){//Serial1リード処理な if(Serial1.available()){ int availableNum = Serial1.available(); Serial.print("Serial Available return value = "); Serial.println(availableNum); for(int i = 0; i<16; i++){ get1bytedata = Serial1.read(); sprintf(buf,"0x%02X,",get1bytedata); hexdata.concat(buf); } Serial.print("HEXDATA = "); Serial.println(hexdata); Serial1.flush(); hexdata = ""; } t_count++; synchro_count++; }else if((t_count == 499)&& (synchro_count != 10000)){//同期処理 t_count=0; synchro_count++; }else{ t_count++; synchro_count++; } } void setup() { M5.begin(); Serial.begin(9600); Serial1.begin(9600, SERIAL_8N1, 0, 26); Serial2.begin(9600, SERIAL_8N1, 32, 33); pinMode(25, OUTPUT); digitalWrite(25, 1);//Writeゲートを閉じる onemicro =getApbFrequency()/1000000; timer1 = timerBegin(0, onemicro, true); timerAttachInterrupt(timer1, &onTimer, true); digitalWrite(GPIO_NUM_10, 1); attachInterrupt(0,interrupt,CHANGE); } void loop() { if((loop_count == 1000)&&(data_flg==false)){//ハード割込みが発生してこない場合の対応 detachInterrupt(digitalPinToInterrupt(0)); timerAlarmDisable(timer1); //タイマーを停止する Serial.println(); Serial.println("Communication signal not available....."); attachInterrupt(0,interrupt,CHANGE); loop_count=0; String hexdata(""); }else{ loop_count++; } }

尚、上記動作確認のために、もう1個M5StickCPlusを用意し、GPIO33からシリアルデータを500mSec毎に出力させるスケッチを作成し、上記タイミングチャートのUART信号としております。

試したこと

Arduino-IDEの環境設定や、インストールライブラリを全PCで統一させてりしましたが、変化はありませんでした。

・ボードに書き込まれた内容は同じはずなのに「書込みに使用したPCにより動作しない場合がある」とう現象自体が理解できないので、原因を知りたく存じます。
・このような割込み処理プログラムの使い方自体が間違っているのでしょうか(逆に正常に動いているということ自体が奇跡であり、たまたま動作しているだけ?)

原因と対策をご教示いただけないでしょうか?
どうぞよろしくお願い致します。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2022/06/09 13:12

> Arduino-IDEの環境設定や、インストールライブラリを全PCで統一させてりしました 「確認しました」ではなく、具体的に観察された事実を記載してください。 とりあえずボードライブラリのバージョンを一番に疑うところと思います。 本件とは関係ない(症状が違う)とは思いますが、G0はブートモードの決定に関わるため、入力端子として使用する(=外部からレベルが変更される)のは意図しない動作のもとになりそうに思います。
ozwk

2022/06/10 01:25

一応補足しておくと、9600bpsでは1文字送信するのに約1msかかります。
Yasu0421

2022/06/10 03:47

ご回答ありがとうございます。 回答表示が折りたたまれた状態で展開されておらず、気が付きませんでした。 申し訳ございません。 一応、Serialコマンドや、Serial.print系などすべて削除してみてどうなるかも 確認したのですが、結果は変わらず・・・でした。
thkana

2022/06/10 04:54

ここは「回答」ではなくて「質問への追記・修正の依頼」の欄です。本来はこの欄への記入は質問者に「お知らせ」として通知されるはずなのですが、そこがteratailのシステム不具合でスムーズにいかないようですね。 別にSerial.printの類が今回の現象の原因だなんて言ってません。それはそれとしてダメだというだけです。 Serialの話はともかくとして、 あなたがそれぞれのPCについて確認した項目とその結果はどうだったのでしょう。
Yasu0421

2022/06/10 07:00

「ダメだということです」も踏まえて、外してみて確認したという事をいいたかったのですが、 ここに書くべきことでなかったらならば、失礼しました。
thkana

2022/06/11 08:03

結局「PC間の違いの何を確認してどうだったか」の話は無し? まぁいいや。では、ばっさりと全部... 正常に動いている(と思われる)PC(Windowsということで良いかしら?)の "C:\Users\ユーザー名\AppData\Local\Arduino15\packages\esp32" で、他のPCの同ディレクトリを置き換えてからコンパイル/書き込みしたらどうなるかしら。(そこにコンパイラや設定一式が入っています) 一応、現状データは他の場所に逃がすなどして戻せるようにしておくことを推奨しますが、特に手をいれていないのならボードライブラリを一旦削除してインストールしなおし(あるいはバージョンを一旦ロールバックしてから最新に戻す)すれば通常状態には復帰するので神経質になることもないと思います。
guest

回答1

0

ベストアンサー

まずは、どういうふうにタイミングチャートから外れているのか、を調べましょう。
どの部分でどれだけずれているかってのを詳細に調査する必要があります
それがわからないことには、どーにもなりませんよ

#で、双方のバイナリの比較はしてみました?

投稿2022/06/09 12:56

編集2022/06/09 13:07
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yasu0421

2022/06/09 23:01

ご回答ありがとうございます ・正しく動作してくれなくなるPCで書き込んだM5StickCPlusではすぐに上記エラーが発生するため  「どういうふうにタイミングチャートから外れているのか」の確認アプローチが情けないことに  おもいつきません ・バイナリ比較はやり方が分からないので行っておりません  別々のPCで作成した、コンパイル後のバイナリデータをArduino-IDEでは吐き出すことができる  のでしょうか?(ご教示いただければ助かります)
Yasu0421

2022/06/09 23:16 編集

Arduino-IDEからバイナリ出力はできるようですね 以下に記載されておりました https://www.jh4vaj.com/archives/28795 ただ、ソースコードは同じでも、書き込むPCによってバイナリが異なることは多いらしいということと、そもそも動作がことなるので、バイナリデータ自体も異なっているとおもいます。 確認はしてみます
y_waiwai

2022/06/09 23:11

ああ、まずはビルド結果のHEXファイルの比較してみてください。 これが違ってるなら、コンパイルオプションとかなんかのビルド設定が双方で違ってるってことですね
Yasu0421

2022/06/09 23:28 編集

ご回答ありがとうございます。 コンパイルオプション・・・・ 特に違った設定はしていないのですが、再確認してみます。 因みに、正しく動作してくれるM5StickCPlusがあるということは、ソースコード自体は 怪しくないと言えるでしょうか? とりあえず「platform.txt」あたりを比較してみます
y_waiwai

2022/06/09 23:42

まずはボード設定とか書き込み設定などが同一か、ArduinoIDEのバージョンが同一か、あたりですかね > ソースコード自体は怪しくないと言えるでしょうか? これはむずかしいところで、こういう組み込み系のCPUでは、実行中のアクセス違反のたぐいは*全く*検出しませんし、エラーも出しません。後々に、そのアクセス違反が原因で何かがコケる、という形で知るしかないです。 #怖いのは、何事もなく正常に実行される(ようにみえる)ときですね
Yasu0421

2022/06/10 03:41

エラーとして「表に出ない」場合もあるということですね。 その場合は非常に厄介ですね。 ビルドオプションで治ることを祈ります。 ご見解いただきありがとうございました。
Yasu0421

2022/06/13 00:55

土日を挟んで間があきましたが、ようやく確認できました。 ・ビルドオプションファイル(platform.txt)は全く同じファイル ・各PCで生成したバイナリファイルを比較すると全て異なる そこで、M5StackcPlusボードのバージョンを確認するとそれぞれ違うことがわかりました。 正しく動作してくれるPCのM5Stackのバージョン(1.0.9)に合わせることで全て同じ動作を行ってくれるようになりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問