ラズパイ日記

2021年3月 6日 (土)

デジタルフィルターの実験

Python scipyでデジタルフィルターの実験をしてみた。

インプットとしてフォトレジスターの値をMCP3208で読み取った。Raspberry Pi 4BにSPIでインターフェースしている。回路図左側のラベルはRaspberry Pi 4BのGPIO信号で、カッコ内はヘッダーピン番号。

Mcs3208cds

実際の様子はこんな感じ。
Img04797

0.01秒周期で512サンプル行った。読み取ったサンプルデータに対して先人の知恵に学びながButterフィルターをかけてみた。

写真のセットを机の上(蛍光灯、LED証明、LCDモニター前)に置いた場合。
通過域端周波数 4Hz、阻止域端周波数 6Hz

どうやら蛍光灯の影響で3Hzから4Hzの間の周波数でCdS出力が変化する(蛍光灯を切るとこの周期の波はなくなった)。通過域端周波数を4Hzとするとフィルター出力は正にこの変化を捉えることになった。

Fl2fp4ps6

通過域端周波数 1Hz, 阻止域端周波数 3Hz

通過域端周波数を1Hzとすると、3~4Hzの波の下に隠れている周波数成分を取り出すことが出来たようだ。

Fl6fp1fs3

ちなみに蛍光灯を消した状態ではこんな感じになった。

Fl7

CdSを手で覆って光を遮断した状態
通過域端周波数 4Hz、阻止域端周波数 6Hz

CdSの光を遮断(センサー表面を手で隠す)した場合、相対的にノイズ成分が多くなる。この状態でフィルターしてみた。確かにノイズの下に隠れている波を取り出しているように見える。

Fl5fp4fs6dark

CdSの上およそ20cmのところで手のひらを1秒弱で往復させた場合
通過域端周波数 2Hz、阻止域端周波数 4Hz

1~2Hz程度でインプットがあった場合の周期性を捉える実験もしてみた。これは手のひらを通過させたときの出力変位が多きの出フィルターするまでもない感じだけれども、仮に多量にノイズが乗っていても恐らく同様の結果が得られるものと期待できる。

Fl4fp2fs4

記録のためにここで使ったコードは以下に置く。多くの方々の知恵をまとめて一つにしたもの。

ダウンロード - filtertest2.py

感謝。

 

 

 

 

2021年3月 5日 (金)

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回、カウント数とループ一回当たりの時間をコンソール出力している。

Adc0

 

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。

Adc1

以上。

2021年3月 4日 (木)

Raspberry Pi 4でscipyをimport

以下の3つのimportを持つPythonコードについての作業記録。環境はRaspberry Pi 4B, Python 3.7, Python3 IDLE。

import numpy
import scipy
import matplotlib.pyplot

コードをRUNすると以下のエラーになった。

Traceback (most recent call last):
File "/home/pi/raspi/study/filter-test.py", line 3, in <module>
from scipy import signal
ModuleNotFoundError: No module named 'scipy'


pi@raspberrypi:~ $ sudo apt-get install python-scipy
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
libexiv2-14 libgfortran3 libgmime-2.6-0 uuid-dev
これを削除するには 'sudo apt autoremove' を利用してください。
以下の追加パッケージがインストールされます:
python-decorator
提案パッケージ:
python-scipy-doc
以下のパッケージが新たにインストールされます:
python-decorator python-scipy
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 1 個。
8,955 kB のアーカイブを取得する必要があります。
この操作後に追加で 38.2 MB のディスク容量が消費されます。
続行しますか? [Y/n] y
取得:1 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf python-decorator all 4.3.0-1.1 [14.4 kB]
取得:2 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf python-scipy armhf 1.1.0-7 [8,941 kB]
8,955 kB を 8秒 で取得しました (1,144 kB/s)
以前に未選択のパッケージ python-decorator を選択しています。
(データベースを読み込んでいます ... 現在 179465 個のファイルとディレクトリがインストールされています。)
.../python-decorator_4.3.0-1.1_all.deb を展開する準備をしています ...
python-decorator (4.3.0-1.1) を展開しています...
以前に未選択のパッケージ python-scipy を選択しています。
.../python-scipy_1.1.0-7_armhf.deb を展開する準備をしています ...
python-scipy (1.1.0-7) を展開しています...
python-decorator (4.3.0-1.1) を設定しています ...
python-scipy (1.1.0-7) を設定しています ...

