google-site-verification: google3bd66dd162ef54c7.html

Arduino よもやま話 -2 (変数の命名方法)

1.まえがき
 Arduino よもやま話の2回目、今回は変数名の話です。プログラムを書くためには、変数の名前を決める必要があります。役割が一目で判る良い変数名を付けることが出来れば、コーディングがはかどります。一方で、ちょっと違うなーという感じの名前だと、それが気になって、なかなかプログラムを書き進むことが出来なくなったりします。

 ということで、変数名はとても重要です。

2.変数名の決め方
 変数名の決め方については、Arduinoのコーディングルールと命名規則を調べてみたに書かれている内容が網羅的に情報をカバーされているのでとても参考になります。いろいろな流儀があるようですが、私はロワーキャメルケースを使っています。スネークケースの例も以下に示します。
例) ロワーキャメルケース: sunRiseTime ←私はこれ派
   スネークケース:sun_rise_time

 英単語を二つつ三つ使って、その関数の役割を簡潔に表現するのがポイントです。

 あと、1文字だけの短い変数名は使わないことが推奨されています。でも、1文字変数を使った方が判り易くな場合もあるので一概にダメでも無いと思います。例えば下記、これは日の出日の入り時刻を計算した時に作った関数です。
float eCalc(int n) {                           // 近似式で均時差を求める
float e, w;
w = (n + 0.5) * 2 * M_PI / 365; // 日付をラジアンに換算
e = + 0.0072 * cos(w) - 0.0528 * cos(2 * w) - 0.0012 * cos(3 * w)
- 0.1229 * sin(w) - 0.1565 * sin(2 * w) - 0.0041 * sin(3 * w);
return e; // 均一時差を返す(単位は時)
}
 数式通りに書けているので読み易いと思います。こんなふうに関数の中のローカル変数だったら、1文字変数でも許してもらえるはずです。

3.グローバル変数の書き方
 グローバル変数は、すぐわかるように先頭を大文字で書くという作法があるようです。つまり私の場合、変数名をアッパーキャメルケースで書くことになります。
 アッパーキャメルケース:SunRiseTime ←先頭が大文字になっています

 なるほどこれは良いかも、と思って一度やってみたことがあります。でも Arduino の場合はよろしくないと思いました。というのは、Arduinoではグローバル変数がとても多くなることが多いからです。もちろん関数内だけで閉じている変数はローカル変数を使いますが、その数は意外と少ないです。それに、引数を渡して、結果を戻り値で返すという手順を踏むより、グローバル変数を直接いじった方が手っ取り早いということもあります。(お行儀が悪いですが)

 ともかくそんなことで、プログラムはグローバル変数だらけになったわけですが、変数がアッパーキャメルケースで書いてあると、大文字が目立ってしまって、ソースが読み難くなってしまいました。

 あと、Arduino ではほとんどの場合、一人でプログラムを作るので、変数名の競合なんて心配する必要がありません。それにメモリも小さいので、サイズの大きなプログラムになることはありません。そんなことで、グローバル変数だらけになってしまっても、いいのではないか思います。

4.ハードウエアレジスタ名との衝突
 グローバル変数は全部大文字で書く(アッパーケースで書く)、という作法もあるようです。でもArduinoでは、ハードウエアのレジスタ名がアッパーケースであらかじめ大量に定義されているので、これと衝突する恐れがあります。そんなことで、アッパーケースの変数名は使わない方が良いと思います。それにソースが読み難いです。

5.まとめ
 Arduino のリファレンスには変数名は説明的な名前を付けましょう、と書かれているだけでキャメルケースなどの具体的な表現のテクニックまでは書かれていないようです。初心者に余計なプレッシャーを与えないように気を使っているのだと思いますが、少し上達すると、この記事に書いたようなことも大切になってくるはずです。

 あと、変数名は各々の人でこだわりがあるようなので、組織に属していない人は好きなものを使えば良いのですが、こんな意見もあるよ、という感じでこの記事を読んで頂ければ幸いです。

Arduino よもやま話 -1 (関数を書く順序)

