2020年6月27日土曜日

【Arduino】delay関数を使わないLチカ

こんにちは。そろそろ遠隔授業に疲れてきたたかみやです。

みなさんは、Lチカってご存じですか?知らない方はいませんよね(強引)

LEDを点滅させる「Lチカ」は、Arduinoのチュートリアル的存在としても知られています。
新品のAVRにブートローダーを書き込んだ時なんかの動作確認にも用いられますよね

そんなLチカに関してですが、僕は最近、こんなものを書きました。Bloggerへのコードの張り方がわからないので画像で失礼しますが...
これ、なんだか分かります?実はこれも「ただのLチカ」なんです。このスケッチの動作自体は、Arduino IDEのスケッチ例に入っている「Blink」と全く同一です。

delay関数を使わない代わりに、millis関数を使って計時しているのがこのスケッチの特徴です。計時中もloop関数は常に実行されているので、計時しながら別の処理を実行させることができるのも特徴です。

実はこのLチカは、delay関数を使えばこんな風にシンプルに書くことができます。
非常に簡単ですね。
じゃあ、いつもdelay関数を使えばいいのでは...と思うかも知れませんが、そういうわけにはいきません。
delay関数は、指定した時間だけ、(ほとんど)すべての処理を止めてしまう関数です。ms単位で指定するので、引数に1000を指定すれば、1000ミリ秒=1秒間もの間、すべての処理が止まってしまうことになります。
Lチカの場合はLEDを光らせることにしかマイコンを用いていないので無問題ですが、マイコンで様々な情報を処理させたり、複数の表示デバイスを同時に用いたり、スイッチやセンサからの入力をリアルタイムで監視する場合など、delay関数が問題になる場面は多いのです。
そんなわけで、なるべくdelay関数を排除してプログラミングできないか、最近は模索するようにしています。今回のLチカプログラム「Blink_NoDelay」はその一環です。

ちなみに先ほどのLチカですが、pinModeやdigitalWrite関数などをAVR寄りに置き換えるとこういう書き方もできます。名付けて「Blink_NoDelay_HS」。HSは「High Speed」の略で、プログラムの動作を高速化させたという意味合いで付けた名前です。
この手法はマイコンの動作を高速化できる手法として知られていますが、スケッチの容量削減にも一役買ってますね。標準的なblinkスケッチが924バイトもあるのに対し、こちらはコードがゴリゴリ記述されているにもかかわらず、654バイトしかありません。
ちなみに先ほど説明した「Blink_NoDelay」は936バイトと、標準的なblinkスケッチよりもスケッチのサイズが大きくなってしまっています。pinModeやdigitalWrite関数を省いたことでスケッチの容量を削減できたことは明らかです。

ところで、なんでこの期に及んでLチカなんか書いているんだい?と思われるかも知れませんが...
実は実家に帰省していて、ArduinoとPCだけ実家に持って帰ってきたんですが、他の電子部品を全部アパートに置いてきたので、電子パーツを使った工作が全然できない状況なんです。
そのため、他の電子部品を一切使わないようなプログラムを書いたりして、気晴らしをしています。
Arduinoに2次方程式を解かせたり...

Arduinoに5元連立1次方程式を解かせたり...

とにかく色々やって遊んでます。まあ、C言語の練習かな。
2次方程式を解くプログラムはオリジナルですが、連立方程式はQiitaに掲載されていたプログラムをほぼ流用しています。
今までJavaでプログラミングを学んでいたので、C言語は訳が分からなくて苦労していますが、少しずつ慣れていけたらなと思います。

---- おまけ(三角関数を含む総和計算) ----
Arduino、何やってもめちゃくちゃ高速に演算して結果返してくれるので、ヤケクソになって「とにかく時間かかる演算ばかりさせてCPUパワーを消費してやるー!」と思い、こんな計算をさせてみました。この計算はATmega328Pにはしんどいようで、約2.8秒かかるという結果に。ですがよく考えてみると、16MHzのCPUでここまでできれば、まあ優秀ですよね。
ちなみに、計算に使用した数式ですが、以下のサイトで紹介されていたものを利用しました。

2020年6月5日金曜日

秋月のATmega168/328ボードが完成した!


じゃーん!できたー!!!
まともにはんだ付けするのがものすごい久々なので、部品の実装がめちゃくちゃ雑になっちゃいました。各方面から怒られそうなはんだ付けですが、これでも「めっちゃ丁寧にやったつもり」なんです許してください!

組み立てで難しかったのは、はんだ付け前の部品の固定でしょうか。特に1列のピンヘッダーとかピンソケットが動かないように固定するのが難しいです。多分、他の部品を実装する前にまずピンヘッダーやピンソケットを実装してしまったほうが楽に作業できるのではないでしょうか。

組み立てる上でのこだわりポイントは、基板上のLEDの配色です。このキットには元々赤色LEDが4個付属してくるのですが、自分は純正のArduino UNOに合わせて、電源LEDをグリーン、それ以外のLED(Tx, Rx, L)をイエローにしました。LEDのVfが2.1V前後で、数mA程度の電流を流せるものであれば、特になにもしなくてもポン付けできると思います。

このキットを組む上で避けては通れないのが、FuseBitとブートローダーの書き込みです。
FuseBitは、いわばマイコンに対する初期設定のようなものです。マイコンの動作条件などを指定します。ブートローダーは説明が難しいですが、簡単に言えば「Arduinoのスケッチを読み込むための下準備」といった感じです。

これらの初期セットアップをするためには様々な方法があります。
正攻法では、AVRISPmkIIという書き込み装置と、Atmel Studio 7という統合開発環境を使い、PCからマイコンにプログラムを書き込める環境を用意します。ですが、AVRISPmkIIは入手が今のところ困難なようですし、書き込み装置を別途用意するのはお手軽ではありません。
このため、ボードに標準搭載されているUSB-シリアルインターフェース "FT232RL" を使った、Bitbangと呼ばれる書き込み方法がお手軽です。
ですが、個人的にハマった点が、Atmel Studio 7はどうやらFT232RLからのBitbang書き込みには対応してなさそうなんです。悪戦苦闘の末、Atmel Studio 7を使うのは諦めました。

結局のところ、以下のURLで紹介されている手法を用い、AVRdude-serjtagを使ったBitbang書き込みを行いました。
外付けAVRライタ無しでBootloaderを書き込む - kosakalab
Bootloaderファイルは、Arduino IDEをインストールするとついてきます。

また、以下のサイトも参考とさせていただきました。助かりました。

ちなみにこれは耳寄り情報なのですが、既に動作するArduino(もしくはその互換機)を持っていれば、Arduino as ISPという機能を使って、Arduino(もしくはその互換機)同士を接続してブートローダーやスケッチの書き込みができるようです。結構簡単に扱えるので苦労も少ないかもしれません。
そういう面では、このキットは既にArduinoを持っている人が2台目3台目として組み立てるのに向いているとも言えそうです。

完成したキットでLチカをしたり、LCDで遊んでみたりしましたが、それは別の記事として書くことにします。
いやあ、マイコン遊びは超楽しいです。

ATmega328P-PUを最小構成で動かす

最近、空き時間にAVRマイコンで遊んでいるのですが、Arduinoボードのように周辺機器や回路を満載せず、最小構成で動かしたいと感じることがあります。 Arduinoボードには、USB-シリアル変換インターフェース、5Vおよび3.3V定電圧電源、水晶発振子やセラミック発振子、電源...