第3回:Spresenseでラジコンカーを作ろうPart② -プログラミングに挑戦-
Let‘s Spresense ~文系営業マンのプログラミング奮闘記~ のバックナンバーはこちら
本連載は、ソニーセミコンダクタソリューションズ(以下:ソニー)よりリリースされているSPRESENSE™を使って実際の営業活動に携わっている(株)レスターエレクトロニクス・(株)レスターマーケティングの若手社員3名がプログラミング初心者ながらデモ機を制作する過程を描いた連載記事になります。
今回制作したデモ機の展示を予定しておりました、「メイカーフェア京都2020」は
コロナウイルスの影響で開催中止となりました。
なお展示会の中止に伴い、5月2日(土)に「Maker Faire Kyoto Online」というイベントが開催されることとなりました。本イベントの詳細は下記リンクよりご確認頂ければと思いますがTwitterを使ったイベントとなっております。
そして、本連載記事の作品もSpresenseの公式Twitterアカウント上で公開を予定しておりますので楽しみにして頂ければと思います!
デモ機の公開など詳細情報は、本記事の最後に記載しているのでご確認下さい。
イベント情報 :Maker Fair Kyoto Online
Spresense公式Twitterアカウント: @SpresensebySony
🔶目次
- 初めてのラジコンカー組み立て!
- プログラミングに挑戦!
▷Arduino環境でのプログラミング
▷そもそも“関数”って?
▷setup()関数について
▷loop()関数について - Spresenseでラジコンカーを動かしてみる!
▷実際のスケッチで確認
▷サンプルスケッチの確認
▷サンプルスケッチをアレンジする
▷変数とは?
▷「グローバル変数」と「ローカル変数」
▷制御構造とは? - 次回予告
①初めてのラジコンカー組み立て!
―ラジコンカーは1/10サイズの市販品を購入しました。全員が開封した瞬間、部品数の
多さに驚きました(笑)。説明書を眺めて頭を抱えながらも制作を進めました。
―制作すること数時間、ようやく車体が形として分かるようになってきました!
そして付属のプロポを使うことで車体が動くところまで何とかこぎつけました。
②プログラミングに挑戦!
▷Arduino環境でのプログラミング
―はじめにArduino環境でプログラミングを行う際の、基本的な決まり事について
調べたものを下図でまとめさせて頂きました。
◆Arduinoでプログラミングを書く際の決まり事▷基本的には半角で入力する。
▷半角カナは使わない。
▷大文字、小文字は区別して書く。
▷1つの文の終わりには「 ; 」をつける。
▷コメントは「 // 」の後に書く。
→コメント欄は、日本語で書いても良い。
上記記載内容を頭において、進めていきましょう!
―実際にインストールすると下記図1のような画面が表示されます。
次にAruduinoの基本構造のsetup()関数とloop()関数について簡単に説明させて
頂きます。
図1
▷そもそも“関数”って?
―関数とはプログラミングにおいて、あるきまった処理を記憶しておく機能の事を
意味します。
例えば、私たちが生活している中でもあるきまった動作があります。
◆会社員の場合…
- 朝起きます。
- 顔を洗い、歯を磨きます。
- 着替えてから朝食を食べます。
- 電車に乗って通勤し、出社します。
上の図では、会社員の日常の動きを簡単に記しておりますが読者の皆様にも決まった
日常の流れがあるかと思います。
プログラミングをする際にも、一連の決まった処理を記憶しておくと便利です。
そのようなきまった処理をまとめて記憶しておくのが関数の役目です。
―またArduinoでは、書いたプログラムの事を「スケッチ」とよびます。
▷setup()関数について
―1行目のvoid setupと記載されています。
setup()関数は、Spresenseメインボードに電源が入りボードが起動した時に、
最初に1回だけ呼ばれる処理のことを指します。
setup()関数内ではピンの状態の設定や、シリアル通信の初期設定などを行います。
2行目の//より後の“put your setup code here, to run once:”とこの関数内での説明が
記載してあります。
決まりごとの欄にもある通り、Arduinoでは//より以後の文章は
プログラミングに反映されません。
▷loop()関数について
―loop()関数は名前の通り、関数内の処理をループし続ける関数です。
Arduinoメインボードに電源が入って起動し、setup()関数の処理が終わったら、
電源が切れるまでこの関数内に書いてある処理を繰り返し実行します。
このloop()関数がArduinoのプログラムのメインとも言えます。
ここでも、//の直後に”put your main code here, to run repeatedly”とコメントが記載されております。
―またArduinoでは、必要な制御を実行するために様々な関数が用意されています。
下記に関数の説明やその他の細かいルールについてなどの情報などをまとめている
サイトのリンクを貼り付けておりますので、こちらのサイトなども参考にして頂ければと思います。
参考:Arduino日本語リファレンス:http://www.musashinodenpa.com/arduino/ref/
★初心者の気づき
▷実際のスケッチで確認
―今回は、第1回の記事で動作確認した際の“Lチカ”のスケッチをもとに
これまでの内容のおさらいをしていきましょう。
ソースコードはこちらからダウンロードできます
―図2のsetup()内では、2行目に“pinMode”という関数を使っています。
“pinMode”はピンの動作を入力か出力に設定をする関数になります。
2行目では、pinModeの後に(LED0,OUTPUT);となっております。
ここではLED0のPINを出力設定にすると決められます。
3行目~5行目も同様に、各PINの出力設定になります。
―次にloop()内では、“digitalWrite”と”delay“という2つの関数を用いています。
loop内の動作の流れとしては、下記のようになります。
loop()内の概略図
- 9行目でLED0ピンが出力されている状態になります。
↓ - 10行目ではプログラムを指定した時間だけ止めます。
→delay関数の単位はミリ秒となっており、ここでは0.1秒の設定になります。
↓ - 11行目ではLED1ピンが出力されている状態になります。
→ここでLED0ピンからの出力はされていない状態になります。
↓ - 12行目~25行目についても同様の流れにもなります。
③Spresenseでラジコンカーを動かしてみる!
―SpresenseのArduinoライブラリには、サンプルスケッチが多く用意されています。
GNSS情報の取得やカメラボードの機能が使えるサンプルなども存在します。
今回はPWMを使って、サーボモータの制御が行えるサンプルを参考にしながら
実際にラジコンカーを動かしていきたいと思います。
▷サンプルスケッチの確認
―①画面上の左上にある「ファイルタブ」を選択します。
②ファイルタブ選択後、「スケッチ例」という項目を選択します。
③既にSpresenseでの環境構築済みの場合は、スクロールしていくと
「Spresense用のスケッチ例」という項目が表示されます。
その項目内の「Servo→Servo」を選択します。
図3
↑上記①~③の内容を表したものになります。
―まずは実際に、このサンプルスケッチを使ってSpresenseとラジコンカーを
つないだ場合にサーボモータが動くかを確認していきましょう。
参考:https://developer.sony.com/ja/develop/spresense/specifications
―Spresenseのデベロッパーサイトの製品仕様欄を選択後、下にスクロールしていくと
各製品の仕様とピンの割り当て表が掲載されています。
今回は、メインボードとLTE拡張ボードを使っていくので
下記2つの図を参考にピンの割り当てを行います。
◆メインボードピン割り当て表
◆LTE拡張ボードピン割り当て表
▷サンプルスケッチをアレンジする
―今回はプロポの代わりにLTEを用いて、LTEからステアリングの操作とスピードの操作
を行いたいと考えているので、プログラムを3つのステップに分けて考えてみました。
- LTEからステアリングの操作情報とスピードの操作情報を送ってもらう。
- 送ってもらったステアリングの操作情報に応じて、ステアリングサーボを
コントロールする。 - 送ってもらったスピードの操作情報に応じて、スピードモーターを
コントロールする。
この3つの機能をそれぞれ関数にしてみました。
- ltereceive_control()関数
- stearing_control()関数
- speed_control()関数
この内容をもとに実際にサンプルスケッチをアレンジしてみました。
書いたのが以下のスケッチになります。
ソースコードはこちらからダウンロードできます
様々なHPの情報などをもとにアレンジを行いました。
要点ごとにスケッチの説明をしていきます。
◆1行目:#include
→Arduinoリファレンスにあるサーボのライブラリをインクルードします。
(使える状態にします/設計図面を用いるイメージ)
◆5/9行目:int stear_pos;
→「変数」と呼ばれるものになります。
▷変数とは?
変数は、簡単に説明をすると様々なデータを保存しておくことができる箱のような
ものをイメージしてください。
intは変数名を定義するときに保存するデータの型を定義しています。
▷「グローバル変数」と「ローカル変数」
・グローバル変数
関数のプログラムの外で定義されたものになります。全ての関数から参照が
できるものになっており、プログラムのどこでも使えるというイメージです。
ここでは、「stear_pos」がグローバル変数になります。
・ローカル変数
関数のプログラミング内で定義されたものになります。宣言された関数内でのみ
参照されます。その関数内でのみ使える変数というイメージです。
◆17行目:void setup()~
→ステアリングとスピードの初期設定を行うイメージです。
電源が入った時に、どのような状態でスタートするかをイメージします。
(ここでは、タイヤは直進方向で停止している状態)
◆19行目:stear_servo.attach(PIN_D06);
→Spresenseの6番ピンにサーボモータが接続されていると指定しています。
今回はステアリングのサーボの操作を基板のD06を使ったので、
D06ピンを示すプログラム上の名前PIN_D06を指定しています
◆28行目~
→ここでは、今後実行したい内容も記載しておりLTEの通信機能については
このスケッチには記載されていません。
◆42行目~:if/else
▷制御構造とは?
setup()関数は1度、loop()関数は繰り返し行われるというものですが、これだけだと
決まりきった動作しかできません。もう少し複雑な動作を実現するために
「制御構造」というものがいくつか用意されています。
・if構文
特定の条件を満たしたときにだけ実行したい処理を定義するための構文です。
書き方としては、
if (条件式) {
条件を満たしたときの処理
}
となります。かっこ内で囲まれた条件式を満たす時だけ、この中に書いた処理が
実行されるので、条件が満たされない場合は処理がスキップされます。
・else
文には後ろにelseという構文を追加することができます。これは逆に「条件を満たさなかった場合」の処理で「もし~ならこう、そうでなければこう」という場合分けを
書く際便利な書き方です。
if (条件式){
条件を満たした時の処理
} else {
条件を満たさなかった時の処理
}
となります。
◆82行目:void loop~
→最後に38行目~80行目で定義した、3つの処理を繰り返すようになっています。
④次回予告
今回は、ラジコンカーの組み立てからプログラミングを学び実際にSpresenseで
ラジコンカーを動かす事が出来るようになりました!
現時点でのデモ機を、5月2日(土)14:00~15:00頃でソニーのSpresense公式アカウント上で公開を予定しております。
Spresense公式Twitterアカウント: @SpresensebySony
ぜひ、“リツイート”/“いいね”で皆様からの情報発信もして頂ければと幸いです!
よろしくお願いします! #Spresense
次回は、LTE拡張ボードを使って通信を行い、送信機とラジコンカーを接続出来ればと
考えております。難しいチャレンジになるかと思いますが乞うご期待!!
今回の記事を見て、一度Spresenseを使ってみたい方や追加でボードが欲しいという方は
下記URLよりお進み下さい。
(ご購入はコチラから:https://developer.sony.com/ja/develop/spresense/buy-now)