Arduino + Python Hacking 第0回

1.概要

東京、秋葉原で開催しますPythonとArduinoを使った勉強会です。

基本的には、Pythonを使ってソフト的にハードウェアを制御していく勉強会です。

なので、ハードウェアの知識は元より、ソフトウェアの知識も特に必要ありません。

本勉強会はソフトウェア開発(Python)の開発に重点を置きます。

今回は、ArduinoとPythonを使ってWEBブラウザからLED制御を行う。

基本的な動作は、PythonのPysirialと言うシリアル通信用ライブラリを使い、Arduinoの内部関数を制御する。

2.管理情報

開催日:2012/09/16
作成日:2012/09/24
作成者:北神雄太
分類:PyconJP2012 Sprints , Arduino

3.背景

ハードウェアとPythonの相性について発表して来たが、実際にその相性の良さを体感して頂く為に、

Arduinoを使ってPythonとハードウェア制御を楽しんでいただきたい。

また、Arduinoは非常に簡単な機能しか無く、商業用に利用するには非力な為、実用的なReDreaMに

ついての紹介もいくつか行っていきます。

4.内容

ステップ 1 概要

ArduinoからLEDを付けて、シリアル通信からビット制御を行う。

  1. Pysirial<http://pyserial.sourceforge.net> をインストールする。PyPiからもインストール可能です。
  2. Pythonにて import sirial が実行出来る事を確認。
  3. 続いてArduinoの開発環境を入れる。
  4. Arduinoに、Step1.cのソースを書き込む。
  5. PythonでStep1.pyのソースを記述する。
  6. time.sleepで間隔を変えたりビットを変えたりして遊んでみる。

ステップ 2 ソース説明(Arduino側)

・ LEDのポート設定。今回は2,3,4,5ポートを使ってLED制御します。

// digital pin 2 has a pushbutton attached to it. Give it a name:
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;

・ setup関数

シリアルの速度を115200bpsに設定し、LEDの端子をOUTPUTに、初期状態として全点灯を設定する。
void setup() {
  Serial.begin(115200);

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);

  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, HIGH);
}

・ loop関数

シリアルの受信待ちをし、受信があった際に動作を行う。その際、受信した文字を数字に変換し、1が来た際はLED1を点灯し、それ意外は消灯を行う。 同じ様な動作でLED2,3,4も行う。
void loop() {
  int tmp;
   if (Serial.available() > 0) {
      tmp = Serial.read();
      tmp = tmp- '0';

  if(tmp == 1)
     digitalWrite(LED1, HIGH);
  else
     digitalWrite(LED1, LOW);

   if(tmp == 2)
     digitalWrite(LED2, HIGH);
   else
     digitalWrite(LED2, LOW);

   if(tmp == 3)
     digitalWrite(LED3, HIGH);
   else
     digitalWrite(LED3, LOW);

   if(tmp == 4)
     digitalWrite(LED4, HIGH);
   else
     digitalWrite(LED4, LOW);
  }
}

・ 全ソース

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

// digital pin 2 has a pushbutton attached to it. Give it a name:
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(115200);

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);  

  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, HIGH);
}

// the loop routine runs over and over again forever:
void loop() {
  int tmp;
   if (Serial.available() > 0) {
      tmp = Serial.read();
      tmp = tmp- '0';
  
  if(tmp == 1)
     digitalWrite(LED1, HIGH);
  else
     digitalWrite(LED1, LOW);

   if(tmp == 2)
     digitalWrite(LED2, HIGH);
   else
     digitalWrite(LED2, LOW);
   
   if(tmp == 3)
     digitalWrite(LED3, HIGH);
   else
     digitalWrite(LED3, LOW);
   
   if(tmp == 4)
     digitalWrite(LED4, HIGH);
   else
     digitalWrite(LED4, LOW); 
  }
}



ステップ 3 ソース説明(Python側)

・ お約束、今回はSleep関数があるtimeと、シリアル通信を行うsirial、そして念のためにsysをインポートします。