なんだかインストールできた感じがする。再びRUNするも、結果は同じ。Scipy Moduleが無いといってくる。そこでpipでのインストールを実行した。

pi@raspberrypi:~ $ sudo pip install scipy
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting scipy
Downloading https://www.piwheels.org/simple/scipy/scipy-1.6.1-cp37-cp37m-linux_armv7l.whl (62.0MB)
100% |████████████████████████████████| 62.0MB 7.3kB/s
Collecting numpy>=1.16.5 (from scipy)
  Downloading https://www.piwheels.org/simple/numpy/numpy-1.20.1-cp37-cp37m-linux_armv7l.whl (11.6MB)
    100% |████████████████████████████████| 11.6MB 39kB/s
Installing collected packages: numpy, scipy
  Found existing installation: numpy 1.16.2
    Not uninstalling numpy at /usr/lib/python3/dist-packages, outside environment /usr
    Can't uninstall 'numpy'. No files were found to uninstall.
Successfully installed numpy-1.20.1 scipy-1.6.1

なんだか既にインストールされているnumpyとして1.16.2があるけれどアンインストールできなかったと言ってる。でも1.20.1は無事インストールできたようだ。結果を見る限りなんだかよい感じだ。そこで再びRUNを実行してみた。結果はエラー。。。。

Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/numpy/core/__init__.py", line 22, in <module>
from . import multiarray
File "/usr/local/lib/python3.7/dist-packages/numpy/core/multiarray.py", line 12, in <module>
from . import overrides
File "/usr/local/lib/python3.7/dist-packages/numpy/core/overrides.py", line 7, in <module>
from numpy.core._multiarray_umath import (
ImportError: libf77blas.so.3: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/pi/raspi/study/filter-test.py", line 2, in <module>
import numpy as np
File "/usr/local/lib/python3.7/dist-packages/numpy/__init__.py", line 145, in <module>
from . import core
File "/usr/local/lib/python3.7/dist-packages/numpy/core/__init__.py", line 48, in <module>
raise ImportError(msg)
ImportError:

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

* The Python version is: Python3.7 from "/usr/bin/python3.7"
* The NumPy version is: "1.20.1"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: libf77blas.so.3: cannot open shared object file: No such file or directory

>>>

どうもlibf77blas.so.3が無いって言っている。先人の知恵に学ぶとlibatlas-base-devをインストールすれば解決するらしい。

pi@raspberrypi:~ $ sudo apt install libatlas-base-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
libexiv2-14 libgfortran3 libgmime-2.6-0 uuid-dev
これを削除するには 'sudo apt autoremove' を利用してください。
以下の追加パッケージがインストールされます:
libatlas3-base
提案パッケージ:
libatlas-doc liblapack-doc
以下のパッケージが新たにインストールされます:
libatlas-base-dev libatlas3-base
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 1 個。
5,365 kB のアーカイブを取得する必要があります。
この操作後に追加で 32.1 MB のディスク容量が消費されます。
続行しますか? [Y/n] y
取得:1 http://ftp.tsukuba.wide.ad.jp/Linux/raspbian/raspbian buster/main armhf libatlas3-base armhf 3.10.3-8+rpi1 [2,399 kB]
取得:2 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf libatlas-base-dev armhf 3.10.3-8+rpi1 [2,966 kB]
5,365 kB を 2秒 で取得しました (2,200 kB/s)
以前に未選択のパッケージ libatlas3-base:armhf を選択しています。
(データベースを読み込んでいます ... 現在 180480 個のファイルとディレクトリがインストールされています。)
.../libatlas3-base_3.10.3-8+rpi1_armhf.deb を展開する準備をしています ...
libatlas3-base:armhf (3.10.3-8+rpi1) を展開しています...
以前に未選択のパッケージ libatlas-base-dev:armhf を選択しています。
.../libatlas-base-dev_3.10.3-8+rpi1_armhf.deb を展開する準備をしています ...
libatlas-base-dev:armhf (3.10.3-8+rpi1) を展開しています...
libatlas3-base:armhf (3.10.3-8+rpi1) を設定しています ...
update-alternatives: /usr/lib/arm-linux-gnueabihf/libblas.so.3 (libblas.so.3-arm-linux-gnueabihf) を提供するために自動モードで /usr/lib/arm-linux-gnueabihf/atlas/libblas.so.3 を使います
update-alternatives: /usr/lib/arm-linux-gnueabihf/liblapack.so.3 (liblapack.so.3-arm-linux-gnueabihf) を提供するために自動モードで /usr/lib/arm-linux-gnueabihf/atlas/liblapack.so.3 を使います
libatlas-base-dev:armhf (3.10.3-8+rpi1) を設定しています ...
update-alternatives: /usr/lib/arm-linux-gnueabihf/libblas.so (libblas.so-arm-linux-gnueabihf) を提供するために自動モードで /usr/lib/arm-linux-gnueabihf/atlas/libblas.so を使います
update-alternatives: /usr/lib/arm-linux-gnueabihf/liblapack.so (liblapack.so-arm-linux-gnueabihf) を提供するために自動モードで /usr/lib/arm-linux-gnueabihf/atlas/liblapack.so を使います
libc-bin (2.28-10+rpi1) のトリガを処理しています ...
pi@raspberrypi:~ $

インストールが無事完了。再度RUNを実行したところimportは無事成功し期待するようにコードが実行された。

めでたし、めでたし。

ところで、apt-getとpipは何が違うのか。aptはシステム環境、pipは個別環境にインストールされるということでインストール先が違うらしい。またインストール元(リポジトリ)が異なる。すくなくともIDLEのRUN環境ではpipのインストール先を見に行っているんだろうとは思う。結果を左右したのはそのくらいなのだろうか。。。。

 

2021年2月26日 (金)

TKinter afterメソッド:再帰的コールによる自動更新

GUIの表示を定期的に更新したくなるのはリアルタイムデータ処理では避けられない(と思う)。

GUI表示自体はTKinterで容易にできるようだけれど、それを定期的に更新する方法を調べて実装してみた。背景にあるのは、Pico+TWELITEによって定期的に取得する超音波距離センサー・データをGUI表示するためだ。

ここで使うのはTKinterが提供するafterメソッドだ。afterメソッドは、このメソッドコール後に実行するFunctionと、その実行までの待機時間をパラメータとして指定する。このFunctionとして、このafterメソッドを実行するFunction自体を指定すると再帰的なコールが実行される。つまり、指定した待機時間後のそのFunctionが繰り返し実行されるようになるわけだ。このFunctionにてGUIを描画すれば、定期ていなGUIアップデータ実現する。

class GUI(tk.Frame):

   def update(self):

      # GUIを描画するコード

      self.after(100,self.update) # 100ms後に自分自身を実行する。結果的にループ化する


if __name__ == "__main__":
   gui = tk.Tk()
   app = GUI(master = gui)
   app.update()  # updateをコールして再帰的コールをキックする
   app.mainloop() # 以後のイベント処理はmainloop内で実行される

ネット上に公開されている先人の知恵に学びながら作成した参考コードは以下からダウンロードできる。

ダウンロード - tktest04.py

また具体的な工作内容はこちらから参照できる。

aftetrメソッドを上手く使えばいろいろな事ができそうだ。

 

2021年2月21日 (日)

Raspberry Pi でのUSB CDC ACM

rshellでPicoをUSBで接続するにあたって/dev/ttyACM0を指定した。

そもそもACMってなんだろうってことで調べたので備忘録。

USB CDC ACM、Universal Serial Bus Communication Device Class Abstruct Control Modelの頭文字だということらしい。

このデバイスはLinux上では /dev/ttyACM* として認識されるとのこと。つまり、PicoはCDC ACMデバイスとして認識されたということだ。そこでlsusbを実行してみた。

pi@raspberrypi:~ $ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 2e8a:0005
Bus 001 Device 003: ID 046d:c534 Logitech, Inc. Unifying Receiver
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

この中にPicoらしきものがない。とりあえず2e8a:0005をメモ。現在Raspberry PiのUSBにはデバイスが2つ(LogitechのUSBアダプターとPico)が接続されている。

Img04713

そこでdmesgでカーネル出力メッセージをみてみた。

pi@raspberrypi:~ $ dmesg
....
[ 1.813769] usb 1-1: new high-speed USB device number 2 using xhci_hcd
[ 1.996373] usb 1-1: New USB device found, idVendor=2109, idProduct=3431, bcdDevice= 4.21
[ 1.996394] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 1.996412] usb 1-1: Product: USB2.0 Hub
[ 1.998223] hub 1-1:1.0: USB hub found
[ 1.998538] hub 1-1:1.0: 4 ports detected
[ 2.323746] usb 1-1.1: new full-speed USB device number 3 using xhci_hcd
[ 2.463994] usb 1-1.1: New USB device found, idVendor=046d, idProduct=c534, bcdDevice=29.01
[ 2.464014] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2.464032] usb 1-1.1: Product: USB Receiver
[ 2.464048] usb 1-1.1: Manufacturer: Logitech
[ 2.476766] input: Logitech USB Receiver as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C534.0001/input/input0