1.まえがき
 これまでArduinoを使っていろいろな物を作ってきましたが、そういう経験を通じて得られた知識やノウハウなどを整理すると、これからArduinoを勉強しようという方の参考になりそうです。まあ、そんなたいそうな話では無くても、自分の経験を整理することで、新たな発見(勘違いの発見?)があるかも知れません。

 そんなことで、「Arduino よもやま話」と題して、感じたことや気付いたことを記事にしてみることにしました。ベテランの方から見るとアホみたいなことばかり書くかもしれませんが、ご容赦下さい。なお、Arduinoではプログラムのことをスケッチと言いますが、ここでは原則としてプログラムと呼ぶことにします。

2.関数を書く順序の問題
 初回の記事は「関数を書く順序」です。ArduinoはC言語をベースに、初心者向きに使い易くしたもの、という理解で良いと思いますが、ちょっと違いがあります。そのあたりが一番はっきりと出ているのが、関数を書く順序だと思います。

 Arduinoのプログラムを触った人なら誰でも知っていますが、Arduino のプログラムは以下のような構造になっていて、setup() とloop() をプログラムの最初に書くことになっています。
void setup() {
}
void loop() {
}
 いつもこういう書き方になっていたら判り易いだろう、ということでこの書き方、つまり先頭にsetup()を置いて、次にloop() を書くことになっています。簡単なプログラムなら、この構造の中に全部の内容を書くことが出来ますが、少し複雑な処理を書く場合は、サブルーチンを使う、つまり関数を使って下記のように書くことになります。
void setup() {
}
void loop() {
hogeFunction();
}
void hogeFunction(){
}
 hogeFunction() が追加された関数です。

 Arduinoで関数を使う場合、上に書いたようにように、loop() の後に書くしかありません。何しろsetup() と loop() は先頭に書くのが約束なので、これより前にhogeFunction() を書くわけにはいかないからです。

 これ、Arduinoでは当たり前の書き方ですが、C言語でこの書き方は許されません。関数は、それが実行される前に定義しておく、(あるいはプロトタイプ宣言を行って入出力を明確化しておく、)というルールなので、このままでは、Cコンパイラは通りません。

3.解決策
 どうしているかと言うと、コンパイラに掛ける前にプリプロセッサで構文解析を行い、抜けているプロトタイプ宣言を追加しています。
 プリプロセッサでは setup とloop の処理を、main()の中に展開している、という解説がよく出てきますが、同時にプロトタイプ宣言の追加ということもやっています。

 コンパイラの前処理でこういう操作が行われているため、ユーザーは関数の定義の順序を気にしないでプログラムを書くことが出来るようになっています。

Arduinoの関数のリファレンスに、「関数はloop()の前でも後でも、どちらに書いても良い」とさらっと書いてありますが、このために裏では面倒な処理が行われている訳です。原文だと、下記がそれに相当する部分です。
 Arduinoのレファレンスの関数の説明(Functions)に、Our function needs to be declared outside any other function, so "myMultiplyFunction()" can go either above or below the "loop()" function.

4.まとめ
 ネットにはいろいろなArduinoのプログラムが公開されていますが、その中にはsetup() とloop() が最初に書かれていないものがたまにあります。Arduinoのルール違反と言えなくも無いですが、そういう書き方される方は、たぶんC言語に精通された方なんだろうと思います。変な癖が付くと困るので、あえてCの標準スタイルでプログラムを書かれているのでしょう。
 実は昔、そういうプログラムを見た時に、なんでこういう読みにくい書き方になっているのか、理由が判りませんでした。でも、Cのプログラムとしては、そういう書き方が正しいわけです。実際、そういう書き方になっているプログラムは、高度な内容のものが多いです。

 実は私、C言語は大昔に使ったことがあって、関数の定義を先に書くなんて当たり前にやっていたはずです。でも、うん十年ぶりにArduinoからC言語を使うと、そんなことはすっかり忘れていました。後付けされた関数の参照の解決なんて、機械で出来るんだから人間にやらせるなよ、と言いたくなりますが、C言語はそういう緊張感の下でコードを書くものなんでしょう。

 ということで、よもやま話の初回は、関数を書く順序の話でした。なお、この話は "Arduino プロトタイプ宣言" あたりで検索するともっと質の良い解説が出てくると思います。

