2019年5月23日木曜日

MPC3208 ADconverter


https://qiita.com/shiraco/items/8c2587ae5a647b4f9803#%E4%B8%BB%E5%BD%B9   から

彼らがAD変換の主役です。本記事で解説します。
  • 12ビットADコンバータ MCP3208-CI/P x 1
    • アナログ値をデジタル値に変換します
  • 半固定抵抗 x 1
    • 抵抗値を変化させアナログ値をセンシングします
  • フォトレジスタ x 1
    • 抵抗値を変化させアナログ値をセンシングします

脇役

ちなみに彼らも必要ですが、本記事では解説しません。
  • RaspberryPi一式
  • 抵抗(330Ω) x 1
  • 赤色LED x 1
  • ブレッドボード x 1
  • ジャンパワイヤ
    • オス-メス x 1セット
    • オス-オス x 1セット

AD変換とは?

アナログ値をデジタル値に変換します。

なぜデジタル値が必要なのか?

RaspberryPiへの入力は基本的には、2進数として、LOW(0)/HIGH(1) 2つの状態のどちらかになる。
これは、部屋の明るさだと、明かりがついているか消えているか、の2段階として理解します。
↓
これをデジタル値、0-4095のような段階的な値として入力することを狙います。

そもそもアナログ値、デジタル値って?

  • アナログ値
    • 連続値
    • e.g. 明るさ、温度、電圧など
  • デジタル値
    • 飛び飛びの値(離散値)
    • e.g. 計測して桁を切り捨てた値(デジタル時計)など

AD変換 (画像引用元: Raspberry Piで学ぶ電子工作|ブルーバックス)

adc.jpg
  • 1. センサからのアナログ値の取得
  • 2. AD変換
  • 3. デジタル値の通信

1. センサからのアナログ値の取得:

特定の地点での抵抗値を変化させ、端子から出力させるアナログ電圧を変化させる(0V-3.3V)1.65V
  • 半固定抵抗
  • フォトレジスタ (CdSセル)

半固定抵抗?

P-06110.jpg
画像引用元: akizukidenshi.com
  • 可変抵抗の一つで抵抗の大きさを調整可能

フォトレジスタ (CdSセル)?

I-00110.jpg
画像引用元: akizukidenshi.com

2. AD変換

アナログ電圧を測定しその値を、ADコンバータにてAD変換しデジタル値にする(0-4095->12bit) 2048
  • ADコンバータ

ADコンバータ?

(12ビットADコンバータ MCP3208-CI/P)
I-00238.JPG
画像引用元: akizukidenshi.com

ADコンバータ特徴

  • 16ピンを持つ回路
    • 0ch-7chの8つのアナログ値を読み取れるチャネル
  • アナログ値をデジタル値に変換する
  • 12ビット精度で送れる
    • 212=4096=4∗103
スクリーンショット 2016-11-22 1.59.36.png

3. シリアル通信

デジタル値を2進数 (1000_0000_0000 = 2048) としてSPI通信で送る
  • SPI通信
  • I2C通信

3. シリアル通信

スクリーンショット 2016-11-22 1.55.37.png

code

# MCP3208からSPI通信で12ビットのデジタル値を取得。0から7の8チャンネル使用可
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if adcnum > 7 or adcnum < 0:
        return -1
    GPIO.output(cspin, GPIO.HIGH)
    GPIO.output(clockpin, GPIO.LOW)
    GPIO.output(cspin, GPIO.LOW)

    commandout = adcnum
    commandout |= 0x18  # スタートビット+シングルエンドビット
    commandout <<= 3    # LSBから8ビット目を送信するようにする
    for i in range(5):
        # LSBから数えて8ビット目から4ビット目までを送信
        if commandout & 0x80:
            GPIO.output(mosipin, GPIO.HIGH)
        else:
            GPIO.output(mosipin, GPIO.LOW)
        commandout <<= 1
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
    adcout = 0
    # 13ビット読む(ヌルビット+12ビットデータ)
    for i in range(13):
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
        adcout <<= 1
        if i>0 and GPIO.input(misopin)==GPIO.HIGH:
            adcout |= 0x1
    GPIO.output(cspin, GPIO.HIGH)
    return adcout
inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)

演習1

スクリーンショット 2016-11-21 0.22.03.png
06-01-print.py
    while True:
        inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        print(inputVal0)

演習2

