Arduino IoT ~Arduino IDEの使い方~

イントロダクション

昨今、IOTという言葉が使われるようになって久しいですが、「IOTとはなんぞや?」という疑問がぬぐえないのも一つの現実ではないでしょうか?

抽象的なんですね。「インターネットに接続できる小物関連なら何でもいいんじゃね?」と思って間違いないのでは?
こちらのページを見てみると、次のように書いています。

IoT:Internet of Thingsにより、インターネット経由でセンサーと通信機能を持ったモノ達、例えば、ドアが「今、開いているよ。」、工場内の機械が「調子が悪いよ。故障しそうだよ。」、植物が「水が欲しいよ。」、猫の首輪が「今トイレにいるよ。」等とつぶやき始めるのです。これらの情報をインターネットを介し様々な場所で活用することができます。

早い話が、「詳細な定義はない」という認識です。「ネットにつながる何か?」がIOTということになります。

Arduino + Java(できない)

自分はJava言語を主に学習しているので、Java言語でいろいろとやりたいと思っているのですが、Java + 電子工作というのがなかなかできませんでした。

しかし、最近は、いろいろとツールがあるようで。。。早速実践したいと思います。

Arduino クラウド

最近の流行なのか「クラウド」というものがよく使われるようです。確かに、使用するPC毎に開発環境を作るのも大変です。
ならば、ブラウザで開発できれば早いですよね。
ということだと思います。ここからアクセスできるので、いろいろと調べていきます。

Firmataについて

Firmataというプロトコル(通信するときに使用するもの(http,ftpなど))の一つでArduinoと通信する。
主に以下の二つの機能があるようです。

  • Arduino デバイスとホスト コンピューターで実行されているソフトウェアとの間でデータを選択的に送受信します。
  • StandardFirmata と呼ばれる汎用スケッチ (または必要に応じて StandardFirmataPlus や StandardFirmataEthernet などのバリアントの 1 つ) を Arduino ボードにロードし、ホスト コンピューターを排他的に使用して Arduino ボードと対話する

Firmata4jを使う

よくよく調べてみるとFirmataは、PCなどからArduinoにメッセージを送って操作する、リモコンのような機能の実装に使用するプロトコルらしいのと、動かせなかったのを踏まえて、Arduino言語での実装を行うことにしました。
Firmataというプロトコルがあるようなので、これを使用してLチカをしたいと思います。
上記のリンク先には、下のような手順が示されているので、それに従います。

ArduinoでFirmataプロトコルを使用してホストコンピュータとやり取りする場合は、ArduinoIDEを立ち上げて、ファイル -> スケッチの例 -> Firmata -> Standard Firmata を選択、開きそのままArduinoに書き込めば良いです。

まずは、Arduino IDEが必要なので、これをインストールします。しかし、ブラウザでIDEが使えるようなのでウェブエディタのほうを使用することに会います。

次は、Javaプログラムを実行するのですが、バージョンが2.3.1以上である必要があるらしく、まぁ動かなかったので。。。

Arduinoの実装

Javaを使いたいという思いをあきらめて、そのままC言語のような
C言語のようなコードで実装することにします。Arduino言語というようです。
ちなみに、Lチカをやってみました。
コードとしては、下のようなものです。

#define LED_PIN 13
#define WAIT_TIME 1000

void setup() {
  pinMode(LED_PIN,OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN,HIGH);
  delay(WAIT_TIME);
  digitalWrite(LED_PIN,LOW);
  delay(WAIT_TIME);
}

プログラムの内容としては、リファレンスにありますが、大まかに自分の理解している部分を解説すると以下のようになります。

Arduinoプログラム

まずは、「setup()」が動いて「loop()」がループして待機処理をするような感じです。
そして、定数としてはつぎのように解説がありました。
#define

#defineで定義された定数は、コンパイル時に値へと置き換えられ、チップ上のメモリ(RAM)を消費しません。

#include

#includeは外部のライブラリ(あらかじめ用意された機能群)をあなたのスケッチに取り入れたいときに使います。

制御文

Javaプログラムをやっているひとであれば、なじみのある構文になっています。C言語とほぼ同じです。

if (someVariable > 50) {
  // 条件を満たしたとき実行される文
}

// if-else
if (pinFiveInput < 500) {
  // 動作A
} else {
  // 動作B
}

For文

int PWMpin = 13;
for (int i=0; i <= 255; i++){
    analogWrite(PWMpin, i);
    delay(10);
}

関数の定義もC言語と同じようです。

返却値 関数名(引数)

// 足し算する関数
int tashizan(int left, int right) {
   return left + right;
}

