ADCのサンプリングレート
アナログ出力に対してADCをかけて波形サンプリングをしたい。サンプリングレートはどの程度になるのか以下の2パターンを実験してみた。
- PicoのADCを使ってサンプリングして、PicoからUARTでRaspberry Piにデータを取り込む
- ADC IC MCP3208を使ってSPIでRaspberry Piにデータを取り込む
結果
PicoのADCをUARTでサンプリングした場合の最小周期は1300us(800Hz)程度
MCP3208をSPIでサンプリングした場合の最小周期は50us(20KHz)程度
結論
ナイキスト周波数を100Hzとすればいずれの方法でもサンプリングは可能。
PicoのADCをUARTにて
PicoのUART0(1ピン、2ピン)をPiのUART(8ピン、10ピン)に接続した。
以下のMicroPythonをPicoで実行。
import machine
import utime
uart = machine.UART(1,115200)
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / 65535
count = 0
ptime = utime.ticks_ms()
while True:
reading = sensor_temp.read_u16() * conversion_factor
temperature = 27 - (reading - 0.706) / 0.001721
ctime = utime.ticks_us()
count += 1
output = "{}/{}\n".format(count, (ctime - ptime))
if (count % 1000) == 0:
print(output)
uart.write(output)
ptime = ctime
以下のPythonコードをRaspberry Pi 4Bにて実行した。
import time
import serial
s = serial.Serial("/dev/serial0",115200, timeout=3)
s.reset_input_buffer()
count = 0
try:
while True:
line =s.readline()
line = line.decode('utf-8')
count += 1
if (count % 1000) == 0:
print("{}".format(line))
except KeyboardInterrupt:
pass
結果は以下。1000回に1回、カウント数とループ一回当たりの時間をコンソール出力している。
MCP3208をSPIにて
MCP3208をRaspberry Pi 4BのSPIに接続している。PythonコードはBlue Backs Raspberry Piで学ぶ電子回路に掲載されているものを使っている。
import RPi.GPIO as GPIO
import time
# 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
GPIO.setmode(GPIO.BCM)
# ピンの名前を変数として定義
SPICLK = 11
SPIMOSI = 10
SPIMISO = 9
SPICS = 8
# SPI通信用の入出力を定義
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICS, GPIO.OUT)
ptime = time.time()
count = 0
try:
while True:
inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
ctime=time.time()
if (count % 1000) == 0:
print("{}/{}".format(inputVal0, ctime-ptime))
ptime=ctime
count += 1
except KeyboardInterrupt:
pass
GPIO.cleanup()
結果は以下の通り。1000回に1回、ADC値とループ時間をコンソール出力している。5掛ける10のマイナス5乗で50us。
以上。
« Raspberry Pi 4でscipyをimport | トップページ | デジタルフィルターの実験 »
「ラズパイ日記」カテゴリの記事
- NEO-7M GPSモジュールが中国から届いた(2023.01.15)
- TNCアプリにおけるDemoduatorの動作確認(2023.01.09)
- AFSKでの復調について(2023.01.04)
- APRSでのNRZIについて備忘録(2023.01.02)
- pico_tnc 2200Hz(Space)でPhaseをずらす件の備忘録(2022.12.31)
コメント失礼します。
現在、PicoのADCのサンプリングレートを固定することは可能なのでしょうか?
ADC.initなどで設定、または他の方法などでできますでしょうか?
投稿: めかぶ | 2023年5月 1日 (月) 15時34分