Arduinoで作るSDカードを使ったデーターロガー

 前の記事で簡単なデーターロガーを作りましたが、やはり液晶表示があった方が使い易そうなので、改良版を作ってみました。

▼液晶表示を付けたデーターロガー
ロガーのブレッドボード
 ご覧のように16x2のキャラクタ液晶を付けました。この写真では見づらいですが、液晶の接続基板は本来の向きとは裏返しに使いました。こうした方が構造的に安定するし、フットプリントも少し小さくなります。

▼回路図 (クリックで別窓に拡大)
ロガーの回路図
 I2C液晶なので接続は4本だけで済みます。この手軽さは嬉しいです。

 右下の明るさセンサーは周囲の明るさをモニターするためのものですが、これは無くてもOKです。

 ロガーのスケッチはこちら (拡張子をinoに要変更。S-JISでエンコードしています)

 ログの記録条件はLogConf.txtで指定しますが、下記はその設定例です
Data Logger test 2017/10/3
Log00450.csv
60
N, time(s), ch0, ch1, ch2, brightness, cpuTemp(C), cpuVcc(V)

説明
これはSDロガーの設定ファイルです。最初の4行だけ有効で、
以降はメモ領域(何を書いても読み飛ばされる)
1行目:ここに書いたテキストはログデーターの最初に記録される
2行目:ログファイル名(8+3形式で指定)
3行目:記録間隔。秒単位で指定
4行目:列の名前
 以下は実行時の液晶画面です

▼ログ記録開始前
開始時の液晶表示
 ログの名称(LogConf.txtの1行目の最初の16文字)とログファイル名、ログ記録間隔(秒)を表示します。

▼記録中
記録中の液晶表示
 1行目は左から、記録インターバル残り時間、記録した行数、CPUの温度。2行目は、各チャンネルの電圧で、表示の内容は1秒周期で更新されます。

▼ログの例
出力例
 brightnessはフォトトランジスタで検出した周囲の明るさです。このロガーはRTCが無いので正確な時刻は判りませんが、明るさセンサーがあれば、昼夜の区別くらいはつけることが出来ます。なおbrightnessの値は、夜間は5V近くになり、昼間は1V以下の値になります。この感度を調整したい場合は、フォトトラのコレクタ抵抗(Rp)をCPU内蔵のプルアップ抵抗から外部抵抗に変更すればいけると思います。

 cpuTempはCPUに内蔵された温度センサーの値、cpuVccはCPUの電源電圧です。このあたりの測定原理は以前の記事をご覧ください。なおCPUに内蔵されている温度センサの分解能はとても粗いので、何度も測定してアベレージングすることで無理やり 0.1 度単位の値にしています。また絶対精度も怪しいので、無いよりがマシくらいに考えて下さい。それにCPUチップの発熱の影響もモロに受けますし、、

 CPU電源電圧(cpuVcc)はADCの内部基準電圧(1.1V)を使って測定しているので、そこそこ正確な値が得られるはずです。なお、ch0~3 の測定結果は、フルスケール(電源電圧)が5Vという前提で換算した値なので、絶対値が問題になる場合は注意が必要です。

◆まとめ
 Arduinoで作るデーターロガーとしては結構高機能なものが出来たと思います。これをベースに改造でもなんでもやって試していただけば、と思います。

 次はこれを電力ロガーとして仕上げていきたいと思います。電力量計を買ったのが7月の終わりなので、あれから2ケ月経ったわけですが、納期など無いので自分のペースでのんびりとやっていきたいと思います。

 ところで、今回のプログラムは液晶に固定フォーマットで数値を表示させていますが、そのプログラムが何とも美しくないのが気になっています。lcd.printf( )とやって書式指定が出来ればいいのですが、液晶のライブラリにはそんな機能はサポートされていないようです。ということで、他の手を探す必要があります。
 String形式を操作する関数を使うか、sprintf()を使えば良さそうですが、うまくいったら記事にしたいと思います。
カレンダー
03 | 2018/04 | 05
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 - - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード