前回の答えは!!
「コア2つでのマルチタスク!!!」
でした~!
ESP32て、CPUがデュアルコアでプロセッサーが2つあるので同時に2つの処理ができるんですよ!凄すぎません!!!?この辺はなおさんが専門かな?
模型に仕込めるマイコンもここまできましたか!それではその方法おば説明^^
参考にしたのはこちらのサイト
いつもお世話になっています(`・ω・´)ゞ「Long-Ship」さん
です。ただ、これ読んではい!そうですか!と分かるのは、Vividさんやなおさんレベルでないと無理w
てなことで、ぶっちゃけどうしたらできるかだけ書きますw
何故なら、私もまだよく理解していないからww
まずはsetup()にこの一行
ちょっと簡単な説明
xTaskCreatePinnedToCore(①blue_op, “②blue_op“, ③8192, NULL,④ 1, NULL,⑤PRO_CPU_NUM);
①別コアで実行する関数の名前
②ここも関数の名前(その関数だと分かれば何でもおっけー)
③別コアで実行する関数に割り振るメモリー(8192位から4096位を見かけました)
④優先順位 数が多いほど優先度が高いようです。最高は25とからしいです。
⑤この関数を実行するコアの番号。
⑤についてはESP32ではコアは0か1のどちらかです。
PRO_CPU_NUMは「0」を表し。
APP_CPU_NUMは「1」を表します。
直接0もしくは1と書いてもいいみたいです。
ちなみにメインのloop()はAPP_CPU_NUMで実行されているみたいですから、完全なマルチタスクを求める場合はPRO_CPU_NUMを選択しましょう。
次に今回の私の場合の関数を
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
//==================Bluetooth======================= void blue_op(void *pvParameters){ while (1) { if (SerialBT.available()) { String receiveData = SerialBT.readStringUntil(';'); if(receiveData=="dstop"){demo=0; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="dstart"){demo=1; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="dstartup"){demo=2; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="dwepon"){ demo=3; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="dtakeoff"){demo=4; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="dmisa"){ demo=5; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="dradar"){ demo=6; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="ddogfight"){demo=7; String sendData =receiveData+";"; SerialBT.print(sendData); } } delay(10); } } |
2行目の関数名は void 好きな関数名(void *pvParameters)の書式で
3行目のwhile(1){ は必ず入れてください。
40行目 今回は40行目ですがどこでもいいですから、delay();を関数に入れてください。遅延時間は1ms以上ならいくらでもOKです。
このwhile(1)とdelay();が無いと
リブートの嵐となりますww
なんでもウオッチドックとかいう犬が住んでるみたいで、これらの記載がないとマイコンが暴走していると判断して無限に再起動がかかっちゃいますw
後最後にもう一つ注意点
今回2つのコアでマルチタスクを行っていますが、2つのコアの間で共通の「demo」という変数を使っています。このような場合は変数設定の時に
int demo;
ではなくて
volatile int demo;
としましょう。
よく知らないけどそういう物らしいですww
はい!これであなたもマルチタスク出来ます!!
ただし、変数の変更のタイミングやタイマー割込みとか排他制御とか色々と気にしないといけない部分もあるみたいですが、その辺は問題出た時に検索してくださいw
ここまで読まれて、初めに紹介したブログを読まれると理解が進みやすいかもです。
以上の説明だけだとちょっとイメージわかないという方用にbluetooth接続で点滅速度が変わるマルチタスクのプログラム置いておきます。これを元に色々と改変されてみると良いかも^^
ただ・・・・・・・・間違っていたらごめんなさいねwその時は優しく教えてくださいww
とりあえずは下の動画のように動きます^^
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#include "BluetoothSerial.h" #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif BluetoothSerial SerialBT; #define LED1 12 volatile int SW; void blue_op(void *pvParameters){ while (1) { if (SerialBT.available()) { String receiveData = SerialBT.readStringUntil(';'); if(receiveData=="on"){SW=1; String sendData =receiveData+";"; SerialBT.print(sendData); } if(receiveData=="off"){SW=0; String sendData =receiveData+";"; SerialBT.print(sendData); } } delay(20); } } void setup() { Serial.begin(115200); SerialBT.begin("ESP32test"); //Bluetooth device name Serial.println("The device started, now you can pair it with bluetooth!"); xTaskCreatePinnedToCore(blue_op, "blue_op", 8192, NULL, 1, NULL,PRO_CPU_NUM); pinMode(LED1,OUTPUT); } void loop(){ if(SW==1){ digitalWrite(LED1,HIGH); delay(300); digitalWrite(LED1,LOW); delay(300); } else{ digitalWrite(LED1,HIGH); delay(1000); digitalWrite(LED1,LOW); delay(1000); } } |
PCもしくはスマホでbluetooth 接続して「on;」、「off;」とシリアル通信で入力すると点滅速度が変わると思います。ちなみにPCでの接続は前回も紹介した「JH7UBCブログ」さんを参考にしてください。
スマホの場合はそれぞれのアプリによって使い方違いますのでググってください。
それにしても、一つのマイコンでマルチタスクが実現できるなんて凄いですよね~。
関連すると思われる記事:
- None Found
なるほろ。
レスポンスが必要な部分は、面倒でこんがらがる前に別々に処理しちゃうんですか。シンプルですね。
ま、でも結局別のタスクで送受信したやつを元々のタスクで処理しなくちゃいけないから、めんどくささもちゅうくらいなりおらがタスク?
元々のタスク上の処理で、入出力や送受信を完全に切り分けて、都度待たせるようなプログラムだったら処理は簡単だけど昭和のパソコンみたいになっちゃうねw
こんばんは。
なるへそ!!
良くこんなサイトを探し出しましたね! その探求心に感激です。
ちょっと前には考えも及ばなかった、32ビットマルチタスクCPU!!
6jiroさんが雲の上のそのまた上に、、、、
こちらは、「タッチボタン」のレベルでとん挫しています(笑)
こんばんは! 回答編ありがとうございます!
ESP32ってデュアルコアだったんですね、そしてマルチコアにタスクを明示的に振り分けるんですね。OSいないから自分でタスク管理しているのが最初の関数と。なるほどなるほど、まったく予想できませんでした(^^;
理屈は理解できました。しかし、OSなしでマルチタスクとかマニアックな使い方w
いや、これはプラットフォームがQuadやOctコアのプロセッサを使うようになったら、ArdOSとかなんとかでてきてOSのるな。個人の趣味の世界を越えてきてる
Volatile指定しないといけないのは、ArdIDEの癖のような気もします。コア間の共有変数なので本来コンパイラが自動判断すべきとこ。
ちなみにWDTは設定でキャンセルできそうですけど、IDEはそこら辺は触らせてくれないんでしょうね。
昔の専門分野に近いのでいらん事いろいろ書いてしまったような気がします。すいません、、、
gyoさん こんにちは!
2つのCPUで別々に作業して、変数の受け渡しが出来るという感じですね^^
メインのループではあの液晶表示をフルでやっていますのでタイマー割り込みはちょっと厳しい感じでした。
仰るようにメインの方のdelayの部分にこの受信関数放り込んでその都度受信を確認するのも一つの手なのですが、それやるとプログラムのあちこちにこの受信関数入れないといけなくて、プログラムが超カッコ悪いww
受信自体は優先度が24と高いのでメインの処理していても、割り込みで受信しているのですが、そのデーターを使っての処理は今回はこのような方法で解決しました。普通のリモコンなら返信しても意味がないのですが、タッチパネルを使ったリモコン考えていますので返信が有るとそれによってリモコン側の表示も変えれますので^^
Vividさん こんにちは!
ESP32ならではのマルチタスクやってみましたw
このサイトはブログでフォローさせていただいてる方のサイトでLovyanGFXについても色々と書いてくださっていますのですごく勉強になるんですよ^^。
おっしゃるように、マルチタスクなんて半年前では全く想像も出来ない世界に入ってきちゃいましたねwwここまでESP32が優秀なマイコンとは思いもしませんでしたw
arduinoのメモリーが足りなくなって、一時はどうしようとかなり悩みましたが、そのおかげでホント良いマイコンにであえました^^
あっ、マルチタスク使えるようになりましたが全く理解は追い付いていませんからww
タッチボタンでVividさんがそこまで苦戦されるとは・・・・・その辺手を出さなくてよかったw
なおさん こんにちは!
ね~~っ!
まさかこんなマイコンがデュアルコアでマルチタスクが出来るなんて思いもしませんよね~!
私も初めて知った時かなりビックリしましたww
さすが専門に近いだけ有りますね~!
ArdOSとか出来てきたらもうほとんどラズパイになっちゃいますねww
でも将来的にはそうなっていくかもしれませんね~。
Volatile指定はarduinoクセなのですか~まっ、ESP32ではそういう物だと覚えておくことにしますw
WDTもキャンセルは出来るようですが、やり方は知りませんww
arduinoIDEも直接指定で書き方が有るのだとはおもいますが^^;
当初delay()入れてなくて暴走しまくって難儀しましたww