はじめに
こんにちは。bockringです。初投稿です。
ということでArduinoやArduinoのブートローダーは読み込まれたマイコンなら動作可能なArduMarkというベンチマークソフトです。ぜひご使用ください。
ちなみにソフトの動作は全て英語です。
そしてなにより、Arduino用ベンチマークソフトウェアはネット上でたくさんありますが、シリアル通信速度測定ができるソフトはほとんどないと思っています。
※この記事に切れ端で登場するコードは単体では動作しないことがあります。
仕様
その前にまず、ファイルリンクです。
演算内容は
1.浮動小数点演算(sine(rad);
cos(rad);
tan(rad);
)
2.擬似乱数生成(random(min, max);
)
3.絶対値演算(abs(value);
)
4.平方根演算(root(value);
)
に加え、処理用に加法や除法なども使用します。
使用する関数は続きをお読みください。
演算速度の測定が終了したらシリアル通信の速度も測れるようにコーディングしています。
コード解説
演算処理部分
主軸に使う浮動小数点演算は無難に三角関数で実行します。
//三角関数演算
sin(rad); //Sine演算
cos(rad); //Cosine演算
tan(rad); //Tangent演算
そして、これを32768(2^15)回繰り返します。
ついでに加法(足し算)の演算も済ませてしまいます。
long count; //変数を定義
for (count = 0; count < 32767; count++) { //32768回繰り返す
float SUM = SUM + sin(count); //変数"count"をラジアン角度に代入して演算 そして加法を実行
}
これだけでもArduino UNOで数秒はかかる処理の完成です。
しかしこれで実行してもリザルトの表示や、そもそもソフトが処理を始めているのかすら分かりませんね。ですので、以下の処理を良い感じに追加します。
Serial.begin(115200); //115200bpsでUSB経由のシリアル通信を開始
Serial.print(variable); //任意の変数に格納された文字列を送信
Serial.print("text"); //任意の文字列を送信
Serial.println(variable); //任意の変数に格納された文字列を送信して改行
Serial.println("text"); //任意の文字列を送信して改行
そしていろいろ付け足していき、擬似乱数生成や除法(割り算)なども追加します。
for (count = 0; count < 32768; count++) {
int random1 = random(2, 255); //擬似乱数の生成し、「random1」変数に格納する
int random2 = random1 - 1; //「random1l変数の値から1引いたものを「random2」変数に格納する
float CALC = random1 / random2; //除法を実行する
}
スコア算出部分
ここでですが、スコアが出なければベンチマークとは言えませんね。ですからスコアを出していきます。この時、millis()
関数またはmicros()
関数を使用して実行時間を読み取ります。この関数の戻り値は実行時間です。ここではmillis()
関数の方を用いてスコアを求めていきます。
long TIME = millis(); //変数"TIME"を定義し、実行時間を格納する
そして、反比例(y=a/x)のグラフを考えるに定数(a)を定めて実行時間(x)で割るとスコア(y)が求められるわけです。
long TIME = millis; //省略(上記参照)
long SCORE = 100000000 / TIME; //スコアの算出
スコア算出は必ず「定数を」割りましょう。「定数で」割ってはスコアが算出できません。
これだけでスコアも出せました。
シリアル通信速度計測部分
ご存知かとは思いますがArduinoにはシリアル変換によってマイコンに書き込みます。しかし、稀にシリアル変換が不調を起こすこともありますし、故障することだって無いとは言えません。そしてそれを検知するためにシリアル通信速度を測定し、あらかじめ買い換えるなどの準備ができるようにします。
今回は私の能力が低いために誤差が大きい方法で測定します。
それは、約512Bytes(半角512文字)の文字列をSerial.print("");
関数で送信し続け、実行時間で割り出す方法です。一気に速度を出すコードも作ってしまいます。
int count;
for (count = 0; count < 256; count++) { //256回繰り返す
Serial.println("Now testing serial connection(sending) speed.... Arduino is sending 512bytes(4096bit) text file to your computer. Arduino UNO Revision3 and DUE Revision2 have ATMEL(Now : Microchip)'s ATmega16U2. It support USB 2.0 Full Speed(After renewal). But it supports up to 115200bps connection(14.0625KB/sec). And Arduinos are not expensive, but they have powerful IO and connection. Also they have many editons. For example, UNO, DUE, MEGA, NANO Family, Leonardo, Micro, GIGA, MKR Family, and more. They have some types.");
} //512Bytes(理論上)のデータを送信
Serial.print("通信速度 : ");
long SPEED = 1048576000 /TIME; //送信バイト数(理論上)を時間で割り、Bytes per Secを算出する
Serial.print(SPEED);
Serial.println("bps");
if (speed < 85000) { //測定結果表示
Serial.println("問題有");
} else {
Serial.println("問題無");
}
さぁ、これで処理部分が全て完成しました。これを全て合わせ、表示部分などを作ったものはGitHubまたは次章(こちらについては日本語に直してあります)をご覧ください。
コード全体
ここではコードを載せておきます。また、GitHubで公開しているのは英語版ですが、せっかくQiitaで再公開するのですから、説明書きやコメント、シリアル通信の送信内容を日本語版にしておきます。
※シリアル通信速度測定の分のみはByte数調整の都合で英語のままにしています。
日本語版コード
/*
ArduMark V2.0をご利用いただきありがとうございます。
これは@bockringが作成しました。無断コピー等は強化しません。
ただし、メール等で連絡をしたうえ、私@bockringが許可した場合のみ編集したものの共有を許可します。(オープン・ソース・ソフトウェア)
※必ず使用は無料とすること。
その際、以下のようにクレジットすること。
"
This program was remixed by XXXX(あなたの名前(ペンネーム含)).
Remix source:https://github.com/bockring/ArduMark.git
"
ステータス表示ランプ(オンボードLED : 13番ピン) *デバイスによって正常に動作しない場合があります。
点灯 :処理中
消灯 :処理していません
点滅 :ベンチマーク終了
ご使用方法
1.シリアルポートを選択する
2.シリアルモニタを開く
3.コンパイルし、書き込む
4.処理終了まで待つ
5.シリアルモニタにてスコアを確認する
このソフトウェアは純正Arduinoにて動作を確認しています。(特にArduino UNO R3)
その他のデバイス使用中にコンパイルエラーが発生した場合は、各々で修正するか、Emailで私に修正を申し出てください。
Copyright @bockring 2024~
bockring.scratcher@gmail.com
*/
long count; //進捗状況の格納
float sinsum; //Sine演算
float cossum; //Cosine演算
float tansum; //Tangent演算
boolean start; //実行回数の調整用(起動時用・電源投入1回につき1回実行)
int random1; //擬似乱数の格納
int random2; //擬似乱数の格納
float answer; //整数演算の解の格納
unsigned long benchtime1; //演算時間記録用
unsigned long benchtime2; //シリアル通信速度測定用
unsigned long score; //スコア
unsigned long calcpros; //キャッシュ保存用
void setup() {
Serial.begin(115200); //シリアル通信の開始(115200bps)
}
void loop() {
sinsum = 1;
cossum = 1;
tansum = 1; //和のリセット
start = 0;
Serial.println("ArduMark V2.0をご利用いただきありがとうございます。"); //開始メッセージ
Serial.println("このソフトウェアはArduino用ベンチマークソフトウェアです。3秒以内に開始します。");
Serial.println("Copyright @bockring 2024~"); //著作権表示
delay(2000);
Serial.println(" "); //改行
Serial.println("↓Progress↓");
digitalWrite(13, HIGH);
for (count = 0; count < 32768; count++) { //32768回繰り返す
sinsum = sinsum * sin(count);
}
digitalWrite(13, LOW);
Serial.println("Sine演算が終了しました。");
digitalWrite(13, HIGH);
for (count = 0; count < 32768; count++) {
cossum = cossum * cos(count);
}
digitalWrite(13, LOW);
Serial.println("Cosine演算が終了しました。");
delay(1000); //クールダウン
digitalWrite(13, HIGH);
for (count = 0; count < 32768; count++) {
tansum = tansum * tan(count);
}
digitalWrite(13, LOW);
Serial.println("Tangent演算が終了しました。");
Serial.println("もうすぐ整数演算が開始します。");
delay(1000);
Serial.println("開始");
digitalWrite(13, HIGH);
for (count = 0; count < 32768; count++) { //Repeat 32768 times
random1 = random(0, 255); //擬似乱数を生成する
random2 = random(128, 255); //擬似乱数を生成する
calcpros = random1 / random2;
}
digitalWrite(13, LOW);
digitalWrite(13, HIGH);
for (count = 0; count < 32768; count ++) {
random1 = random(2, 255); //擬似乱数を生成する
random2 = random1 - 1;
random1 = sqrt(random1);
random2 = sqrt(random2);
answer = answer + random1 / random2;
answer = abs(0 - answer);
answer = sqrt(answer);
}
digitalWrite(13, LOW);
Serial.println("整数演算が終了しました。");
benchtime1 = millis();
Serial.println("まもなくシリアル通信速度測定を開始します。(115200bits/秒 512bytes(4096bits)相当のテキストファイルを256回送信します)");
for (count = 0; count != 255; count++) {
Serial.println("Now testing serial connection(sending) speed.... Arduino is sending 512bytes(4096bit) text file to your computer. Arduino UNO Revision3 and DUE Revision2 have ATMEL(Now : Microchip)'s ATmega16U2. It support USB 2.0 Full Speed(After renewal). But it supports up to 115200bps connection(14.0625KB/sec). And Arduinos are not expensive, but they have powerful IO and connection. Also they have many editons. For example, UNO, DUE, MEGA, NANO Family, Leonardo, Micro, GIGA, MKR Family, and more. They have some types.");
}
Serial.println(" ");
Serial.println("全ての項目の性能測定が終了しました。");
benchtime2 = millis() - 2000;
benchtime2 = benchtime2 - benchtime1;
Serial.print("演算時間 : ");
Serial.print(millis());
Serial.println(" ms");
score = 100000000 / (benchtime1);
Serial.print("あなたのArduinoのスコア : ");
Serial.println(score);
Serial.println(" ");
Serial.print("シリアル通信速度 : ");
float speed = 1048576000 / benchtime2;
Serial.print(speed);
Serial.println("bps");
Serial.println("※Arduinoの最大通信速度は115200bpsです。");
if (speed < 85000) {
Serial.println("速度が落ちています。Arduinoの買い替えを推奨します。");
} else {
Serial.println("現状は特に気にする必要はありません。");
}
Serial.println("");
Serial.println("ArduMark V2.0をご利用いただきありがとうございました。");
Serial.println(" ");
Serial.println("Copyright @bockring 2024~");
for (start = 0; start == 0; start = start + 0) { //ループ
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
}
}
おわりに
最後まで読んでいただきありがとうございました。
バグ報告などはGitHubのIssuesタブで受け付けています。
これからもどうぞよろしくお願いします。