isol
Posts: 2
Joined: Tue Oct 09, 2018 5:58 am

Raspberry Pi センシング

Wed May 08, 2019 12:36 am

初めての投稿となります。
分かりずらい部分があればご指摘ください。

現在、Raspberry Pi3Bを使用してセンサからセンシングを行っております。
環境は下記です。
Raspberry Pi 3B
OS:Raspbian Python3
AD変換:MCP3208

44.1kHzでサンプリングしたいと考えております。
ライブラリにspidevを使用しておりますが、SPIのCSのタイミングを指定できず
毎回違うサンプリング周波数となってしまいます。
※delayを入れずにサンプリングすると40kHz程度でばらつく。

所望のサンプリング周波数を得るにはどのような操作が必要なのでしょうか。

otani
Posts: 50
Joined: Fri Dec 13, 2013 4:18 am

Re: Raspberry Pi センシング

Thu May 16, 2019 7:39 am

少しばかり情報不足なのですが。
クロック周波数は、どうしていますか?Vccは?

MCP3208 5Vで2MHz, 3.3Vで1MHz Specです。速くしたければ5V駆動で回路設計します。
RaspiのSPI設定は、かなり高速で動き10MHz Clockでも問題なく動きました。(MCP3208でなく別のADCです。)

それで spidev のCSについてですが、こちらを見てください。
https://www.raspberrypi.org/forums/view ... 2&t=227903
そのまま spidevを使いたい場合は、ドライバソースを変更して再コンパイルすると速くなります。
または spidevを使わずにレジスタアクセスで処理する方法もあります。

44.1kHzでサンプリング希望とのことですが
オーディオ入力として使う場合はRaspiでのソフト制御では実用にはなりません。
ADCを水晶制御で動作させないとソフト・ジッタ―が増えて実用にならないのです。
もちろん実験でやってみて限界を知るのは有意義なことだと思います。
頑張ってください。

isol
Posts: 2
Joined: Tue Oct 09, 2018 5:58 am

Re: Raspberry Pi センシング

Fri May 17, 2019 8:30 am

>少しばかり情報不足なのですが。
>クロック周波数は、どうしていますか?Vccは?

 情報不足で申し訳ございません。
 クロック周波数は指定していません。Vccは5.0Vで設定しています。
 コードは下記です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import spidev

class MCP3208_Class:

def __init__(self, ref_volts):
self.ref_volts = ref_volts
self.spi = spidev.SpiDev()
self.spi.open(0,0)

def GetVoltage(self,ch):
raw = self.spi.xfer2([6+((ch&3)<<6,0])
data = ((adc[1] & 0x0f) << 8) | adc[2]
volts = data * self.ref_volts
return volts

def Cleanup(self):
self.spi.close()

"""メイン関数"""
if __name__ == '__main__':
ADC = MCP3208_Class(ref_volts=5)
try:
Volts_num = []

while True:
volts = ADC.GetVoltage(ch=0)
Volts_num.append(volts)


>そのまま spidevを使いたい場合は、ドライバソースを変更して再コンパイルすると速くなります。
>または spidevを使わずにレジスタアクセスで処理する方法もあります。

 pythonで処理は難しいですかね。。。
 ご教授頂いた方法を試してみます。

>44.1kHzでサンプリング希望とのことですが
>オーディオ入力として使う場合はRaspiでのソフト制御では実用にはなりません。
>ADCを水晶制御で動作させないとソフト・ジッタ―が増えて実用にならないのです。
>もちろん実験でやってみて限界を知るのは有意義なことだと思います。
>頑張ってください。

 色々教えて頂きありがとうございます。

otani
Posts: 50
Joined: Fri Dec 13, 2013 4:18 am

Re: Raspberry Pi センシング

Fri May 17, 2019 4:34 pm

Clock速度は、spi.max_speed_hz = で設定できます。
範囲は 125000000 ~ 7629 で数値を見ればわかるように
クロックを整数分周しているものです。
そのため、分周値以外の設定をしてもクロックは変化しません。
速い方が転送速度も上がります。

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 7629

Speed spi.max_speed_hz
125.0 MHz 125000000
62.5 MHz 62500000
31.2 MHz 31200000
15.6 MHz 15600000
7.8 MHz 7800000
3.9 MHz 3900000
1953 kHz 1953000
976 kHz 976000
488 kHz 488000
244 kHz 244000
122 kHz 122000
61 kHz 61000
30.5 kHz 30500
15.2 kHz 15200
7629 Hz 7629


SPI Driver latencyについては
https://www.raspberrypi.org/forums/view ... ?p=1115408
以下にある写真を見てください。
SPIドライバのパッチがあって、ソースを変更してコンパイルが必要です。
WiringPiはSPIドライバを使うので上記と同じです。

一方で pigpioは、レジスタを叩くので速いです。pythonも対応可能です。
実際にやっている人もいます。
http://arakik10.hatenablog.com/entry/2018/10/27/152206
なお、pigpioでもCLK指定できます。
また cs latency問題は無くなると思います。

検索キー
"pigpio" "spi" "python"
"pigpio" "MCP3208" "python"
でググってみてください。

以下は高精度にしたい場合に読んでください。
そうでなければ、流し読みでいいです。

50~100MHzオシロがあれば波形観測してオーバーシュートスパイク
を確認します。スパイクは配線長、浮遊容量で大きく変わります。
状況にあわせてリンギング対策として22/33/47/100オーム
の抵抗をSPI線に直列に追加して綺麗な方形波になるようにします。
ロジックアナライザでは見えません。

RaspberryPiは、0.3~0.5Vpp程度のクロックノイズがGNDを含む全線に乗るので
シビアな設計の場合は、実装基板での波形を見てノイズ対策が必要になります。
ADC電源のパスコン等には「OSコンデンサ」を使うとノイズスペクトルが変わりました。
ノイズに重畳してA/D変換されるので、有機コンデンサは効果が大きいです。

ADCのフィルタでノイズが大きく変わります。
A/D値を波形で見ると一目瞭然です。参考にしてください。
一番下の波形を見てください。
https://www.raspberrypi.org/forums/view ... p?t=149814
時定数は周波数に合わせて計算すること。

宜しくお願いします。

Return to “日本語”