ここまで、C言語とそっくりなのであれば、Java言語に慣れ親しんでいる人であれば、すぐに使えると思います。
注意点としては、Arduino言語には、すでに実装されている関数が多数あるので、それをうまく使うようにする、というところです。

Arduino IDE

デスクトップ版と、クラウド版があるようです。昔は、寄付とか要求されずにデスクトップ版がダウンロードできたのですが、
今はクラウド版でやるのがよろしいようで。。。

Arduinoの公式サイトにアクセスして、クラウドの利用をするためのサインアップを行い、クライアントアプリをインストールすれば使用できるようです。

ウェブエディターを使う

最近では、フツーになったのでしょうか?ウェブでコーディングできるのでPCはなんでもよさそうです。
余談ですが、自分のPCにArduinoを接続したらこんな感じでした。

## Javaコードを作成する
IntelliJ IDEAを使用しているので、次のような形でJavaプロジェクト作成しました。
![](http://zenryokuservice.com/wp/wp-content/uploads/2021/08/arduino2.png)
POMファイルは、下のように追加修正しました。
```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>ArduinoPractice</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>com.github.kurbatov</groupId>
<artifactId>firmata4j</artifactId>
<version>2.3.8</version>
</dependency>
</dependencies>
</project>
```
これでプロジェクトをリロード(Mavenリロード)すれば、必要なライブラリはOKです。

## インストール(デスクトップ)
[こちらのリンクから](https://www.arduino.cc/en/software/)ダウンロードできます。
そして、インストールが終わったら、使い方を学びます。

[参考サイトはこちら](https://www.indoorcorgielec.com/resources/arduinoide%E8%A8%AD%E5%AE%9A/arduino-ide%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%A8%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC/)です。

## シリアル通信を行う
初めの一歩として次のようなプログラミングを行います。
<**シリアル通信**(ケーブルを使った通信)>
接続したArduinoとPCの間でデータの通信を行います。技術的には基本的(低レベル)なデータ通信方法です。
この通信ができるということは、「ArduinoとPCがつながっています」という確認ができて、プログラムが動いていることの結果をPC上でそれを見ることができるということです。

<まとめ>
PCでArduinoの動きを確認するためにPCと接続して通信の結果をPCに表示するということです。

というわけで、細かいところを見ていきます。

## Arduino IDEの使用
【前提】
* スケッチ:プログラムを書くためのファイル
* Arduino IDEを開くと下のように開発するためのフォルダ構成が作られます。
 ![](http://zenryokuservice.com/wp/wp-content/uploads/2021/08/ArduinoIDE2.png)
![](http://zenryokuservice.com/wp/wp-content/uploads/2021/08/ArduinoIDE1.png)
* この構成と呼んだものは単純にフォルダがあるだけです、必要なものはこの場所に作成されます。
* 作成したものは最終的にArduinoに書き込まれます。

## 実装(コードを書く)
参考サイトにあるコードをとりあえず書いてみます。
どのプログラミングでもまずは、動くコードを書き写して、それから実行、書いている内容を理解するというような順序で学習していきます。

これになれると、プログラミングの学習も早くなり、最終的には、どの言語でも大体読めるようになってきます。

### 写経(書き写し)した内容
```clang
int counter = 0; // counterという名前の変数を用意して、0をセットする

void setup() {
// 起動後、この中の内容が上から順に1回実行される
Serial.begin(115200); // シリアル通信の準備をする
while (!Serial); // 準備が終わるのを待つ
Serial.println("プログラム開始"); // シリアル通信でメッセージをPCに送信

// 最後まで実行された後はloop関数に移行する
}

void loop() {
// setup関数が終了すると、この中の内容が上から順に何度も実行されつづける

Serial.print("カウンターの値 "); // シリアル通信でメッセージをPCに送信
Serial.println(counter); // シリアル通信でカウンターの値をPCに送信
counter = counter + 1; // カウンターの値を1増やす
delay(1000); // 1000ミリ秒(1秒)待機

// 最後まで実行された後はloop関数の先頭に戻る
}
```
これが書けたら、IDEから検証ボタンを押下して動くかどうかテストします。
![](http://zenryokuservice.com/wp/wp-content/uploads/2021/08/ArduinoIDE3.png)

これでコードがうまくコンパイル出来たら、動かす準備はOKです。

ちなみに「コンパイル」というのは、プログラムコードを機械語に変換する処理のことです。

# TFT LCDディスプレイを表示する
[こちらのサイト](https://ht-deko.com/arduino/shield_tftlcd.html)にあるようなものを使用しました。
このタイプのものは、Arduinoに直接続々出来るようで、GPIOピンを直接かぶせるように接続できました。

そして、参考にしたのは[こちらのサイト](https://learn.adafruit.com/2-8-tft-touch-shield/overview)です。このサイトにはTFTLCD touch shieldを使用した操作、実行方法の手順がかいてありました。
あと、下のような注意があったのでこれも注意します。
![](http://zenryokuservice.com/wp/wp-content/uploads/2021/08/TFTLCD1.png)

早速進めることにしますが、以下の手順を行いました。
1. ArduinoIDEでライブラリをインストールする
* Adafruit GFX library
* Adafruit TFTLCD library
2. プログラムコードを修正する
* Adafruit_TFTLCD.h

### 具体的にどうやったか?
ライブラリがインストールした前提で話を進めます。
下のように、ドキュメントフォルダの下に「Arduino」フォルダがあるのでその下に入っていきます。
![](http://zenryokuservice.com/wp/wp-content/uploads/2021/08/TFTLCD2.png)

この様に入っていき「Adafruit_TFTLCD.h」というファイルがあるのでそのファイルにある
> //#define USE_ADAFRUIT_SHIELD_PINOUT

と書いてある部分を修正して、次のようにします。
> #define USE_ADAFRUIT_SHIELD_PINOUT

具体的には、下のようなコードになっています。
```clang
// IMPORTANT: SEE COMMENTS @ LINE 15 REGARDING SHIELD VS BREAKOUT BOARD USAGE.

// Graphics library by ladyada/adafruit with init code from Rossum
// MIT license

#ifndef _ADAFRUIT_TFTLCD_H_
#define _ADAFRUIT_TFTLCD_H_

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <Adafruit_GFX.h>

// **** IF USING THE LCD BREAKOUT BOARD, COMMENT OUT THIS NEXT LINE. ****
// **** IF USING THE LCD SHIELD, LEAVE THE LINE ENABLED: ****

// この部分を修正しました。
#define USE_ADAFRUIT_SHIELD_PINOUT 1

class Adafruit_TFTLCD : public Adafruit_GFX {

public:
Adafruit_TFTLCD(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst);
Adafruit_TFTLCD(void);

void begin(uint16_t id = 0x9325);
void drawPixel(int16_t x, int16_t y, uint16_t color);
void drawFastHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color);
void drawFastVLine(int16_t x0, int16_t y0, int16_t h, uint16_t color);
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t c);
void fillScreen(uint16_t color);
void reset(void);
void setRegisters8(uint8_t *ptr, uint8_t n);
void setRegisters16(uint16_t *ptr, uint8_t n);
void setRotation(uint8_t x);
// These methods are public in order for BMP examples to work:
void setAddrWindow(int x1, int y1, int x2, int y2);
void pushColors(uint16_t *data, uint8_t len, boolean first);

uint16_t color565(uint8_t r, uint8_t g, uint8_t b),
readPixel(int16_t x, int16_t y), readID(void);
uint32_t readReg(uint8_t r);

private:
void init(),
// These items may have previously been defined as macros
// in pin_magic.h. If not, function versions are declared:
#ifndef write8
write8(uint8_t value),
#endif
#ifndef setWriteDir
setWriteDir(void),
#endif
#ifndef setReadDir
setReadDir(void),
#endif
#ifndef writeRegister8
writeRegister8(uint8_t a, uint8_t d),
#endif
#ifndef writeRegister16
writeRegister16(uint16_t a, uint16_t d),
#endif
writeRegister24(uint8_t a, uint32_t d),
writeRegister32(uint8_t a, uint32_t d),
#ifndef writeRegisterPair
writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d),
#endif
setLR(void), flood(uint16_t color, uint32_t len);
uint8_t driver;

#ifndef read8
uint8_t read8fn(void);
#define read8isFunctionalized
#endif

#ifndef USE_ADAFRUIT_SHIELD_PINOUT

#ifdef __AVR__
volatile uint8_t *csPort, *cdPort, *wrPort, *rdPort;
uint8_t csPinSet, cdPinSet, wrPinSet, rdPinSet, csPinUnset, cdPinUnset,
wrPinUnset, rdPinUnset, _reset;
#endif
#if defined(__SAM3X8E__)
Pio *csPort, *cdPort, *wrPort, *rdPort;
uint32_t csPinSet, cdPinSet, wrPinSet, rdPinSet, csPinUnset, cdPinUnset,
wrPinUnset, rdPinUnset, _reset;
#endif

#endif
};

// For compatibility with sketches written for older versions of library.
// Color function name was changed to 'color565' for parity with 2.2" LCD
// library.
#define Color565 color565

#endif
```

そして、書き込み開始!!!

しかしエラー!

原因は何か?

出力ポートを間違えていました。「Arduino」と書いてあるポートを選択しましょう。

追伸:電源はUSB電源ではなくDC電源を使用しないとディスプレイは移りませんでした。。。。

でわでわ。。。