スクリーンショット 2016-11-21 0.22.10.png
06-02-led.py
    while True:
        inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        if inputVal0 < 2000:
            GPIO.output(LED, GPIO.HIGH)
        else:
            GPIO.output(LED, GPIO.LOW)

演習3

06-03-volume.py
    while True:
        inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        vol = "{0}%".format(int(inputVal0*100/4095))
        if vol != vol_old:
            print(vol)
            args = ['amixer','-q','cset','numid=1',vol]
            subprocess.Popen(args)
            vol_old = vol

まとめ

  • AD変換することで、センサーに入力されたアナログ値をデジタル値として回路から利用することができる
  • AD変換はADコンバーターを使って行う
  • デジタル値の通信はSPI通信でおこなう
なお、AD変換の仕組みはRaspberry Piで学ぶ電子工作(ブルーバックス)にわかりやすくまとまっているので、みなさん買って読みましょう。

参考

書籍

回路




2019年5月18日土曜日

引用元:https://qiita.com/miki-tensorflow/items/472d970ab0269169ed7e 

はじめに

  • IoTが注目され始め、最近何かと話題のラズベリーパイをはじめてみようとRaspberryPi3とRaspberry Piで学ぶ電子工作 専用 実験キット 基本部品セット スターターパック (電子部品関連)を購入しました。
  • ラズパイの初期設定からLチカまでは簡単にできたのですが、LCDディスプレイの接続には結構苦労しました。購入したセットには説明書も付いておらず、ネットで色々調べ試すはめになりました。
  • 私と同じ苦労をしなくて済むよう、現在ラズパイ-LCDディスプレイ接続で苦戦している人向けに本ページを書きました。少しでもお役に立てれば幸いです。

LCDディスプレイ接続結果のイメージ

  • 本ページでは以下画像のように文字を表示できるところまでを目標としています。
[ラズパイとLCDディスプレイを接続し文字を表示させた時の写真]

前提

ラズパイとLCDディスプレイの配線の仕方

  • ラズパイの2ピン・3ピン・5ピン・6ピンの4つを利用し以下写真のように配線します。配線する際は必ずラズパイの電源をオフ(USBケーブルを外した状態)にしておきます。
    • 2ピンはLCDディスプレイ裏側のVCCと書かれたピンをジャンパー線で接続
      ※写真では緑のジャンパー線
    • 3ピンはLCDディスプレイ裏側のSDAと書かれたピンをジャンパー線で接続
      ※写真では黄色のジャンパー線
    • 5ピンはLCDディスプレイ裏側のSCLと書かれたピンをジャンパー線で接続
      ※写真では橙色のジャンパー線
    • 6ピンはLCDディスプレイ裏側のGNDと書かれたピンをジャンパー線で接続
      ※写真では青色のジャンパー線
[ラズパイのピン配置拡大図]
IMG_6185.jpg
[ラズパイとLCDディスプレイ配線写真]
IMG_6188.JPG

ラズパイ側の設定

  • ラズパイとLCDディスプレイの接続にはI2C通信という技術を使います。そのためにはラズパイ側にI2C通信を有効化したり、必要なライブラリをインストールするなど諸々の設定が必要になります。

I2C通信の有効化

  • ラズパイのターミナルを起動し、以下コマンドを実行します。
sudo raspi-config
  • 以下のような画面が立ち上がるので「5 Interfacing Options > P5 I2C」を選択します。その後ラズパイを再起動し、I2C通信を有効化します。※ラズパイのバージョンによってやり方が異なるようです。その場合はこちらのサイトが参考になると思います。
[Raspbianの設定ツール起動画面]
image.png
[5 Interfacing Options選択後の画面]
image.png
[P5 I2C選択後の画面]
image.png

モジュールファイルの設定

  • ラズパイのターミナルにて以下コマンドを実行し、モジュールファイルに「i2c-bcm2708」、「i2c-dev」を追記します。
sudo vim /etc/modules
[モジュールファイルの編集結果]
image.png

I2Cに必要なライブラリをインストール

  • ラズパイのターミナルにて以下のコマンドを実行し、smbusとi2c python libraryのインストールします。
sudo apt-get install -y python-smbus i2c-tools

ラズパイとLCDディスプレイの接続確認とI2C通信のアドレスを確認

  • ラズパイのターミナルにて以下のコマンドのいずれかを実行します。
sudo i2cdetect -y 1
sudo i2cdetect -y 0
  • 以下のような表示がされれば成功です。以下の結果の場合、LCDディスプレイのI2C通信アドレスは「0x3f」と読み取れます。 ※ハードウェアによっては、「0x27」の場合もあるようです。
  • すべて「--」と表示される場合はLCDディスプレイとの接続に失敗しています。配線やこれまでのラズパイの設定に誤りが無いか再度確認してみてください。
[コマンド実行結果]
image.png

pythonコードをインストール

  • アドレスが「0x27」の場合は以下のコマンドを実行します。
wget http://osoyoo.com/driver/i2clcda.py
  • アドレスが「0x3f」の場合は以下のコマンドを実行します。
wget http://osoyoo.com/driver/i2clcdb.py
※「i2clcda.py」と「i2clcdb.py」の差はI2C通信のアドレス(0x27か0x3f)しかなく、それ以外は同じコードのようです。

LCDディスプレイに文字を表示させてみる

  • ダウンロードしたpythonコードを以下のコマンドで実行すれば、LCDディスプレイに文字が表示されるはずです。※冒頭の「I2C LCDディスプレイ接続結果のイメージ」の写真の様になります。
sudo i2clcdb.py

トラブルシューティング

  • 設定や配線も間違えてない、pythonのエラーも出ていない、なのにディスプレイに文字が出てこない!!っという現象に遭遇した時はディスプレイの濃度を確認してみて下さい。ディスプレイの濃度が薄過ぎて既に表示されている文字が見えていないだけかもしれませんよ!
  • LCDディスプレイの裏側に濃度を調整できる青いモジュールがあります。中心をドライバー等で回すとことで濃度の調整を行えます。※右に回すと濃く、左に回すと薄くなります。
    私はこれに気づかず3日間を無駄にしてしまいました:sweat_smile:
[LCDディスプレイの濃淡調節のやり方]
image.png

参考サイト

2019年5月11日土曜日




プロセス停止は
タスクマネージャで停止させるのが楽  Rasbian

2019年3月24日日曜日


Pythonプログラムには、標準でコンパイル関数の py_compile() が用意されています。 例えば、
print('コンパイルだよ')
というコードを hello.py で保存。
次にターミナルもしくはコマンドを hello.py と同じディレクトリで開きます。
そして
>>> python
>>> import py_compile
>>> py_compile.compile('hello.py')
とすると
'__pycache__/hello.cpython-36.pyc'
が生成されます。
image
image
一旦 Pythonスクリプトを終了し、
cd __pycache__
python hello.cpython-36.pyc
と入力すると、
コンパイルだよ
と出力されます。
image
なんとPythonは .py 以外に、Pythonコードをコンパイルした .pyc というファイルも実行できるんですね。
それで次に hello.py はエディタで開けますが、 hello.cpython-36.pyc はどうでしょうか? いつも使っているエディタでは開けませんので、ターミナルから
vi hello.cpython-36.pyc
とすると、読めないファイルに。 Pythonファイルがコンパイルされていることが分かりますね。
image

自動的にコンパイル

image
Python学習を進められている方の中には、 __pycache__ というフォルダに見覚えがある方もいらっしゃるかもしれません。 この __pycache__ というフォルダ、実はモジュールを実行した時、自動的に生成されます。 試しに簡単なモジュールを作成して、実行してみましょう。
【ファイル名 main.py】
from module import tool

tool()
【ファイル名 module.py】
def tool():
    print('モジュール')
【コマンド】
python main.py
<< 実行結果 >>
image
なんと自動的に __pycache__ フォルダ内が作成されて、その中に module.py のコンパイルされたファイルが保存されています。 これはPythonプログラム内で import を使った時に自動操作されていることで、よく import する numpy や Beautiful Soup など各ライブラリにも __pycache__ フォルダは存在し、使う度に更新。 どんな状態になっているか興味ある方は、pip show numpy などでライブラリのある場所を確認して、フォルダを覗いてみて下さい。
【.pyc について】
ファイルサイズこそ大きくないにしても、 「.pyc も pycacheフォルダ も消したい」と思うこともあるでしょう。大丈夫です、消してもPythonプログラムを実行するとまた .pyc も pycache も自動的に作成されます。

Pythonプログラムの処理フロー

image
Pythonプログラムでモジュールを利用する時のコンパイルフローを上記に示します。
実際に、プログラムを書き換えて実行してみると、コンパイルファイルも自動更新されますので試してみて下さい。

