MENU

溶けかけてるうさぎ HP BLOG TOP RECENT ARTICLES POPULAR ARTICLES ABOUT THIS BLOG

CATEGORY

大学 (85) 航空宇宙 (55) 写真 (25) 旅行 (14) 飯・酒 (11) コンピュータ (88) その他 (13)

TAG

ARCHIVE

2018 (92) 2017 (80) 2016 (0)

RECENT

【駅メモ】4年目に突入して,ようやく3000駅突破 【WebRTC】Raspberry Pi搭載ロボットをWebRTCで遠隔操作しようとして失敗した 【航空宇宙】航空宇宙アドベントカレンダー 始まります! 【Perl】YAPC::Tokyo 2019 のチケットを確保しました! 【カメラ】Canonから富士フイルムに乗り換えました

【Ubuntu】PythonでUbuntu - Arduino間のシリアル通信

2017-03-30

UbuntuとArduinoでシリアル通信を行なった.Perlスクリプトで実現したかったのだが,使いやすいライブラリが見つからなかったので,Pythonで実装した.

今回は,LM35温度センサの値を取得する.

1.実行環境

Ubuntu Server 16.04.2 LTS

Arduino Uno R2

Python 2.7.12

2.Arduino回路図

Arduino回路図

LM35温度センサと104コンデンサを使用.

3.環境設定

まず,pyserialのインストール.

$ sudo pip install pyserial

lsusbでArduinoのデバイス表示.

$ lsusb
Bus 001 Device 004: ID 2341:0001 Arduino SA Uno (CDC ACM)
$ ls -al /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0  3月 29 10:25 /dev/ttyACM0

/dev/ttyACM0にアクセス権がないので,グループに追加.

$ sudo gpasswd -a ${username} dialout

# 以下でグループへの追加を確認
$ id ${username}

Ubuntuの再起動.

4.ソースコード

# coding: UTF-8

# arduinoからシリアル通信受信して温度をモニター

import sys
import os
import serial
# importはカレントディレクトリもまわるので,このスクリプト名をserial.pyにすると動かない!

def main(args):
    # while True:
    if True:
        # timeoutを秒で設定.ボーレートはデフォルトで9600.
        ser = serial.Serial('/dev/ttyACM0', timeout=5.0)

        # 1文字読み込み
        # c = ser.read()
        # 指定文字数読み込み ただしtimeoutが設定されている場合は読み取れた分だけ
        # str = ser.read(10)
        # 行終端'¥n'までリードする
        # line = ser.readline()

        # 最初に届く行は不完全な可能性があるので捨てる.
        line1 = ser.readline()
        line2 = ser.readline()
        ser.close()

		# 改行コードの削除.
        # line2.strip()
        # これだと,LFのみでCRLFは消せない.
        # ArduinoはWindowsから書き込みしているのでCRLF.
        line2 = line2.replace('\n','')
        line2 = line2.replace('\r','')
        ps(line2)

def ps(output):
    sys.stdout.write(str(output))
    sys.stdout.flush()

if __name__ == '__main__':
    main(sys.argv)
mySerial.py
const int N = 100;
int analogPin = 0;
double analogIn;
double temperature[N];
double temperature_avg;

void setup() {
    // http://www.arduino.cc/en/Reference/AnalogReference
    // INTERNAL: an built-in reference, equal to 1.1 volts
    analogReference(INTERNAL);
    // シリアル通信速度
    Serial.begin(9600);
}

void loop() {
    // N回平均
    temperature_avg = 0;
    for (int i=0 ; i< N ; i++) {
        // アナログピンから計測値を取得(0-1023)
        analogIn = analogRead( analogPin );

        // 摂氏に換算 100度で1.0V
        temperature[i] = (1.1 * analogIn * 100.0) / 1024.0;

        temperature_avg = temperature_avg + temperature[i] / N;
    }

    Serial.println( temperature_avg, 4 );

    // 停止
    delay(1000);
}

// 参考
// http://playground.arduino.cc/Main/LM35HigherResolution
Arduino用ソースコード

蛇足だが,Perlから呼び出す際は以下のようにすればいい.

#!/usr/bin/perl

use strict;
use warnings;

my $command = 'python "/${path}/mySerial.py"';
my @CommandResult = `$command`;
Perlソースコード

5.実行結果

$ python mySerial.py
23.2805
実行結果

6.出典・参考サイト

hirooka.pro. [Ubuntu] Arduino Uno. Retrieved March 29, 2017, from https://hirooka.pro/?p=675

コメントを投稿

名前

Email (※公開されることはありません)

コメント