....

[ 2.723762] usb 1-1.3: new full-speed USB device number 4 using xhci_hcd
[ 2.861186] usb 1-1.3: New USB device found, idVendor=2e8a, idProduct=0005, bcdDevice= 1.00
[ 2.861207] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2.861225] usb 1-1.3: Product: Board in FS mode
[ 2.861242] usb 1-1.3: Manufacturer: MicroPython
[ 2.861258] usb 1-1.3: SerialNumber: 000000000000

[ 6.833920] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device

USB Bus 1-1.1にLogtech、1-1.3にPicoが検出された記録が残っている。そして1-1.3はUSB ACM Deviceと認識されてttyACM0でマウントされている。LogtechはMouseとKeyboardがその先に繋がっていて、ACM Deviceとしては認識されていない(実際コミュニケーションデバイスではないし)。

lsusbの出力でメモした2e8a:0005はUSB deviceとしてのpicoのVendor IDとProduct IDだったようだ。なのでBus 001 Device 005はpicoと判明した。

1-1.1とか1-1.3とかはUSBのソケット番号に対応するらしい。実際、LogtechのUSBアダプタを直下のソケットに移したらdmesgに以下が記録された。

[ 3602.399066] usb 1-1.2: new full-speed USB device number 6 using xhci_hcd
[ 3602.539296] usb 1-1.2: New USB device found, idVendor=046d, idProduct=c534, bcdDevice=29.01
[ 3602.539317] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 3602.539335] usb 1-1.2: Product: USB Receiver
[ 3602.539353] usb 1-1.2: Manufacturer: Logitech

いろいろと奥が深い。

2021年2月20日 (土)

PicoとTWELITEを電池駆動

PicoもTWELITEも電池2本で動かすことができる。

Picoは内部にスイッチング電源(Switched Mode Power Supply:SMPS) を持っている。VSYS(39ピン)に入力された電圧をSMPSで3.3Vにして内部供給している。したがってVSYSに入力する電圧に関わらず、GPIOは3.3Vだ。

  Minimum Maximum
Raspberry Pi Pico VSYS 1.8 5.5
TWELITE DIP VCC 2.0 3.6

一方、TWELITE DIPはVCCが2.0から3.6Vとなっている。SMPSを内部に持っていないから(多分)、VCC電圧でGPIOを駆動することになる。これはPicoとTWELITEを接続する場合に考慮しないといけない点だと思う。

乾電池2本で3Vとして、この電圧をTWELITEのVCCに与えると、PicoとTWELITEのインターフェース間で電位差が生じるわけだ。でもこのことをPicoはちゃんと考えていて内部のSMPSで生成した3.3Vを外部にも供給できるように3V3(36ピン)を備えている。これをTWELITEのVCCに接続すればインターフェース間の電位差が生じない。

まとめると、電池のプラスラインはPicoのVSYSに接続。TWELITEのVCCはPicoの3V3に接続する。

この状態で動かしている様子が以下の写真になる。

Img04711

ここではPicoで以下のコードをmain.pyとして実行している。

import machine
import utime

led = machine.Pin(25, machine.Pin.OUT)

uart = machine.UART(1,115200)

while True:
      led.toggle()
      utime.sleep(1)

      uart.write("Hello World")

1秒おきにオンボードLEDの点灯消滅を繰り返し、その切替の度にTWELITEにUARTで”Hello World”と書き込む。TWELITEはそれをブロードキャストする。こんな具合だ。

これで写真のセットの電池ボックスのスイッチを入れると即座にその動作を始める。

これはおもしろい!!

Pico: main.pyとrshellの取り扱い

PicoでMicroPythonを使っている時、このプログラムをPicoのパワーオンで自動実行したくなるのは人情。

調べた結果、以下が分かった。

main.pyというファイル

Pico Python SDKガイドには以下が書かれている。

If you "save a file to the device" and give it the special name main.py, then MicroPython starts running that script as
soon as power is supplied to Raspberry Pi Pico in the future.

つまり、今Thonny上で作ったコードをmain.pyでPico上に保存すると次回のパワーオンの時にそのプログラムが自動実行されるわけだ。早速試した。ファイル保存の時にpy拡張子が自動で付くかとともってファイル名をmainで保存したら拡張子が付かなかった。なのでファイルはmain.pyで保存しなおして、USBケーブルを抜き差ししたら確かに自動で保存したPythonプログラムが起動した。これはいい。

でも、さっき間違えて保存したファイル削除や、さらに自動起動を停止したい場合のファイル名変更はどうしたらいいんだ???

BOOTSELボタンを押してFlash Drive ModeでPicoを立ち上げてもそんなファイルは見えない。。。。

この手の処理はSDKガイドにも書かれていない。困った、、、でグーグルしてみたらこのブログが見つかった。救われた。 rshellで/pyboardディレクトリを見に行けばいいのだ。
こういった事は考えて分かることではないのでmain.pyを紹介するのであれば、その取扱いについても公式ガイドでちゃんと記載しほしいのもだ。

rshellでファイル管理

ガイドを見ると以下でrshellをインストールせよとある。
$ sudo apt install python3-pip
$ sudo pip3 install rshell

python3-pipは既にインストール済みだったので、rshellのみインストール実行となった。で、rshellの実行。救ってくれたブログでは -pで具体的に指定するポートが書かれていなかったが、こちらはSDKガイドの記載をそのまま使ってみた。

pi@raspberrypi:~ $ rshell --buffer-size=512 -p /dev/ttyACM0
Using buffer-size of 512
Connecting to /dev/ttyACM0 (buffer-size 512)...
Trying to connect to REPL connected
Testing if ubinascii.unhexlify exists ... Y
Retrieving root directories ... /Hello_World.py/ /main.py/ /main/
Setting time ... Feb 20, 2021 12:40:22
Evaluating board_name ... pyboard
Retrieving time epoch ... Jan 01, 1970
Welcome to rshell. Use Control-D (or the exit command) to exit rshell.
/home/pi> ls /pyboard
Hello_World.py main.py main     <<- 拡張子なしでmainを保存したので消したい。
/home/pi> rm /pyboard/main
/home/pi> ls /pyboard
Hello_World.py main.py
/home/pi>

rshellが立ち上がってlsを実行してもpyboradというディレクトリは見えなかったが ls /pyboard はThonny IDEで保存したファイルを表示した。で、rmを実行。

Thonnyを立ち上げてPico上のファイルを見たらmainが無くなっていた。これでmain.pyも消すことができる。

Pyfiles-2

これで自由度がぐっと広がった。しかし、情報を集めるのに時間がかかる。。。。

そもそもrshellって。。。