コンパイルのメリット・デメリット

image
【メリット】
  • プログラムの実行速度が早くなることもある
  • Pythonコードを秘密にできる
  • コンパイル方法を変えると Java や C# とも共存できる
【デメリット】
  • 内容がややこしい
  • 処理速度が早くならないこともある
Java や C++ などはコンパイルが必須ですが、Pythonは基本コンパイル不要で動作。 ただそれは自分たちの知らない間にコンパイルしていただけの話。
コンパイルを標準の CPython 以外に PyPy や Jython などにすると、処理速度が早くなったり Java と Pythonが共存できたりなど標準以上の機能に期待できます。

Pythonの標準以外のコンパイル方法

image
Pythonの標準コンパイル方法は、 CPython。
これよりも実行速度が早いと言われるコンパイル方法が、 PyPy。
他の言語との共存を可能にする方法が、Jython や IronPython、PythonNet など。
これらのツールは、Pythonの基礎学習用参考書には載っていなく、上級者向けの内容と考えられます。アプリケーション開発などを行う方は、PyPy などを知っておくといいかもしれませんね。
【PyPyのサンプル】
pypy hello.py
PCにPyPyをインストールした後は、Python ●●.pyの代わりに pypy ●●.py と命令文が変わるだけです。
image
また __pycache__ フォルダの中には、 ●●.pypy3-24.pyc というような形式でコンパイル済みのファイルが自動生成。

Pythonのいろいろな実装方法

image
画像引用:IronPython
先ほど登場した PyPy など標準外のPythonの実行方法をご紹介します。参考程度に閲覧下さい。

CPython

Pythonに標準で備わっているソフトで、最も広く使われている実装方法。C言語で書かれ、C拡張モジュールと高い互換性を示します。

PyPy

PyPyは、CPythonと高い互換性を示しつつ、より高いパフォーマンスの実現に期待できるソフトです。場合によっては、CPythonより 5倍以上高いパフォーマンス*を示した例もありますね。

IronPython

IronPythonは、Windows の Visual Studio でPythonを使う場合の実装方法で、 .NET フレームワーク・ライブラリと Pythonライブラリの両方を使うことが可能。Windowsのコアユーザーは、知っておきたい実装方法の一つかもしれませんね。

PythonNet

PythonNetは、Windows以外のOSXやLinuxユーザーで .NET フレームワークを使っている方向けの実装方法の一つです。

Jython

Jythonは、PythonファイルとJavaファイルの両方を使えるようにする実装方法。 例えば、JavaのクラスをPython内で実行など。 ちょっと頭が混乱しそうですが、システム上 Java が必要なときなどに有効。実行コマンドは、
jython hello.py
など。
image

まとめ

Pythonって標準でもWebやデスクトップアプリ、IoT など幅広いジャンルで利用できるのに、実装方法を変えるともっと広範囲で使えるって、スゴイですね。Pythonの「コンパイル」以前に、Pythonの基礎やコンパイルの基礎がまだという方、CodeCampで Python もしくは Java の勉強を始めてみませんか? オンライン × マンツーマンの CodeCamp ならスムーズにプログラミング・スキルを獲得できると思いますよ。

おまけ スピードテスト

Pythonのコンパイルは、実効速度を早くするために行うもの。またPyPyという実行方法は、Python以上に早いとか。 簡単なプログラムで実行速度を測ってみました。
【コンパイル・ファイルなし no_m.py】
import time
t1 = time.time() 

for i in range(9999999):
    s = i**31
print(s)

t2 = time.time()
done_speed = t2-t1
print("処理時間:", done_speed)
image
【py_compile()によるコンパイルで実行】
image
【モジュール実行によるCPython自動生成で】
image
【PyPy】
image
<< まとめ >>
実行方法タイム(秒)
python no_m.py7.09
python no_m.cpython.pyc5.36
python main.py4.9
pypy3 main.py8.19
Qiita などを参考に他の方のスピードテストを拝見すると、実行するプログラムによって PyPy の方が早かったり、遅かったりとまちまちな様子。今回私が試したループ処理も PyPy の方が遅く、あえてややこしいシステムを積極的に習う必要はない、と感じました。ただし、モジュールなしの no_m.py については、コンパイルファイル no_m.cpython.pyc を実行した方が早い結果になっています。こちらについてはコンパイルの恩恵を受けているといえますね。

https://blog.codecamp.jp/programming-python-compile-can-1   ここを参照