# -*- coding: utf-8 -*-
import time
import serial
import sys

・ Arduinoが接続されているポートを指定します。Mac&Linux版とWin版でポートの指定方法が違ってくるので注意。

Mac&Linux版 /dev/〜のドライバを選択。Arduinoのバージョンによって変わって来るので説明するのも困る状況。基本的にはArduinoコンパイラで選択したポート名を記述する。(詳しい話はGoogle先生に聞いてください。その内まとめます。)

Windows版 COM-1で設定します。デバイスドライバーで記載されているCOMナンバーから1を引いた数を設定してください。

#Mac&Linux
tmp_msg = "/dev/tty.usbserial-A800eGnD"
#Windows
tmp_msg = 1-1

・ ポートの解放設定

sirial.Sirialで指定したポートを開き、baudrateで通信速度を設定し、timeoutでタイムアウト時間を設定する。

ser = serial.Serial(tmp_msg)
ser.baudrate = 115200
ser.timeout = 1

・ 1秒間隔でLEDが1個目→2個目→3個目→4個目→1個目と循環する用に記述

Arduinoには、ser.write(“1”)を記述すると1番目のLEDが点灯するようプログラムされている。そのため、それらの記述を利用して簡単なプログラムを記載した。

この辺は皆さんご自由に改造してみてください。

for i in range(0,20):
        ser.write("1")
        time.sleep(0.1)
        ser.write("2")
        time.sleep(0.1)
        ser.write("3")
        time.sleep(0.1)
        ser.write("4")
        time.sleep(0.1)
        ser.write( "0")
        time.sleep(0.1)

・ 全ソース

 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
# -*- coding: utf-8 -*-
import time
import serial
import sys

#Mac & Linux
tmp_msg = "/dev/tty.usbserial-A800eGnD"

#Windows
#tmp_msg = 1-1

ser = serial.Serial(tmp_msg)
ser.baudrate = 115200
ser.timeout = 1
print ser.portstr

for i in range(0,20):
	ser.write("1")
	time.sleep(0.1)
	ser.write("2")
	time.sleep(0.1)
	ser.write("3")
	time.sleep(0.1)
	ser.write("4")
	time.sleep(0.1)
	ser.write( "0")
	time.sleep(0.1)
ser.close()

ステップ 4 Flaskを使ったサーバー作成(Python側)

後日記載予定

・ 全ソース

 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
38
39
40
41
42
43
44
import time
import serial
import sys

from flask import Flask


app = Flask(__name__)

@app.route("/1")
def arduino_1():
	ser.write("1")
	time.sleep(0.1)
	return "LED 1 ON!"
	
@app.route("/2")
def arduino_2():
	ser.write("2")
	time.sleep(0.1)
	return "LED 2 ON!"
	
@app.route("/3")
def arduino_3():
	ser.write("3")
	time.sleep(0.1)
	return "LED 3 ON!"
	
@app.route("/4")
def arduino_4():
	ser.write("4")
	time.sleep(0.1)
	return "LED 4 ON!"



if __name__ == "__main__":
	tmp_msg = "/dev/tty.usbserial-A800eGnD"
	ser = serial.Serial(tmp_msg)
	ser.baudrate = 115200
	ser.timeout = 1
	print ser.portstr

	app.run("127.0.0.1",1234)
	ser.close()

5.次回スケジュール

日付 場所 内容 必要な物 参加費用
10中期 13:00〜17:00 秋葉原CERO? Pygame+可変抵抗 PC,Arduino,USBケーブル 1500円

5.今後の予定

6.メッセージ

とりあえず、さくっとサイト作りました。

タグも Arduino+Python なので #arduinopy でいこうかなと思います。

7.参考資料

Arduino , Python , PySirial

8.奥付け

作成者:北神 雄太
Twitter:@nonNoise
開催日:2012/9/16
作成日:2012/9/24
分類:Arduino,Python
提供:ArtifactNoise http://ArtifactNoise.com
クリエイティブ・コモンズ・ライセンス