通信はほかのディバイスとのデータの送受信になります。
パソコンなどとの通信にはシリアル通信,近くにある機械との通信はI2C・SPIがあります。電波による通信はBluetooth・wifiがあります。赤外線や超音波による通信もあります。
通信ということはデータの送受信なので入出力の全てが通信になります。
ここではシリアル通信について学んでいきたいと思います。
パソコンと通信 送信
せっかくパソコンとつながっ ているのですからパソコンと通信できるようにしたいと思います。しかも用意する物は何も有りません。パソコンとはプログラムの転送のため,すでにUSBケーブルでつながれています。
Arduinoが何を言ってくるか見るためにシリアルモニタを使います。
シリアルモニタ

serial01
1
2
3
4
5
6
7
8
//初期設定
void setup() {
Serial.begin(9600);//serial初期化
}
//繰り返し
void loop() {
Serial.write("Hello");
}
スケッチ
HelloHelloHello
送信
シリアル通信は初期設定のvoid setup(){の3行目のSerial .begin(9600);で始めることができます。
void loop(){の中でSerial.write()の()内に通信したい文字を""でくくって入れます。
改行
しかし横に流れてしまいます。そこでwriteの代わりにprintlnとします。すると改行してきれいに表示されます。writeとprintはあまり変わらない様ですが,lnはprintにしか付けることはできません。
送信
serial02
//初期設定
void setup() {
Serial.begin(9600);//serial初期化
}
//繰り返し
void loop() {
Serial.println("Hello");
}
Hello
Hello
Hello
改行されて見やすくなりました。
ただし,ものすごい速さで「Hello」を送信してくるので,それこそ目にも止まりません。
writeとprintの違い
lnが使えるのはprint文です。普通はprintを使います。Serial.write( )はByteを扱います。
パソコンと通信 受信
serial03
1
2
3
4
5
6
7
8
9
10
//初期設定
void setup() {
Serial.begin(9600);//serial初期化
}
//繰り返し
void loop() {
byte m;
m=Serial.read();
if(m!=255){Serial.println(m);}
}
通信を使えるようにするのは送信の時と同じです。
受信ですから何が送られてくるのかわかりません。そこで,送られてきたものを受け入れる容器を用意しましょう。一応文字だということにします。1文字ならば1byteの容量でいいと思います。7行目でmという変数をbyteの仕様にします。8行目でmにシリアル通信で得た値を入れます。データの通信は数字で行われます。何もしなければmは255になっています。ですから,mが255でない時だけmを返せばいいのです。
if文(もし~ならば)!は無いまたは違うの意味
最後の行は,もしmが255でない時は{}内を実行せよということです(マルチステートメントになっています)。
mを送信します。ただし,mそのものではなくてmの数字です。
たった10行のスケッチですがプログラムらしくなってきました。
行番号があると説明がわかりやすくなります。
ファイル→環境設定→行番号を表示するとします。
文字列の受信
一文字を受信することは簡単にできますが,文字列の受信には工夫が必要です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//宣言
//初期設定
void setup() {
Serial.begin(9600);//serial初期化
}
//繰り返し
void loop() {
int i=0;//文字数をカウント
char str[100]="";//文字を記憶する変数,初期化
while(Serial.available()){//読み込む文字があれば
str[i]=Serial.read();//i番目の文字として入力
delay(10);//通信のための時間
i++;}
if(i!=0){
Serial.println(str);}//送信
}
Serial.available( );でバッファに文字があることを確かめ,存在する場合char str[ ]="";で確保した変数に入力していきます。32文字までは読み込めます。
String str;
str=Serial.readString();は少し遅いのですが簡単です。
11行目のchar str[100]="";の=""を省略すると文字が残ってしまいます。
14行目のdelay(10);を書かないと文字の読み込みに失敗してしまいます。"";
Hexデータを配列にする
char_num_00_03
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void setup(){//初期化
Serial.begin(9600);
Serial.println("Ready");
}
void loop() {//繰り返し
int hex=0xaa;//Hexデータ
int bin[]={0,0,0,0,0,0,0,0};//配列
for(int i;i<8;i++){//変換
int a=hex/2;
bin[7-i]=(hex-a*2);
hex=a;
}
for(int i;i<8;i++){//通信・表示
Serial.print(bin[i]);
}Serial.println();
delay(1000);
}
Hexデータを0,1の配列に格納し直します。
RaspberryPiの場合

I2C通信
I2C接続で動作するLCD
2017年7月1日
比較的近い距離にあるディバイスとの通信に使われる2線式(2線+VCC+アース)通信です。
ACM1602NI
I2C 16×2 LCDキャラクタディスプレイ

I2Cアドレス
I2Cアドレスは0x50です。データシート7.0.3の2行目から3行目に
Only one 7-bit slave addresses (1010000) is reserved for the LCM 0x 5 0
と書いてあります。
Arduinoとの接続
VSSはGND,VDDは3.3Vまたは5Vです。
BL+とBL-でバックライトLEDを点灯します。
VOはコントラスト調整です。
SCLは1番pin,SDAは2番pinへプルアップして接続します。

コントラストは液晶側にVRを付けてもいいと思います。プルアップはArduino側ですね。RTCには10Kのプルアップが付いているので必要ありません。
サブルーチン
I2C_LCD
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
#include <Wire.h>//I2C接続
void setup() {//初期設定部
}
void loop() {//繰り返し部
}
//関数・サブルーチン
void writeCmd(byte cmd){//コマンド送信
Wire.beginTransmission(0x50);
Wire.write(0x00);//第1BYTE
Wire.write(cmd); //第2BYTE
Wire.endTransmission();//ストップ
}
void writeData(uint8_t dat){//データ送信
Wire.beginTransmission(0x50);
Wire.write(0x80);// 第1BYTE
Wire.write(dat); // 第2BYTE
Wire.endTransmission();//ストップ
}
これら2つのサブルーチンを書いておけばほとんどの動作をさせることができます
コマンド
インストラクション
インストラクションコード
RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0
0
0
0
0
0
0
0
0
1
カーソル0,0
RAM読み込み
RAM書き込み
フラグ読み込み
DDRAMアドレス
CGRAMアドレス
機能設定
カーソル 表示
表示On,Off
モードセット
表示初期化
0
0
0
0
0
0
0
0
1
-
0
0
0
0
0
0
0
1
I/D
S
↑ ↑
↑拡張表示
カーソル移動方向
1インクリメント
0デクリメント
0
0
0
0
0
0
1
D
C
B
↑ ↑ ↑
↑ ↑ ブリンク
↑ カーソル表示
ディスプレイOn
0
0
0
0
0
1
S/C
R/L
-
-
↑ ↑
↑ ↑
↑ 移動方向
カーソル移動
0
0
0
0
1
DL
N
F
-
-
↑ ↑ ↑
↑ ↑5×10,5×8dots
↑ ディスプレイ行数
1,8bit 0,4bitデータ長
0
0
0
1
ac5
ac4
ac3
ac2
ac1
ac0
0
0
1
ac6
ac5
ac4
ac3
ac2
ac1
ac0
0
1
BF
ac6
ac5
ac4
ac3
ac2
ac1
ac0
1
0
D7
D6
D5
D4
D3
D2
D1
D0
1
1
D7
D6
D5
D4
D3
D2
D1
D0
ACM1602 データ表よりアレンジ
上記のコマンドを送ればその設定になります。
液晶の文字のアドレス
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10・・・・・39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50・・・・・79 7A 7B 7C 7D 7E 7F
液晶の画面は上のようなアドレスになっています。
LCD初期化
#include <Wire.h>//I2C接続
void setup() {//初期設定部
Wire.begin();
initLcd();//LCD初期化
}
void loop() {//繰り返し部
}
//関数・サブルーチン
void writeCmd(byte cmd){//コマンド送信
Wire.beginTransmission(0x50);
Wire.write(0x00);//第1BYTE
Wire.write(cmd); //第2BYTE
Wire.endTransmission();//ストップ
}
void writeData(uint8_t dat){//データ送信
Wire.beginTransmission(0x50);
Wire.write(0x80);// 第1BYTE
Wire.write(dat); // 第2BYTE
Wire.endTransmission();//ストップ
}
void initLcd(){//LCD初期化
delay(10);writeCmd(0x01);//ディスプレイ空白
delay(10);writeCmd(0x38);//データは 8bit
//2行表示,フォントサイズ 5x8
delay(10);writeCmd(0x0c);//表示開始
//カーソル使用,カーソル場所使用
delay(10);writeCmd(0x06);//モードセット
//インクリメント,シフト表示なし
delay(10);
}
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
31
32
33
34
35
36
37
同じように上記のサブルーチンを書き足せ,setCursor(x,y);でカーソルを思う位置に移動できます。
カーソル移動
initLcd()のサブルーチンを付け加えると初期設定でinitLcd()が使えて,LCDを白紙にしてくれます。
void setCursor(byte col, byte row){//カーソル移動
byte rowOffsets[] = { 0x00, 0x40 };//1行の文字数
if ( row > 1 ) {row = 1;}
writeCmd( 0x80 | (col + rowOffsets[row]) );
}
文字表示
writeData(0x31);//"1"文字コード出力
writeData(0x41);//"A"文字コード出力
writeData(0xB1);//"ア"













