【電子工作】3-1.Arduinoのソースコードを複数ファイルに分けよう
最近、どんどんコードが長くなっていますよね。
特に、数字を表現する部分は、変更することがないのに
毎回コードが長くて、ファイル全体の可読性を下げてしまっています。
できれば、もう変更しない部分を分けてしまいたいですよね。
例えば、前回のコードでいうと、
何個も出てくる”数字表現”を定義した
//Display function x
の部分です。
また、Arduinoではなかなかないかもしれませんが、
C言語に限らず、規模が大きくなってくると、
1つのプロジェクトを複数のメンバーで作成や修正することが増えてきます。
しかしながら、
複数のメンバーで1つのファイルを同時に編集するのは色々と問題が発生します。
また、別のプロジェクトに流用するためにも
ファイルを分けちゃいましょう!
Arduinoの画面には、ひっそりとファイル追加する画面があります。
ただ、Arduinoの画面って名称に癖がありますね。
◆ファイル分割① ファイルを追加
新規タブ と書いていますが、これがファイル追加を意味しています。
このボタンを押すと。。
画面を大きくしているとわかりにくいんですが、
以下のような、ファイル名を記入する画面が表示されます。
なんで画面の下やねん。。。
好きな名前を入力してOKを押しますよ
今回、SAIはDisplayFunctionを別ファイルに分けたいので、
こんな名称にしました。
拡張子はひとまず、".h " にしておきましょう。
◆ファイル分割② コードの移動
続いて、
新しく作成した"DisplayFunction.h"に、移動させたいコード部分を全部移動させましょう。
とりあえず、
エラーチェックをしたいので、
何も考えず、DisplayFunction に関連する定義を 全部移動させましょう。
◆ファイル分割③ includeの追加
そして、
最後にメインの関数に、新ファイルをincludeしましょう。
追加するファイルはローカルヘッダなので、 ” でくくります。
この段階で、一回ビルドしてみてください。
うまく移動できていたら、
ビルドが成功するはずです!
◆ファイル分割④ ソース用のinoファイル追加
続けて、ソースコード部分を移植します。
Arduinoの追加するソースファイルは”ino”である必要があります。
①と同様の方法でファイル追加ができますが、
拡張子を指定しなければ、勝手に”ino”になるようです。
◆ファイル分割⑤ コードの移動
続いて、
新しく作成した"DisplayFunction.ino"に、
移動させたいコード部分(作った関数のことです)を全部移動させましょう。
C言語と違い、ヘッダファイルにプロトタイプ宣言をする必要はないようです。
"DisplayFunction.ino"に、関数を書いたら、
ビルドをしてみましょう。
どうでしょうか?
※サンプルソースを最下部に載せておきます。
お試しください。
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
雑談
それにしても、C言語を扱っていた人からすると、
Arduinoはちょっと変わっていますね。
C言語の感覚でコードを書くと、よくわからないエラーが出たりします。
関数に関しては、どれかのinoファイルに関数を記載しておけば、
リンク時に整合性を撮ってくれるっぽいですね。
それに反して、定数は事前にIncludeしていないとエラーになる。
最初は、プロトタイプ宣言と定数宣言がうまくいかないので、
考え方が理解不能でした。。
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
それでは、コードです。
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
★メインのinoファイル
/*
* Author: SAI
*/
/* *** Include *** */
#include <TimerOne.h>
/* 注意
TimerOne.h を使用するためには、
スケッチ -> ライブラリのインクルード -> ライブラリの管理
から、TimerOne をインストールしておく必要があります。
*/
// 7Seg LED 表示Function //
#include "DisplayFunction.h"
/* *** Define 定義 *** */
#if 0
/* 1桁の表示時間 */
const long TIMER_ADJUST = 103;
const long TIMER_DELAY = (5 * 1000) - TIMER_ADJUST;
/* 1秒にかかるカウント数 */
const long TIMER_CNT_SECOUND = ((long)1000 * 1000) /(TIMER_DELAY*4);
#endif
/* 1桁の表示時間 */
const long TIMER_DELAY = (5 * 1000);
/* 1秒にかかるカウント数 */
const long TIMER_CNT_SECOUND = ((long)1000 * 1000) /(TIMER_DELAY);
/* 砂時計用内部カウンター */
long gTimerCounter;
long gDispTime;
/* initial setting 初期設定 */
void setup() {
/* IO output setting IO出力設定 7Seg用端子を出力 */
pinMode(ASeg, OUTPUT);
pinMode(BSeg, OUTPUT);
pinMode(CSeg, OUTPUT);
pinMode(DSeg, OUTPUT);
pinMode(ESeg, OUTPUT);
pinMode(FSeg, OUTPUT);
pinMode(GSeg, OUTPUT);
pinMode(DotSeg, OUTPUT);
pinMode(Keta1Seg, OUTPUT);
pinMode(Keta2Seg, OUTPUT);
pinMode(Keta3Seg, OUTPUT);
pinMode(Keta4Seg, OUTPUT);
digitalWrite(Keta1Seg, LED_KETA_OFF);
digitalWrite(Keta2Seg, LED_KETA_OFF);
digitalWrite(Keta3Seg, LED_KETA_OFF);
digitalWrite(Keta4Seg, LED_KETA_OFF);
/* タイマー用のカウンターを初期化 */
// Timer setting タイマー設定
Timer1.initialize(TIMER_DELAY); //マイクロ秒単位で設定
Timer1.attachInterrupt(timerFire); // コールバック関数設定
gTimerCounter = 0;
gDispTime = 0;
}
/* Mail loop 通常処理(繰り返し) */
void loop() {
delay(1000);
}
/*
* タイマー割り込み処理
* 100ms(=100000us)毎にここが呼び出される */
void timerFire() {
// 時間計測 //
gTimerCounter++;
if(gTimerCounter >= (long)10000*1000)
{
gTimerCounter = 0;
}
/* 100ms単位の時間に変換 */
int lTime = gTimerCounter / (TIMER_CNT_SECOUND /10 ) ;
if(gDispTime != lTime)
{
gDispTime = lTime;
/* 桁上がりした時だけ、1msの処理をする */
delay(1);
}
/* 桁切り分け */
int DispKeta = gTimerCounter % 4 ;
switch(DispKeta)
{
case 0:
/* 1桁を表示 */
DigitDisp(lTime);
digitalWrite(DotSeg, LED_OFF);
Keta1();
break;
case 1:
/* 2桁を表示 */
digitalWrite(DotSeg, LED_ON);
DigitDisp(lTime/10);
Keta2();
break;
case 2:
/* 3桁を表示 */
digitalWrite(DotSeg, LED_OFF);
DigitDisp(lTime/100);
Keta3();
break;
case 3:
default:
/* 4桁を表示 */
digitalWrite(DotSeg, LED_OFF);
DigitDisp(lTime/1000);
Keta4();
break;
}
}
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
DisplayFunction用のinoファイル
// ヘッダファイルはここでIncludeする必要ないみたい。
//Display function 0
void zero() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_ON);
digitalWrite(FSeg, LED_ON);
digitalWrite(GSeg, LED_OFF);
}
//Display function 1
void one() {
digitalWrite(ASeg, LED_OFF);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_OFF);
digitalWrite(ESeg, LED_OFF);
digitalWrite(FSeg, LED_OFF);
digitalWrite(GSeg, LED_OFF);
}
//Display function 2
void two() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_OFF);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_ON);
digitalWrite(FSeg, LED_OFF);
digitalWrite(GSeg, LED_ON);
}
//Display function 3
void three() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_OFF);
digitalWrite(FSeg, LED_OFF);
digitalWrite(GSeg, LED_ON);
}
//Display function 4
void four() {
digitalWrite(ASeg, LED_OFF);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_OFF);
digitalWrite(ESeg, LED_OFF);
digitalWrite(FSeg, LED_ON);
digitalWrite(GSeg, LED_ON);
}
//Display function 5
void five() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_OFF);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_OFF);
digitalWrite(FSeg, LED_ON);
digitalWrite(GSeg, LED_ON);
}
//Display function 6
void six() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_OFF);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_ON);
digitalWrite(FSeg, LED_ON);
digitalWrite(GSeg, LED_ON);
}
//Display function 7
void seven() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_OFF);
digitalWrite(ESeg, LED_OFF);
digitalWrite(FSeg, LED_OFF);
digitalWrite(GSeg, LED_OFF);
}
//Display function 8
void eight() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_ON);
digitalWrite(FSeg, LED_ON);
digitalWrite(GSeg, LED_ON);
}
//Display function 9
void nine() {
digitalWrite(ASeg, LED_ON);
digitalWrite(BSeg, LED_ON);
digitalWrite(CSeg, LED_ON);
digitalWrite(DSeg, LED_ON);
digitalWrite(ESeg, LED_OFF);
digitalWrite(FSeg, LED_ON);
digitalWrite(GSeg, LED_ON);
}
//Display function Keta1
void Keta1() {
digitalWrite(Keta1Seg, LED_KETA_ON);
digitalWrite(Keta2Seg, LED_KETA_OFF);
digitalWrite(Keta3Seg, LED_KETA_OFF);
digitalWrite(Keta4Seg, LED_KETA_OFF);
}
//Display function Keta2
void Keta2() {
digitalWrite(Keta1Seg, LED_KETA_OFF);
digitalWrite(Keta2Seg, LED_KETA_ON);
digitalWrite(Keta3Seg, LED_KETA_OFF);
digitalWrite(Keta4Seg, LED_KETA_OFF);
}
//Display function Keta3
void Keta3() {
digitalWrite(Keta1Seg, LED_KETA_OFF);
digitalWrite(Keta2Seg, LED_KETA_OFF);
digitalWrite(Keta3Seg, LED_KETA_ON);
digitalWrite(Keta4Seg, LED_KETA_OFF);
}
//Display function Keta4
void Keta4() {
digitalWrite(Keta1Seg, LED_KETA_OFF);
digitalWrite(Keta2Seg, LED_KETA_OFF);
digitalWrite(Keta3Seg, LED_KETA_OFF);
digitalWrite(Keta4Seg, LED_KETA_ON);
}
// 数字振り分け .
void DigitDisp(int aNum)
{
int lDigit = aNum % 10;
switch(lDigit)
{
case 1:
one();
break;
case 2:
two();
break;
case 3:
three();
break;
case 4:
four();
break;
case 5:
five();
break;
case 6:
six();
break;
case 7:
seven();
break;
case 8:
eight();
break;
case 9:
nine();
break;
case 0:
default:
zero();
break;
}
}
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
// DisplayFunction.hファイル
/* *** Define 定義 *** */
// A
// ----
// F | G |B
// ----
// E | |C
// ---- . Dot
// D
const int ASeg = 13;
const int BSeg = 12;
const int CSeg = 11;
const int DSeg = 10;
const int ESeg = 9;
const int FSeg = 8;
const int GSeg = 7;
const int DotSeg = 6;
const int Keta1Seg = 5;
const int Keta2Seg = 4;
const int Keta3Seg = 3;
const int Keta4Seg = 2;
const int LED_ON = LOW;
const int LED_OFF = HIGH;
const int LED_KETA_ON = HIGH;
const int LED_KETA_OFF = LOW;









