乾燥剤はものによっては再生可能らしいのでやってみた
要は熱を加えて水分追い出せば良いのだから、最初はフィラメント脱湿機でやってみたけど赤い色(吸湿状態)は数時間ではほぼ変化しない
で、世の中でよくやられているようにフライパン(弱火)で炒ってみる、これは顕著に変化して、徐々に赤玉が青玉に変化していく
写真は赤玉ほとんど見えなくなった状態なのでこの程度で完了、二、三回はこの方法で再生できそうだ、再生後は適度に空気を通す袋に入れて使用
admin

la vie libre
フィラメント保管用に密閉ケースを買ったつもりでしたが、半年ぐらい経過すると湿度上昇して、乾燥剤追加しても割とすぐの戻ってしまう、つまり密閉度が保証されなくなってしまった模様で、フィラメントもポキポキ折れるから完全に吸湿してます
全体をボックスに入れるのではなくて、フィラメント一巻を個別で密閉袋に入れるような仕組みに変更するために
というのをAmazonで購入、中の空気を抜くポンプ付きですが、なぜポンプで中の空気が抜けるのか、つまり一方向性をどうやって確保しているのかがおそらくポイントなんだろうけどメカニズムは不明
ともかくも、中心部に乾燥剤いれて封入してみました、これでなんとかなるものなのかは時間経過しないと効果の程は不明ですが
ともかくも、3Dフィラメント保管用には吸湿したフィラメント乾燥用のヒーターと吸湿防止手段の二つは必需品です
admin
3Dプリンタの熱にも耐えられる季節になってきたので、ホーバークラフトのアップデートをしてみる
① PLA性は車の中に放置されると軟化してグダグダになるので材料はABSに変更
造形パラメターはチューニングが必要、プラットホームから剥離対策(樹脂押し出し量増やして接地面積大きくする)とラフトとオブジェクトの距離設定が大きくて最初の層の密着が改善用(デフォルトで良いけどPLAだとうまく剥がれないから大きめにしていた)
② ファンの位置極めができるようにバンプを追加
裏側から隙間テープで留めて、ファンの水へからの角度を安定させる
③ 移動方向側のファンの回転数を浮上できる範囲で小さくする
つまり回転数の差を大きくして反対側が持ち上がる量を大きくしてやることで推力を増加してやる
PWM指定で最大値は1024、
以上で左右(前後)方向の移動はコントロールできるようになった、動画は以下のリンクから
ただし当然の如くドリフトはするから、micro:bitの加速度センサーとジャイロ(コンパス)機能使ってフィードバックして安定したポジションを取るようにするのが次のステップ
admin
ラズパイゼロのRustクロス環境使って、ssd1306を動かしてみる
以下のリンクのサンプルプログラムを動かしてみただけですが、
https://github.com/fmckeogh/ssd1306-raspi-examples/tree/master
クロス環境はVMware +Ubuntu(20.xx)の環境です
Cargo.tomlはそのまま使い、examplesディレクトリのgraphics-i2c.rsをビルドしてラズパイにscpで転送して実行した結果は以下のようになります
ADCもFFTもどちらのcrateも存在しているようだから、PythonコードをRustで置き換えできそうです
admi
震度計算で気象庁から提示されているのは以下のリンクになります。
https://www.data.jma.go.jp/eqev/data/kyoshin/kaisetsu/calc_sindo.html
じゃ、近似計算でどの程度近似なのかをちょっと考察、
計算方法は① 加速度波形を周波数軸に変換(実質FFT)して、② 重み付けを行ない、さらに③ それを周波数に変換(実質IFFT)して、④ 0.3秒以上継続する値の最小値を求めて⑤ 震度計算式(対数目盛)で求めた値を四捨五入と切り捨てで震度とする、というステップになりますが、
近似計算と気象庁提示の差分のポイントは、②の周波数重み付けに差があります、このフィルターの特性は建物や構造物への影響度を考慮したものだと思われます
近似計算方式では、ハイカット側はデジタル処理ではなくて、以下の回路図で加速度計に付加されているキャパシタ(0.1μF)で一次のカットオフ周波数30Hzぐらい(デフォルトでは内蔵の3300pFでカットオフ800Hzを変化させている、一方ロー側は格段の処理はされていない模様
コード(以下のリンク)でフィルター処理のコメントありますが、実質は平滑処理になってます
https://github.com/p2pquake/rpi-seismometer/blob/master/seismic_scale.py
とはいえ、FFTを使って計算するのとそれほどの差があるわけでもなさそうだから、実用的には十分じゃないかというところで、正確に震度を求めようとすると計測器を設置する工事だけでも大変なのだから
P.S. pythonでnumpyの機能にあるFFTを実行してみると、
M1 Macとラズパイzeroでの速度比較
<用意したデータ>
sampling_rate = 2000 # サンプリング周波数(Hz)
T = 1 / sampling_rate # サンプリング間隔
t = np.arange(0, 1.0, T) # 時間ベクトル
# 信号生成(50Hzと120Hzのサイン波を重ねたもの)
f1 = 100 # Hz
f2 = 300 # Hz
signal = np.sin(2*np.pi*f1*t) + 0.5*np.sin(2*np.pi*f2*t)
<実行速度>
M1 Mac: np.fft.fft: 0.000027 [sec]
ラズパイゼロ: np.fft.fft: 0.001830 [sec]
ふーむ、およそ60倍ぐらい違うか、想定範囲だけどラズパイzeroでもフレーム周期5msでできなくはなさそうなレベル
admin
Raspberry PIでブート時にアプリを自動で立ち上げる方法は、以前は/etc/rc.localに記述という方法もありましたが、今は
https://www.raspberrypirulo.net/entry/systemd
にあるように/lib/systemd/system/配下にxxx.serviceファイルで条件記述して、
$ sudo systemctl start xxx.service
を使うのが推奨だし安定して使えるかと思いますが、震度計で記述したときに問題が起きたのでその状況と回避方法を
/lib/systemd/system/seismic.serviceで以下の内容を記述して、
[Unit]
Description = measure
[Service]
ExecStart=/usr/bin/python3 /home/pi/python/seismic.py
Restart=no
Type=oneshot
[Install]
WantedBy=multi-user.targetラズパイブート時のseismic.serviceの起動で,
Sep 27 20:44:06 rasp-z python3[298]: File "/home/pi/python/seismic.py", line 47, >
Sep 27 20:44:06 rasp-z python3[298]: spi.open(0,0)
Sep 27 20:44:06 rasp-z python3[298]: FileNotFoundError: [Errno 2] No such file or d>こんなエラーが出て起動できない、起動後の実行
$ sudo systemctl start seismic.service
だと問題ない、ということはタイミング問題じゃないかということでseismic.pyの最初で時間待ち(20秒)させてやったら、問題なく起動できました。
本来はサービスの起動条件をseismic.serviceファイルのパラメータで設定して対応すべきことかと思いますが、
<systemdの解説記事>
https://office54.net/iot/linux/systemd-unit-create
admin
取り敢えずOLCDに震度測定値を表示できるようにした。あとラズパイのシャットダウンがネットワーク未接続でも対応できるようにシャットダウンボタンを追加、
現時点でのコード
<seismic.py>
#
# core code is as follow
# https://github.com/p2pquake/rpi-seismometer/blob/master/seismic_scale.py
#
import time
import datetime
import math
import socket
import spidev
import os
import sys
import RPi.GPIO as GPIO
import subprocess
# FPS制御 -----
# ターゲットFPS
target_fps = 200
start_time = time.time()
frame = 0
# initial skip
skip = 7
# Shut down sw is assigned to GPIO17
# GPIO initialize
SHUTDOWN = 17
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(SHUTDOWN, GPIO.IN)
GPIO.setup(SHUTDOWN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# wait for spidev driver ready
time.sleep(20)
def handle_sw_input():
# wait key inout event
def switch_callback(gpio_pin):
subprocess.call('sudo shutdown -h now', shell=True)
#
GPIO.add_event_detect(SHUTDOWN, GPIO.FALLING,bouncetime=250)
# when the sw was pushed, call the 'call back routine'
GPIO.add_event_callback(SHUTDOWN, switch_callback)
return
handle_sw_input()
# SPIセンサ制御 -----
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 1000*1000
def ReadChannel(channel):
adc = spi.xfer2([(0x07 if (channel & 0x04) else 0x06), (channel & 0x03) << 6, 0])
data = ((adc[1] & 0x0f) << 8 ) | adc[2] return data # reset the seisamic intensity with open("/home/pi/python/value.txt", "w") as file: file.write("0") file.close() # 加速度データ制御 ----- # A/Dコンバータ値 -> ガル値 係数
ad2gal = 1.13426
# 0.3秒空間数
a_frame = int(target_fps * 0.3)
# 地震データ -----
adc_values = [[1] * target_fps, [1] * target_fps, [1] * target_fps]
rc_values = [0, 0, 0]
a_values = [0] * target_fps * 5
adc_ring_index = 0
a_ring_index = 0
# リアルタイム震度計算 -----
while True:
# リングバッファ位置計算
adc_ring_index = (adc_ring_index + 1) % target_fps
a_ring_index = (a_ring_index + 1) % (target_fps * 5)
# 3軸サンプリング
for i in range(3):
val = ReadChannel(i)
adc_values[i][adc_ring_index] = val
# フィルタ適用及び加速度変換
axis_gals = [0, 0, 0]
for i in range(3):
offset = sum(adc_values[i])/len(adc_values[i])
rc_values[i] = rc_values[i]*0.94+adc_values[i][adc_ring_index]*0.06
axis_gals[i] = (rc_values[i] - offset) * ad2gal
# 3軸合成加速度算出
composite_gal = math.sqrt(axis_gals[0]**2 + axis_gals[1]**2 + axis_gals[2]**2)
# 加速度リングバッファに格納
a_values[a_ring_index] = composite_gal
# 0.3秒以上継続した合成加速度から震度を算出
seismic_scale = 0
min_a = sorted(a_values)[-a_frame]
if min_a > 0:
seismic_scale = 2 * math.log10(min_a) + 0.94
# 0.1秒おきに出力
if frame % (target_fps / 1) == 0:
if seismic_scale > 0.5:
if skip > 1:
skip -= 1
else:
with open("/home/pi/python/value.txt", "w") as file:
file.write(str(round(seismic_scale, 1)))
file.close()
#print(datetime.datetime.now(), "scale:" , round(seismic_scale, 2), " frame:", frame)
# 次フレームの開始時間を計算
frame += 1
next_frame_time = frame / target_fps
# 残時間を計算し、スリープ
current_time = time.time()
remain_time = next_frame_time - (current_time - start_time)
if remain_time > 0:
time.sleep(remain_time)
# フレーム数は32bit long値の上限あたりでリセットしておく
if frame >= 2147483647:
start_time = current_time
frame = 1表示(disp1.py)にはvalue.txtファイルを介在してデータ渡してます、時間情報と合わせてsqlite3に格納するようにする予定
<disp1.py>
import time
import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
# Define the Reset Pin
oled_reset = digitalio.DigitalInOut(board.D4)
# Change these
# to the right size for your display!
WIDTH = 128
#HEIGHT = 32 # Change to 64 if needed
HEIGHT = 64 # Change to 64 if needed
BORDER = 5
# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset)
# Use for SPI
# spi = board.SPI()
# oled_cs = digitalio.DigitalInOut(board.D5)
# oled_dc = digitalio.DigitalInOut(board.D6)
# oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, oled_dc, oled_reset, oled_cs)
# Clear display.
oled.fill(0)
oled.show()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new("1", (oled.width, oled.height))
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
# Load default font.
font = ImageFont.truetype("fonts-japanese-gothic.ttf", 32)
#font = ImageFont.load_default()
# Draw Some Text
while True:
with open("/home/pi/python/value.txt", "r") as file:
text = file.read()
image = Image.new("1", (oled.width, oled.height))
draw = ImageDraw.Draw(image)
#text = str(mag)
(font_width, font_height) = font.getsize(text)
draw.text(
(oled.width // 2 - font_width // 2, oled.height // 2 - font_height // 2),
text,
font=font,
fill=255,
)
# Display image
oled.image(image)
oled.show()
time.sleep(1)震度は対数メモリでの尺度だから、震度七の強烈さはよく実感できます。
admin
部品実装と配線、配線チェックと単体の機能試験まで、
① 回路図:ライブラリが存在しないパーツは適宜置き換え、三端子、加速度センサー、OLECD、ライブラリあったのはラズパイI/FとADCだけという結果
アナログ電源はノイズ除去のためにL/Cでπ型のフィルタ構成にしています、ラズパイやM5StackなどのADCではデジタルノイズ混入しまくりだし、精度も10ビットしか取れないので震度計算の目的には使えないでしょう
P.S. 2024/10/1 回路図誤記修正(MCP3004電源)
② 実装と配線
アナロググランドは一点アース、この程度の周波数だとそれがベストだろう
③ 機能確認
・OLCD
https://qiita.com/tkarube/items/6808538012cba499d5e2
CircuitPythonのライブラリを使うのが今は推奨だが、動くだけなら旧ライブラリでも動くようだ
・加速度センサー
https://note.com/upyc101/n/nd3a1d606adf2
静止状態で一万回読み出して、最大値と最小値は、
python ./main.py
1259 1262
2045 2048
1843 1847z, y, x座標の値ですが、z軸の値は重力加速度が加算(モジュールを裏返しにしている)されます。ガル値の計算では測定値からオフセットは差し引いていますが
S/Nでフルスケールに対してノイズレベルはおよそ60dB(およそ2/2000)はとれてるからまあまあではないか、
サンプルの最大・最小値を求めるために、リンクのコードのmain.pyは以下に変更、
import sub1
value_array = [
[4000, 0],
[4000, 0],
[4000, 0]
]
adc = sub1.adc() # クラス adc のインスタンスを作成
for j in range(10000):
for i in range(3):
c = adc.rdadc(i)
if c > value_array[i][1]:
value_array[i][1] = c
if c < value_array[i][0]:
value_array[i][0] = c
print(value_array[0][0], value_array[0][1])
print(value_array[1][0], value_array[1][1])
print(value_array[2][0], value_array[2][1])
admin
日本はいつも地震がどこかで発生しているから、自宅の揺れぐらいは観測してみたい。
https://greensoybean.hatenablog.com/search?q=地震計
を参考に作ってみる、最終的にはコードはRustにしてしまうつもりだけど、
地震計用のラズパイzeroはだいぶ前に調達済みで、地震計用の加速度計、三端子レギュレータ、ユニバ基板とコネクタ、ADコン、OLEDは部品調達して、基盤においてみた。
次のステップはアナロググランドとデジタルグランドをセパレーションして配線すること。
admin
当然ながらzeroの能力ではRustのコンパイルには時間かかるので、クロス環境が必要です。以前Golang用のDocker(QEMU環境)では上手くいかなかった、おそらくlinkerの問題なのか、ので代替え案としてIntel MacのVMware環境でのUbuntuで環境作りました。
https://www.freecodecamp.org/news/embedded-rust-programming-on-raspberry-pi-zero-w/
を参考にしています。
いくつか修正が必要だったので、そこを記述します。
・ターゲットインストールのコマンドはtargetとaddが逆になってる
$ rustup target add arm-unknown-linux-gnueabihf configはobslete
・~/.cargo/configを使うのは古くて(obsoleteと言われる)コンパイル通らないから、.cargo/config.tomlに入れる(以下のように)てlinker対象ファイルはパスを通すかフルパスで指定
[target.arm-unknown-linux-gnueabihf]
linker = "/rpi_tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
・hello worldのサンプルプログラムをcargo initで作成(sampleディレクトリに)してコンパイル
fn main() {
println!("Hello, world! from Ubuntu compiler");
}$ cargo build --release --target=arm-unknown-linux-gnueabihf
・バイナリをラズパイに転送(実行ファイルはsample/target/arm-unknown-linux-gnueabihf/release以下に存在)
$ scp release/sample pi@192.168.1.16:~/sample
・ラズパイで実行
$ ./sample
Hello, world! from Ubuntu compiler
ただし、
https://github.com/raspberrypi/tools
のページには、
These toolchains are deprecated. They are outdated and easily available from other sources (e.g. direct from Ubuntu apt). e.g.
sudo apt-get install gcc-arm-linux-gnueabihfとあるので、このやり方の方がスマートなのかもしれない。
クロスコンパイルには他にはcrossとDockerを使うやり方もありますが、それほどのアドバンテージがあるようには思えないから当面この環境かな。
admin