そもそもrshellってなんだろう。Githubに記載があった。MicroPython用のRemote Shellなんだね。ESPってなんの頭文字か分からないけれど、Picoのようなマイコンボードを意味するらしい。そこでは/pyboardがデフォルトのようだ。これは知ってないと、考えて分かることではないね。

Remote MicroPython shell.

This is a simple shell which runs on the host and uses MicroPython's raw-REPL to send python snippets to the pyboard in order to get filesystem information, and to copy files to and from MicroPython's filesystem.

It also has the ability to invoke the regular REPL, so rshell can be used as a terminal emulator as well.

Note: With rshell you can disable USB Mass Storage and still copy files into and out of your pyboard.

When using the commands, the /flash directory, and the /sdcard directory (if an sdcard is inserted) are considered to be on the pyboard, and all other directories are considered to be on the host. For an ESP based board you can only reference its directory by using the board name e.g. /pyboard etc..

おまけにrshellではREPLが実行できる。replの終了はctl+X

/home/pi> repl
Entering REPL. Use Control-X to exit.
>
MicroPython v1.14 on 2021-02-05; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>>
>>> print("this is test")
this is test
>>>
>>>
/home/pi>

これを使うかどうかは分からないけれども、いろいろと機能があることがわかった。

レベルシフトチップTXS0108Eで苦戦

Raspberry Pi Picoに超音波距離センサーHC-SR04を接続したい。

しかし、Picoは3.3VだけれどHC-SR04は5Vだ。すっぴんのままHC-SR04の出力をPicoに接続するとPicoを壊してしまう可能性がある。そこでTXS0108Eの利用を考えてみた。これはレベルシフト電圧トラスレータチップだ。Low VoltageとHigh Voltageを双方向で変換してくれる。つまり、例えばHigh 3.3V信号をHigh 5Vに、またはこの逆に変換してくれるわけだ。で、早速使ってみた。

購入したのはHiGetgoの5個入りパック。半完成品状態となっている。
Img04694

ピンヘッダを半田付けして完成。
Img04697

このレベルシフターをHC-SR04とPicoの間にいれた。PicoのGPIO出力とHC-SR04のTrigger入力、HC-SR04のEcho出力とPicoのGPIO入力の間にいれたわけ。

まず、全然信号が出てこなくて、OEが内部プルアップされていると思ったんだけれど、結局そうでなくて、OEを5V(HC-SR04のVCC)に10KΩでプルアップして出力がでるようになった。

で、変換なんだけれども、デジタルオシロがないので電圧レベルまではわからないけれども、このレベルシフターに電源供給すると回路全体に回路全体に大きなノイズが乗るようで、信号に変なディップが発生した。HC-SR04もバタバタしてしまって、単なるノイズというレベルではなかった。

結局利用をあきらめた。

PicoのGPIO出力は3.3VのままHC-SR04のTriggerに接続した。シグナルマージンはめちゃ少なくなるけれども、とりあえずTriggerはできているよう。ただ、時々Echo出力が変になる(妙に長い値になる)ので、あんまり上手くないのかもしれない(変な出力の原因は究明してない)。問題のHC-SR04の5V出力をPicoの入力につなぐにあたっては抵抗分割を使った。HC-SR04の信号を2.2KΩで受けて、それを3.3KΩで接地する。2.2KΩと3.3KΩの接合点をPicoのGPIO入力につないだ。これでほぼ3Vの電圧になると同時にHC-SR04から過大な電流が流れ込む事を防ぐことができる。

今のところ動いている。

2021年2月19日 (金)

Thonny IDEでのUI Mode切替

Thonny IDEでのUI Mode切替について備忘録。

Thonny IDEの初期状態(インストール後の状態では)UIはSimple Modeに設定されている。メニューバーは表示されていなくて、画面右上にSwitch to regular modeがクリック可能となっている。

190

ここをクリックしてThonny IDEを立ち上げなおすとメニューバーが表示さえるRegular Modeになる。
191

UIを再びSimple Modeに戻したければ、Tools -> Options -> UI Modeを変更すればよい。

InterpreterのリストにPicoが無かったので、Raspberry Piの更新とパッケージのアップグレードを実施。

