eneloop(ニッケル水素電池)でESP32-WROOM-32Eを動かす

eneloopを4本用意してXC9306使用同期整流昇降圧DC/DCコンバータ[1]を噛まして3.3VにしてESP32-WROOM-32E開発ボード[2]にツッコんでみた。電池の電圧を測りつつ、その値をWiFi経由で5秒に1回udpパケットとしてサーバーに送るプログラムを書いて、どれだけ時間的にもつのか試してみた。

分かったことは2つ

  • 48時間は持たないけど、36時間ぐらいなら持つ
  • eneloopの電池の持ち方の特性は説明通りだった

5秒に一度128バイト程度のデータを送り続けるわけで、それで40時間ぐらいは持っているので、悪くはないというか、データシート[3]から想定される値と大きく違いはなかった。

eneloop[4]も一定の期間安定していて、最後にストンと落ちるニッケル水素電池の特性をきちんと示していた[fig1]。

つけっぱなしでも一日ぐらいは余裕で持つというということがわかった。

[1] XC9306使用同期整流昇降圧DC/DCコンバータ
https://akizukidenshi.com/catalog/g/g116055/

[2] ESP32-DevKitC-32E ESP32-WROOM-32E開発ボード 4MB
https://akizukidenshi.com/catalog/g/g115673/

[3] ESP32-WROOM-32E & ESP32-WROOM-32UE Datasheet
https://akizukidenshi.com/goodsaffix/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf

[4] エネループ(ニッケル水素電池)
https://panasonic.jp/battery/products/charge/eneloop.html

電池4本の電力変化グラフ (Fig1)

VirtualBoxでホストOSのUSB SerialをゲストOSのSerialにパススルーする方法は超簡単

ESP32をちょっといじってみることにしたのだが、ESP32開発環境を現在使っているUbuntuの環境に干渉させたくないので、VirtualBox上でUbuntu 22.04 LTS を動かして、そこで開発することにした。心配だったのがホストOS側に見えているUSB SerialをゲストOS側にパススルーする方法だった。

少し不安だったのだが、調べたらホストOSでUSB Serial (/dev/ttyUSB0)をゲストOSのSerial (/dev/ttyS0)にパススルーする方法はとても簡単で拍子抜けした。

基本これだけ。

GNU/LinuxでUSB経由のデータ転送パフォーマンスを改善する方法

USB 3.0接続で外付けHDDを接続し利用していたが、大きいデータの読み書きをすると使用しているHDD機種の標準的な転送速度をかなり下回るパフォーマンスしか出ていなかった。これまで、そういうものかと納得していた。先日別件でUSB経由でのデータ転送のパフォーマンスをあげる方法をみつけた。次のようにやってみると、実際にUSB 3.0接続の外付けHDDのパフォーマンスが大きく改善された。

# echo 256 > /sys/module/usbcore/parameters/usbfs_memory_mb

usbfs_memory_mbはUSBバッファサイズをコントロールするパラメータである。LinuxのUSBバッファサイズは16MBと小さい。これを256MBにあげてみた。実験してみると、ほぼ外部HDDの読み書きの性能(USB 3.0の転送速度より小さい)の上限レベルに達していた。

同じようにUSB 3.0接続の外付けHDDが思ったよりも遅いと悩んでいる人がいたら試す価値はある。

参考リンク
Understanding USBFS on Linux
https://www.flir.jp/support-center/iis/machine-vision/application-note/understanding-usbfs-on-linux/

形態素解析はJanomeが楽ちん

pythonで形態素解析するのはpipでインストールできるJanomeが楽ちんである。数十万ツイート分を形態素解析したのだが量が多いとツライ。せっかくメモリーもCPUコア数も十分にあるのにシングルタスク/シングルプロセスの処理では宝の持ち腐れである。そこで並列処理をしてスループットをあげた。ついでなので大量に行単位で用意されているテキストデータをjanomeを使って並列処理で処理する時のサンプルコードを書いてみた。ちなみに自分のマシンにあわせてCPU数は16にしてある。

githubの上はこちら

#
# How to use Janome with multi-processing.
# Hironobu Suzuki 2022/Aug/24
#
import sys
from multiprocessing import Pool, Manager
from janome.tokenizer import Tokenizer

def doJanome(lineData):
	text=lineData.text
	output=""
	for token in Tokenizer().tokenize(text):
		l=str(token).split('\t')
		k=str(l[1]).split(',')
		if k[0] == '動詞' and k[1] == '自立':
			output+=k[6]+","
		if k[0] == '名詞' and k[1] == 'サ変接続':
			output+=k[6]+","

	output=output.rstrip(',')	# 最後に余計な','がついているのを削除
	lineData.set(output)	# カンマで区切られた文字列 (CSV)
	return

class dataContainer:
	def __init__(self):
		self.text=""
		self.manager=Manager().list(range(0)) 

	def add(self,text_):
		self.text += text_	# 子プロセスに送るための入れ物

	def set(self,container_):	# 親プロセスに戻すための入れ物
		self.manager.append(container_)

	def get(self):
		return self.manager[0]


CPUs=16
textData=[]
for i in range(CPUs):
	textData.append(dataContainer())

content=sys.stdin.read()        # 標準入力からすべてを読み込む。

idx=0
for line in content.splitlines():
	textData[idx%CPUs].add(line) # 行単位で分配
	idx+=1

with Pool(CPUs) as pool:
	pool.map(doJanome,textData) # 並列処理

# 一覧作成
for content in textData:
	for w in content.get().split(','):
		print(w)