site﻿メニューとウィジェットLanguage:日本語English文系人間ですが、Arduinoを使った電子工作に関することをメインにアップしていきます。参考にして頂けるのは嬉しいですが、あくまで自己責任で行ってください。twitterアカウント取得しました。サイトの更新情報がフィードされます。@jumbleat_com検索でヒットする“@jumbleat”は一切関係ありません。2019-01-16RSSメールで通知メール登録でサイトの更新情報が届きます。info@jumbleat.comにご連絡ください。切り替えプリプロセッサで切り替えArduinoでは、変数や状態の確認、あるいはPC側からデータを送信するためにSerial.printをよく使います。かっこよく言えば、デバッグってヤツです。簡単で使い勝手がいいんですが、実は弊害もあります。それはSerial.printを実行することで時間を取ってしまうことです。シビアな反応を必要としない処理であれば全然問題ない話ですが、何かのコントロールをさせたいとか、リアルタイム性を重視したスケッチを書きたいとなるとかなり気になってきます。いうことでこの記事ではSerial.printの出す遅延について書いていきます。Serial.printにかかる時間どのくらいのロスか可変抵抗器で読んだ値でサーボモータを動かすような処理をしながらSerial.printを挟んでいるとスゴくモサモサ感が出ます。Serial.printを外せば問題ないので明らかにそれが原因です。どれぐらいの遅延かはストップウォッチで測れないので、とりあえず、どんなもんか測定できるようなスケッチを組みます。!report;}ループの中でSerial.printする回としない回を作り、それぞれにかかった時間をduration[]に収めます。「Ser」がシリアル通信した場合、「Thr」はスルーした場合のマイクロ秒です。普段、シリアルモニタに書き出す文字数によって、遅延の体感は変わります。!report;}やはり文字数がキーポイントです。1文字あたりのロスfor文で文字数を増やしていき、その差を調べてみます。Serial.print("@");Serial.print(":");Serial.print(duration);Serial.println();repeat++;}10文字以降は大体1040マイクロ秒づつ増えていきます。今までの検証では全て通信速度が9600bpsでした。単純計算だと1秒間に1200バイト。1バイト送るために0.83ミリ秒かかる計算です。理論値ということや、データ転送でのエラーロスとか考えると...まあ、なんとなく上記に近い数値な気がします。逆に通信速度を上げれば、データ送信の時間が短縮されるので、遅延は短くなるハズ。今度はそれを調べてみます。1スケッチをベースにボーレートを変更していき、比較します。95結果かなりざっくりな検証ですけど、それでもSerial.printには時間がかかるのがハッキリしました。速度や文字数も注意しつつ。根本的に、通信はインターバルの電圧変化によるものなので、当たり前なんでしょうけど...やってみた価値はあったのではないでしょうか。対処方法Serial.printが必須のスケッチでは、こういった遅延を回避するにはクロックとボーレートを上げていくしかない思います...。プロトタイピング中の確認では欲しいけど、最終的にはいらないという事であれば方法があります。変数で切り替え要らなきゃ一個づつ削除って方法が一番確実ですが、それでは再度見たい時、特にスケッチが長くなってくるとエラいことになります。そこでそういった検証の類はひとつの変数か、define定数で一括で操作してしまうと楽になります。仮にArduinoのD10ピンにスイッチを付けて、その状態をシリアルモニタに返すスケッチを書いたとします。(print_go){Serial.println(sw_stat);}}2行目のprint_goをtrueか(1)、falseか(0)変更することで、15行目以降のSerial.printを実行するか否かを指定できます。すると確認の書き込みでは実行しておいて、最終的に書き込む時は省くことができます。実は変数よりdefineで定義しておく方がスケッチ量を節約できるので、オススメです。1ただ、この方法だとfalse(0)にしていても、命令自体はスケッチへ組み込まれてしまうので、無駄なif判定が常に行われてしまいます。それも回避する方法があります。プリプロセッサで切り替えよく使う#defineはプリプロセッサと言われる処理です。これはスケッチを書き込む処理をする前にスケッチの書式を整理してくれるものです。単車とすれば、書き込む前に「アイツ」と書かれた場所は全部「単車」に変換してくれます。スケッチ上に「単車」と直接3回書いていたとすれば3つ分の記憶容量を使うけど、defineで「アイツ」=「単車」と定義しておけば、3箇所が「アイツ」1つ分の記憶容量で済むので節約になるわけです。#endifというものもあります。これは普段のifとほぼ同じ使い方です。falseの場合、これに挟まれた命令はプログラム上には無かったことになります。(print_go)Serial.println(sw_stat);#endif}#の行には;(セミコロン)がないことに注意してください。Arduinoへの書き込む前に、命令自体を抹消するのでスケッチ容量が節約できます。この#if〜#endの中へ通常必要な変数や、処理を入れてしまっていると、コンパイル時にエラーが出ます。「どこにあんの?」と。便利でオススメですが、取り扱いも注意が必要なのでお気をつけ下さい。コメントデータの処理方法の詳細はこちらをご覧ください。よるトラフィックデータの収集が行われています。この収集に関しては「匿名」であり、個人情報を特定するものではありません。Amazonアソシエイツ”による広告掲載においても、cookieによるトラフィックデータの収集が行われます。プライバシー規約をご覧下さい。