$ sudo apt update
$ sudo apt upgrade -y

全体で1.6GBくらい消費したようだけれど、とりあえずフレッシュスタートということで。
MicroPython (Raspberry Pi Pico) を選択。
Thonny01

2021年2月18日 (木)

Raspberry Pi Pico開発環境設定 その2

昨日はRaspberry Pi上に開発環境を作った。

これはこれでCOOLなんだけれど、Raspberry PiはGPIOをつないで色々と動かすので、そこに開発環境があるのはリスクが大きすぎる。ちょっと配線を間違えるとRaspberry Pi自体が昇天してしまう危険がある。デバッグはRaspberry Piで行うとしても開発環境はデバッグ環境とは別に用意したい。

そこでWindows PC上にC/C++ Raspberry Pi Pico開発環境を作ることにした。ガイドはRaspberry PiのWebサイトにある資料

手順は以下の通り。

ARM gcc complierのインストール:gcc-arm-none-eabi-...を選択しインストールする。インストール最後でAdd path to environment variableにチェックを入れること(デフォルトではここにチェックが入っていない)。他はチェックが入っているのでそのまま。

CMakeのインストール:とりあえず32bit版をインストールした。理由はARM gcc compilerが32bit版しかなかったから、それに揃えている。途中でそういうチェックがあったかはっきり覚えていないけれど、pathはall usersに適用するように設定すること。

Build Tool for Visual Studio 2019のインストール:ここはちょっとわかりにくかった。

まず以下のメニューからVisual Studio 2019のツールを選ぶ。

Visualstudio0
このツールの中からBuild Toolsをダウンロードする。

O0visualsstudio

ダウンロードしたインストーラを実行してC++ Build Toolsを選択しインストールする(詳しくはガイド参照)。

Python 3.Xのインストール:Python3.8じゃダメなのかな?とりあえず(たまたま)既にPython 3.7.3がインストールされていたのでこのままなんだけれど。

Gitのインストール:ここでも32bit版を選んでインストールした。ガイドにはDefault Editorとしてvimを使うな、とある。とりあえずVisual Studio Codeに設定した。他にも以下のように、いろいろと設定ガイドが書かれているの要注意。
allow Git to be used from third-party tools
以下にチェックを入れること。
"Checkout as is, commit as-is",
"Use Windows' default console window"
"Enable experimental support for pseudo consoles" 

以下を実行してサンプルコード等をダウンロードする。\work\picoってフォルダーを作ってそこにダウンロード・展開した。
C:\work\pico> git clone -b master https://github.com/raspberrypi/pico-sdk.git
C:\work\pico> cd pico-sdk
C:\work\pico\pico-sdk> git submodule update --init
C:\work\pico\\pico-sdk> cd ..
C:\work\pico> git clone -b master https://github.com/raspberrypi/pico-examples.git

この後Windowsメニューから以下を選択して、Developer Command Promptウインドウを開く。
Visual Studio 2019 > Developer Command Prompt for VS 2019

C:\work\pico\> setx PICO_SDK_PATH "..\..\pico-sdk"

この設定を有効化するためにDeveloper Command Promptウインドウを開きなおす。で、以下を実行するとダダ―とBuildが始まる。
C:\work\pico> cd pico-examples
C:\work\pico\pico-examples> mkdir build
C:\work\pico\pico-examples> cd build
C:\work\pico\pico-examples\build> cmake -G "NMake Makefiles" ..
C:\work\pico\pico-examples\build> nmake

結構時間がかかるけれども、これでelfファイルが作られた。

Visual Studio Codeの構成

基本的にガイド通りだけれど、一点分かりにくいところはProject構成のところ。
pico-examplesフォルダーを選択したあとProject構成をするよう問い合わせポップアップが表示されるとあるけれども、これが表示されなかった。で、Raspberry PiでのVSC構成と同様に、画面下のブルーラインのCMake [Debug] 準備完了をクリックするとコンパイラー選択リストが表示されるので GCC for none eabi ..を選択した。次に表示される画面でDebugを選択するとProjectの構成が始まり、無事(多分)終了した。

より以前の記事一覧