モーションセンサーIPM165とESP32
 
IPM-165を前に購入したんですが、使いきれず、
手っ取り早く
これ
 https://akizukidenshi.com/catalog/g/gK-07776/
 を買ったら、やりたい事はできたので
 ほったらかしだったんですが、
 本日、意を決して再挑戦した記事です。
 上記2つはほぼ価格も変わらないので7776の方が使いやすくて良いです。
 
色々調べてみた。
digikeyによると、オペアンプ2個かましてあげると良いっぽい。

 
それでは、という事で、
手持ちパーツからオペアンプLM358NとコンパレーターNJM2403D
このコンパレーターもはるか昔買ったんですけどね。
もうね、秋月でも扱っていないですね。
秋月でデータシート見るのが好きなんですが。ないですね。
良いんですよ。他で見ますからね。
 
■回路図

※最後の段のESPの35への所の10KΩが無いとコンパレーター的にはうまく動かないみたい。
オペアンプとコンパレーターの組み合わせで一本作っておいた方が実験はかどるかもですね。
出力側が5Vで出ちゃうのでESP32へつなぐ時は分圧が必要です。
応用として増幅率の抵抗とかは取り換えられるようにして。
実験用に一台作っておくと便利かもしれませんね。
コンパレーター用の可変抵抗も変えられるので良い感じと思いますしね。
たぶん、焦電系のAKE-1とかも同じ回路で動く気がするが、今日はもう時間切れ。
 
 

■プログラム

 

GPIOがONになったら、ONって表示するだけ。

from machine import Pin
import utime

print("GPIO35")

D35 = Pin(35, Pin.IN)

while True:
  if D35.value()==1 :
    print("ON")
    utime.sleep(1)

 

 


JUGEMテーマ:電子工作


においセンサーtgs2450をESP32で使う
 後ろに後日談追加2022/09/04
■tgs2450について
においセンサ TGS2450
においセンサーという表記に釣られて買ってみた。
メチルメルカプタンと硫化水素に反応するとのことです。
使い方を見ると
端子は4本だけど、2番は使わない。
1 GND
2 NC
3 センサー値(電圧)
4 ヒーター(1.6V 8msec)

 
250ミリ秒に8ミリ秒だけ、ヒーターに電圧を与えるって事なので、
あんまり電気使わないって事になっているみたいですね。
 
サンプルプログラムを見ると、8ミリ秒ヒーターに電圧を与えてから、
240秒待って、冷えてから?センサーの値を測定しているみたいなので
それに従う。
 
秋月の参考回路ではTTA008Bというトランジスタを使うようになっているが、
手持ちで出来るだけ電流流せるやつって事で、2SC4511を使ってみた。
NPN型なので、回路図も適当にいじくってみてます。
 
 
■回路図
 

■試験結果
 
息を吹きかけても反応しました。口臭い?
接着剤でも反応しました。
グラフは黄色い木工用ボンドの例です。

 
元の値に戻るのに時間かかり過ぎな気がする。
 

■プログラム


from machine import ADC
from machine import Pin
import utime

adc = ADC(Pin(35))
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)

raw_voltage = adc.read()

D14 = Pin(14, Pin.OUT, value=0)
D15 = Pin(15, Pin.OUT, value=0)

while True:
  utime.sleep(0.237)
  D15.value(1)    #センサーON
  utime.sleep(0.003)
  raw_voltage = adc.read()
  utime.sleep(0.002)
  D15.value(0)    #センサーOFF
  
  
  D14.value(1)    #ヒーターON
  utime.sleep(0.008)
  D14.value(0)    #ヒーターOFF

  print("value="+str(raw_voltage))
  

■後日・・・・あの後ですね。なんかうまく動かなくなりまして。
例によって酔っぱらって壊したみたいで。

秋月から新しいTGS2450が届いたので再度やってみました。
で、ですね。センサーのヒーターにお届けする電圧が
うまく出ていないことに気づいたので抵抗値を調整したものがこれです。

 

■新回路図

 

■反応グラフ

 

 

宝っこでやってみました。

 

■宝っこだからなのか?

抵抗を低いものにして反応値を上げたためなのか?

それとも、ヒーターの電圧を上げたせいなのかは謎ですが、

前回のテストよりもずいぶん反応が早いですね。

 

おそらく・・・

Heaterを1.37Vにすれば、ヒーターの抵抗が10Ωぐらいとの事なので、

定格の電流である138mAが流れるので最大限性能を発揮するのでしょう。

したかがって、こっちを正解・・・って事にしておきます。

 

ちなみに、トランジスターを2SC1815にした影響はほぼない模様。

もともと、電流を大きく流したいと思って2SC4511を選んだわけですが、

150mA程度流せれば良くて、2SC4511は6A流せる訳ですから単にオーバースペックって事でした。

hfeを考えると逆に2SC1815の勝利ってこともありますので、こっちが適切って事でお願いします。

 

■記念写真

 


JUGEMテーマ:電子工作
 

■CO2センサーMH-Z19Cの使い方

 

■配線

 USBuart MH-Z19C
 5V-------Vin
 TX-------RX
 RX-------TX
 GND------GND

 

■ソース(パソコン側)

 

import serial
import time

ser = serial.Serial("COM10", 9600, timeout=1)

while True :
  b = bytearray([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
  ser.write(b)
  time.sleep(0.1)

  result = ser.read(9)
  print(str(result[2])+" - "+str(result[3]))
  ppm = result[2]*256+result[3]
  print("ppm="+str(ppm))
  time.sleep(5)

 

■ESP32と接続

ESP32が3.3V動作なのでMH-Z19Cからの戻りのTXは分圧しています。

# ESP32      MH-Z19C
# 5V-----------------Vin
# 33(TX)-------------RX
# 32(RX)----+--2KΩ--TX
#            |
#          3.3KΩ※
#            |
# GND-------+--------GND

 

■ソース

#
# Co2センサー MH-Z19C
#

#接続
#
# ESP32      MH-Z19C
# 5V-----------------Vin
# 33(TX)-------------RX
# 32(RX)----+--2KΩ--TX
#            |
#          3.3KΩ※
#            |
# GND-------+--------GND
#
# ※ MH-Z19CのTXが5Vなので、
#    分圧してESP32が破壊されないようにする
#    RXは3.3Vぐらいで出ると思われるがMH-Z19Cで
#    きちんと読み取ってくれるので問題ない
#

from machine import UART
import time

uart = UART(2, baudrate=9600, tx=33, rx=32)

while True:
  b = bytearray([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
  uart.write(b)
  time.sleep(0.1)    #少し待たないと後ろの処理がエラーになる
  result = uart.read(9)
  #print(str(result[2])+" - "+str(result[3]))
  ppm = ( result[2] * 256 ) + result[3]
  print("ppm="+str(ppm))
  time.sleep(5)


JUGEMテーマ:電子工作


ESP32-WROVER-Eピッチ変換キット [AE-ESP32-WROVER-E-BO]でマイクロパイソンで遊ぶ
秋月電子にてwroom32のピッチ変換基盤だと思って買ってきたんですが。
WROVERだった事とかはちょっと想定外だっだけど。
esp32-20220618-v1.19.1.binをダウンロードしてきて書き込む所まで。手順をまとめておきました。
 
mycropythonのダウンロードURL
 https://micropython.org/download/esp32/
 検索キーワード
   micropython esp32 download bin  とかで探せば本家のサイトが見つかります。
で、これをWROVERのピッチ変換基盤に搭載されたWROVERに書き込む方法ですが、
ちょいちょいと、ブレッドボードで回路を組んでくださいな。
 
回路図。
 

 
 
回路のピン配置とESP32-WROVER-Eピッチ変換キット様のピン配置とは異なるので
名前で当ててください。
パソコン側にESPツールをインストールする必要があります。
 https://ken5owata.hatenablog.com/entry/2017/10/21/003706
  自分も最初こちら参考にさせてもらいました。
 
で、上記の回路でパソコン側とUART接続して、Teratermでみながら
回路の二つのボタンを操作します。
 ①IO0をON 離さない。
 ②ENをON
 ③ENをOFF
 ④IO0をOFF 離す
とすると、わかるんですが、
rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download
とか言ってダウンロードモードに入ることを確認して。
テラタームを閉じて、
コマンドプロンプトを開き、
 先ほどダウンロードしたmicropythonのバイナリのディレクトリーに移動して
  例・・・
   cd c:¥esp32
 まずは、フラッシュの消去コマンド
  esptool.py --port COM3 erase_flash
  ↑COM3部分はteratermでつなげてうまくいく所です。
  ↑esptoolは上のURLを参考にしてインストールしてください。
  ↑上に書いた回路の二つのボタンを操作します。①②③④
 リセットのため、ENボタンを一回押して離してください。
 次にmicropythonバイナリの転送をします。
  esptool.py --port COM3 --baud 460800 write_flash --flash_mode dio --flash_size=detect 0x1000 esp32-20220618-v1.19.1.bin
  ↑上に書いた回路の二つのボタンを操作します。①②③④
 リセットのため、ENボタンを一回押して離してください。
 
これで、micropython動くようになっています。
teratermでつなげてmicropythonのプロンプト
   >>> 
が出ていれば動いています。
 
うまくいかなくて
 Brownout detector was triggered
 と出ている場合は電源不足です。3.3VのACアダプタを接続してやってみてください。
 
mycropythonが無事動くようになって、
WIFIのアクセスポイントを開く命令とかWIFI関連命令でBrownout detector was triggeredが出ている場合は
自分自身のWIFI電波の高周波ノイズのせいでおかしくなるみたいです。
回路を最短距離で組むなど工夫すると治る場合があります。ブレッドボードじゃ無理です。
 あと、回路のプラス電源とGND間にコンデンサーをくっつけてください。回路図の0,1μFがそれです。
 ↑高周波ノイズに強くなります。
 ↑前にwroom02で経験済み
 ↑結局安全に遊ぶには、DEVKITが有効です。
 ↑安く手に入れてなんかしようとすると失敗する例です。
 ↑自分の場合はdeepsleepの恩恵にあずかりたくて、
 ↑devkitで試した場合は5mAまで下がったんですが、
 ↑もっと下げたいと思うと、wroomとかwroverを直接ってなるんですよね。
 ↑最短で回路を組むのはこの後か明日か今週か来週でやるんですけど、今日はもうここまでで〆ます。
 
最短で回路組んでDHT22で温度湿度測定、WIFIでデータ送信、1分DeepSleepの繰り返しで
900mAの電池で
    7/25 7:00 開始
    7/27 7:00 終了
    48H
の結果でした。思ったよりも短い気がしますが、そんなもんかな。
 
で、ですね。上のDHT22のやってて気づいた点ですが、
ESP32のENをHIGHにしてあげないと電源を入れただけでは、プログラム動くとこまで行かなかったので、メモしておきます。
最小限の回路を記載しておきます。
 
 

 


JUGEMテーマ:電子工作


庭とか野原に置きっぱなしにできるマイコン用給電システム(ありもので作ってみた)
失敗!!日が当たらない場合にSOLARパネルへの逆電流が30mAも発生することが判明!!
実験も停止中。
 
 

 
①ソーラーパネルからの出力が6V
②7805からの出力が5V
③Eneloopは4本で4.8Vなので、充電は1.1倍の5.28Vまで上げても
  安全と思われますが、パーツがありものなので、
  7805からの出力で良いことにします。
④48033からの出力が3.3Vで、ESP32の等のマイコンなら
 消費電流が200mAぐらい取り出せればOKなので、
 使用してみたい。
※個人的DIYなので逆電流が・・・みたいなところは
 無視しております。実用性に関しては・・・のちのレポートにて。

 
電流が230mAになるように負荷を調整して動き始めてみた。2022/7/24

 
敗北感が漂いつつ、二日経過するなか、
逆電流対策として、ダイオードを導入することに決めたが、
ありもののパーツ縛りだったので、
壊れてしまった電気毛布のコントローラーからダイオードを取り出す事を思いつき、
継続している状況ですが、今日は雨。
 
新回路はこちら。
 

 
①ソーラーパネルからの出力が6V
②ダイオ-ドの後段の出力が5.4V
③Eneloopは4本で4.8Vなので、充電はトリクル充電なら
  1.1倍の5.28Vですが、根性で耐えてくれ。
  固体電池なんで安全と思われますが、パーツがありものなので、
  ダイオードからの出力で良いことにします。
④48033からの出力が3.3Vで、ESP32の等のマイコンなら
 消費電流が200mAぐらい取り出せればOKなので、
 使用してみたい。
※前の実験で逆電流が流れるのが判明しているのでダイオードに
 なった分Eneloopには負荷がかかるかもですね。
 実用性に関しては・・・のちのレポートにて。
 
■振り返り
 
前回の7805と記載している個所は、実際にはNJM2396F05を使っておりました。
7805が同じ動作かはわかりませんが、
OUT側に4.8VをつなぐとIN側に電圧が現れます。実際に電圧を測定したけど忘れた。
この電圧が、余計な消費電流を生む事で、元々やりたかったの省電力で屋外で、
マイコンを動かすという目的とはずれてしまうことと、ソーラーパネルにダメージがある事で
寿命を縮めてしまい、本来やりたかったソーラーパネルによる24時間運転からもはずれてしまう事から、
ダイオードでやる事にしてみました。
ENELOOPはNi-MH電池で、Ni-MHは水素吸蔵合金を使用していて、個体?って解釈で会ってますかね?
電池の電圧と、ソーラーの電圧が拮抗しているときに、
電池側のON/OFFが繰り返されて電極に抵抗が生じるって現象が起きるとダメになるっぽいですよねー。
浅はかな知識ですんません。ですが、その現象が発生するまで。発生したとしてもどのぐらい使えて
実用出来であればいいかなー的な自己満足系の実験なんでご勘弁ください。
 
■箱に収めて。
 
試験運用開始 2022/8/6
 
 
 

 
9/4 停止していた。
 しばらく雨や曇りだったので、さすがに、バッテリー切れたかなーと思い、
 放っておきましたが、晴れててもダメだったので、回収してばらしてみたところ、
 充電すれば動き出しましたので、バッテリーから後段は大丈夫みたいです。
 太陽光パネル側を調べてみたところ、電圧が来ていないみたいでしたので、
 目視確認で、太陽光パネル側の端子が劣化しておりました。
 (端子むき出しではさすがに持たないね、でもひと月持った。)
 一度はんだを溶かしてケーブルを付けなおしました。
 さらに、
 黒ペンキで防水!?たぶん、少しは防水効果あるはずって事で、余計なカネをかけずに
 対処したものを本日2022/9/18から運用開始です。
 
 
 
後日談。11/24
やっぱりひと月ぐらいで停止する症状が出るのでいろいろ調べたり、直したり。
でね。電池は大丈夫っぽいので、ESP32側のIO0を+側に接続してみたり、
でも、太陽光だけだとESP32が起動しない。WIFIの電波発射で止まるとかそんな感じだったので、
電源に10000μFを接続してみたところ、太陽光パネルだけでも安定したのでこうなっております。

 

 


 
 

ESP32-BME280気圧計

 

DHT22で温湿度計をよく作っておりましたが、
これから台風シーズンということで・・・
気圧計も作ってみました。

 


■回路図

I2C通信します。

 

 

 

SDOがGNDに接続されておりませんでした。

接続しない場合は動作が安定しないようです。

 

■プログラム

 

※BME280をmicropythonで使う例です。

 class BME280は先人たちが苦労して作ったものに独自の改造を施しております。

 classはそのまま使えると思います。

 呼び出しは下のほうのコメントmain以下を参考にしてください。

 

import machine
from machine import SoftI2C, Pin

import time
from ustruct import unpack, unpack_from
from array import array

# BME280 default address.
BME280_I2CADDR = 0x76

BME280_REGISTER_CONTROL_HUM = 0xF2
BME280_REGISTER_CONTROL = 0xF4


class BME280:
    def __init__(self,
                 address=BME280_I2CADDR,
                 i2c=None,
                 **kwargs):
        # Check that mode is valid.
        self._mode = 1
        self.address = address
        if i2c is None:
            raise ValueError('An I2C object is required.')
        self.i2c = i2c

        # load calibration data
        dig_88_a1 = self.i2c.readfrom_mem(self.address, 0x88, 26)
        dig_e1_e7 = self.i2c.readfrom_mem(self.address, 0xE1, 7)
        self.dig_T1, self.dig_T2, self.dig_T3, self.dig_P1, ¥
            self.dig_P2, self.dig_P3, self.dig_P4, self.dig_P5, ¥
            self.dig_P6, self.dig_P7, self.dig_P8, self.dig_P9, ¥
            _, self.dig_H1 = unpack("<HhhHhhhhhhhhBB", dig_88_a1)

        self.dig_H2, self.dig_H3 = unpack("<hB", dig_e1_e7)
        e4_sign = unpack_from("<b", dig_e1_e7, 3)[0]
        self.dig_H4 = (e4_sign << 4) | (dig_e1_e7[4] & 0xF)

        e6_sign = unpack_from("<b", dig_e1_e7, 5)[0]
        self.dig_H5 = (e6_sign << 4) | (dig_e1_e7[4] >> 4)

        self.dig_H6 = unpack_from("<b", dig_e1_e7, 6)[0]

        self.i2c.writeto_mem(self.address, BME280_REGISTER_CONTROL,
                             bytearray([0x3F]))
        self.t_fine = 0

        # temporary data holders which stay allocated
        self._l1_barray = bytearray(1)
        self._l8_barray = bytearray(8)
        self._l3_resultarray = array("i", [0, 0, 0])

    def read_raw_data(self, result):
        """ I2Cインタフェースからデータ取得
        """

        self._l1_barray[0] = self._mode
        self.i2c.writeto_mem(self.address, BME280_REGISTER_CONTROL_HUM,
                             self._l1_barray)
        self._l1_barray[0] = self._mode << 5 | self._mode << 2 | 1
        self.i2c.writeto_mem(self.address, BME280_REGISTER_CONTROL,
                             self._l1_barray)

        sleep_time = 1250 + 2300 * (1 << self._mode)
        sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
        sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
        time.sleep_us(sleep_time)  # Wait the required time

        # burst readout from 0xF7 to 0xFE, recommended by datasheet
        self.i2c.readfrom_mem_into(self.address, 0xF7, self._l8_barray)
        readout = self._l8_barray
        # pressure(0xF7): ((msb << 16) | (lsb << 8) | xlsb) >> 4
        raw_press = ((readout[0] << 16) | (readout[1] << 8) | readout[2]) >> 4
        # temperature(0xFA): ((msb << 16) | (lsb << 8) | xlsb) >> 4
        raw_temp = ((readout[3] << 16) | (readout[4] << 8) | readout[5]) >> 4
        # humidity(0xFD): (msb << 8) | lsb
        raw_hum = (readout[6] << 8) | readout[7]

        result[0] = raw_temp
        result[1] = raw_press
        result[2] = raw_hum

    def read_compensated_data(self):
        """ データを読んで気温、気圧、湿度に分解
        """
        self.read_raw_data(self._l3_resultarray)
        raw_temp, raw_press, raw_hum = self._l3_resultarray
        # temperature
        var1 = ((raw_temp >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11)
        var2 = (((((raw_temp >> 4) - self.dig_T1) *
                  ((raw_temp >> 4) - self.dig_T1)) >> 12) * self.dig_T3) >> 14
        self.t_fine = var1 + var2
        temp = (self.t_fine * 5 + 128) >> 8

        # pressure
        var1 = self.t_fine - 128000
        var2 = var1 * var1 * self.dig_P6
        var2 = var2 + ((var1 * self.dig_P5) << 17)
        var2 = var2 + (self.dig_P4 << 35)
        var1 = (((var1 * var1 * self.dig_P3) >> 8) +
                ((var1 * self.dig_P2) << 12))
        var1 = (((1 << 47) + var1) * self.dig_P1) >> 33
        if var1 == 0:
            pressure = 0
        else:
            p = 1048576 - raw_press
            p = (((p << 31) - var2) * 3125) // var1
            var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
            var2 = (self.dig_P8 * p) >> 19
            pressure = ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)

        # humidity
        h = self.t_fine - 76800
        h = (((((raw_hum << 14) - (self.dig_H4 << 20) -
                (self.dig_H5 * h)) + 16384)
              >> 15) * (((((((h * self.dig_H6) >> 10) *
                            (((h * self.dig_H3) >> 11) + 32768)) >> 10) +
                          2097152) * self.dig_H2 + 8192) >> 14))
        h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4)
        h = 0 if h < 0 else h
        h = 419430400 if h > 419430400 else h
        humidity = h >> 12

        #return array("i", (temp, pressure, humidity))
        return (temp, pressure, humidity)

    def values(self):
        """ 温度、気圧、湿度を返却する """

        t, p, h = self.read_compensated_data()

        #print("t="+str(t/100))
        #print("p="+str(p//256/100))
        #print("h="+str(h/1024))
        
        return(t/100, p//256/100, h/1024)

#
#main
#

pin22 = machine.Pin(22, machine.Pin.IN, machine.Pin.PULL_UP)
pin27 = machine.Pin(27, machine.Pin.IN, machine.Pin.PULL_UP)
i2c = machine.SoftI2C(scl=pin22, sda=pin27)

bme = BME280(i2c=i2c)
bme280_temp, bme280_press, bme280_humid = bme.values()

print("bme280_temp="+str(bme280_temp))
print("bme280_press="+str(bme280_press))
print("bme280_humid="+str(bme280_humid))


JUGEMテーマ:電子工作


温度計を作って、東京のアパートと仙台のおうちのお部屋の温度を測ってみました。
 
■回路
 

 
■センサー写真


 
 

 

 
 
 
 
■サーバ側の画面
 

 
 
 

■サーバ側

 

list.cgiからimg.cgiを呼び出しています。
img.cgiは温度計の画像に温度を上書き表示する例となります。


■サーバ側のソース

 

■サーバ側

 

list.cgiからimg.cgiを呼び出しています。
img.cgiは温度計の画像に温度を上書き表示する例となります。


■サーバ側のソース

 

list.cgi

 

#! /usr/bin/perl

#
# MHR温度計システム
#  2022/03/21 : 新規作成
#
#一覧を表示する
#
# パラメータ : なし
#
# 機能 :
#    sensorテーブルを全レコード対象に一覧を表示する
#    linkをクリックすると詳細画面に遷移する
#

print "Content-type: text/html; charset=utf-8¥n¥n";
print "<meta http-equiv=refresh content=30; URL=>";

#DB接続
use DBI;
my $database = 'database-database';
my $host = 'mysql.db.sakura.ne.jp';
my $userid = 'ID';
my $pass = 'PASS';
my $data_source = "dbi:mysql:database=$database;host=$host";
my $dbh = DBI->connect($data_source, $userid, $pass);

#DBはutf8を宣言
$dbh->do("set names utf8");

#sensorテーブルを全部読み込み
my $sth = $dbh->prepare("select sensor_id, sensor_name, sensor_ondo, sensor_shitudo, last_update from sensor order by display_order;");
$sth->execute;

#html出力
print "センサー一覧<br>";
print "<blockquote>";
print "<table border='1' style='border-collapse: collapse' cellpadding='10'>";
print "<tr>";
print "<td width='40%' style='text-align: center;'>センサー</td><td style='text-align: center;'>温度℃ </td><td style='text-align: center;'>湿度% </td><td style='text-align: center;'><font size='-4'>通信日時 <br>(ID)</font></td>";
print "</tr>";
while (my @row = $sth->fetchrow_array) {
  #print join(', ', @row);
  $row[2] = f($row[2]);
  $row[3] = f($row[3]);
  print "<tr><td>";
  print "<font size='+2'>";
  print "<a href='detail.cgi/?id=",@row[0],"'>";
  print "<img src='img.cgi/?ondo=$row[2]&shitudo=$row[3]' width=100 height=100>";
  print "<p style='text-align: right'>";
  print $row[1];
  print "</p>¥n";
  print "</a>¥n";
  print "</font>";
  print "</td><td style='text-align: center;'>";
  print $row[2];
  print "</td><td style='text-align: center;'>";
  print $row[3];
  print "</td><td style='text-align: center;'>";
  print "<font size='-4'>";
  print $row[4]." <br> (".$row[0].")";
  print "</font>";
  print "</td></tr>";
}
print "</table>";
print "</blockquote>";

#DB切断
$dbh->disconnect;

#小数点一位までにする
sub f {
  (my $v) = @_;
  my $str = sprintf("%.1f", $v);
  return ($str);
}

 

 

img.cgi


#!/usr/bin/perl

#use GD::Graph;
use GD;
use CGI;

#パラメータ取得
my $q = new CGI;
my $ondo = $q->param('ondo');   #温度
my $shitudo = $q->param('shitudo');   #湿度

my $str_ondo = "   ".$ondo;
my $ondo = substr($str_ondo, -5, 5);
my $str_shitudo = "   ".$shitudo;
my $shitudo = substr($str_shitudo, -5, 5);

#png読み込み
$im= newFromPng GD::Image('ondokei.png');

#色
$white = $im->colorAllocate(255,255,255);
$black = $im->colorAllocate(0,0,0);       
$red = $im->colorAllocate(255,0,0);      
$blue = $im->colorAllocate(0,0,255);

#透明色とインターレスを指定
$im->transparent($white);
$im->interlaced('true');

#$im->string(GD::Font->Large,40,40,"0123456789",$red);

#文字出力
#$im->stringFT($black, './FONT/GOTHIC_FONT.ttf', 70, 0, 120, 178, "31.2");
#$im->stringFT($black, './FONT/GOTHIC_FONT.ttf', 70, 0, 120, 290, "56.8");
$im->stringFT($black, './FONT/GOTHIC_FONT.ttf', 70, 0, 85, 178, $ondo);
$im->stringFT($black, './FONT/GOTHIC_FONT.ttf', 70, 0, 85, 290, $shitudo);

#$im->line(10,10,50,50,$black);

#出力
print "Content-type: image/png¥n¥n";
print $im->png();


JUGEMテーマ:電子工作

ESP32のmicropythonにてLCDビットマップディスプレーに文字を出力する際にデータ操作で困った話。bytearray

 

python全般なんですが、文字列操作とか、+ でつなげたりできて便利なので

普通にバイナリデータ定義してループの奥底で末尾につなげる処理を書いたんですが、
これが遅いのなんのって。

 

data = b""
for 
  for 
    for
      data=data+rgb

 

そんでですね。色々調べたところによると、代入する場合に新たにメモリを取り直すとの事でして。orz...

 

c言語脳の自分としてはそんなあほな処理あるかいなーって思うわけですが、
最近のコンピューターの性能の進歩もあり、そんな思想でも普通は気にならないぐらいのスピードで動いてくれちゃったりするので、
pythonさんには感謝感謝なんですが、ESP32ぐらいまで処理性能が低くなると。

 

いや、ESP32はチョッ速です。なんたって、python動きますし。atmega328あたりに比べれば、クロック周波数10倍ですしメモリも問題なく。

 

とはいえ、ループの奥底で1バイトずつデータを足したいみたいな場合に代入のたびにメモリを確保する様な重い処理が入るのは
さすがに無理。って訳で聞いてみました。google先生。

 

google先生曰く、前もってmallocの様にメモリを確保しておいて、後から内容を変更できるのじゃ!!

ってことでしたのでこう書いてみた。

 

write_count=0
data = bytearray(size)
for 
  for 
    for
      data[write_count]=rgb
      write_count = write_count + 1

 

これだと、代入の時にいちいちメモリを確保しなおすことはなくなるみたいです。
代入の処理部分を見てもいまいち処理の違いがピンとこないのはアレですが、
bytearrayに感謝ですね。

 

参考

https://micropython-docs-ja.readthedocs.io/ja/latest/reference/speed_python.html#ram-allocation

楽天ひかりのIPv6(クロスパス)対応ルーター
 
最近では、在宅勤務でお仕事をすることが多くなり、
パソコンで資料を投影しながら会議とか普通になっておりますが、
自分だけが音声がすごく遅延したりする事があり、
何かおかしいなと思って我が家の楽天ひかりの情報を
調べていたら、なにやら、IPV6にすると早くなるらしい。
 
とのことが判り、
我が家のホームゲートウェイ(PR-400KI)の設定画面を調べると
IPv6の設定がPPPoEで接続であり、状態が停止となっており、
接続ボタンを押しても変わらず。という状況であった。

 
 
そして色々調べたところ
楽天のページで接続するだけで早くなるルーターなるものを発見!!

 
 
なんだよ、もっと早く言えよって感じですけど、
5千円ぐらいからあるし、NECのをポチっておいた。
もちろん楽天で購入。WG1200HP4
 
 
それでさ、何でIPv6だと早くなるのさ!!
って事が疑問だったので到着するまでに色々
調べてみたので書いておく。
 
我が家のホームゲートウェイ(PR-400KI)の場合
IPoEの設定の[ IPv6セキュリティのレベル ]を無効にしないと
ダメよ!!ってソフトバンクのページに書いてあったので
無効に設定。
 
 
光回線の接続方式が、昔はPPPoEしか無かったものですが、
今はIPoEという接続方式があり、
こちらは2020年ぐらいから出来るようになったっぽい。
 
IPoEとPPPoEの比較ですが、
 
PPPoEというのはPPP over Ethernetで、PPPとはPoint-to-Point Protocolで
Ethernetの上にPPPという論理的なセッションを張ってプロバイダーまで接続(この仕組みで認証)
 
IPoEというのはIP over Ethernetで、Ethernet上にIPをのっける。
↑それって普通のルーターとハブで構成されたIPネットワークと同じ意味ですよね。
とか思いつつ。
 
PPPoEの場合はISPがインターネットに接続してくれると思っていたけど、
こちらはVNEって人が登場してインターネットに接続してくれる。との事で。
 
VNEって何よってなる。
 
VNEとは仮想通信提供事業者で、
網終端装置を使わないでゲートウェイルーターという装置でインターネットに繋げてくれる。
 
で、今度は網終端装置
網終端装置はNTTフレッツのNGN網とプロバイダを接続している装置で、
これはプロバイダごとに用意され設置されていて、
装置単体では通信容量に限界があり、
ユーザ増加=トラフィック増加に伴って網終端装置を増やして行く。
 
との事で。
つまり、網終端装置が遅い。
網終端装置が遅いのでそれを使わない方式である、
IPoEならゲートウェイルーターという高速化しやすい装置を使っているので
早いですよね。って事みたいですね。
 
じゃ、認証どうするの?という話になると思いますが
 
NTTのページにこう書いてあった。抜粋
「IPoE方式とPPPoE方式では、認証方法にも違いがあります。
 PPPoE方式はIDとパスワードによるユーザー認証が必要である一方、
 IPoE方式ではアクセスしてきた回線による回線認証のみで
 IDとパスワードによる認証は不要です。
 ただし、IPoE方式ではIDもパスワードも不要となっているものの、
 セキュリティ的に脆弱というわけではありません。契約情報を基に、
 回線側からインターネット接続に必要な設定情報がルーターへと流れ込み、
 ユーザー認証をせずとも自動的にインターネットに
 接続されるようなしくみとなっています。」
 
回線認証+謎の仕組みで設定情報がルーターへと流れ込み+自動接続
の流れで繋がるっぽいですね。
 
それで、楽天対応ルーターの登場ってわけですか。
なんか判った。←わかったような気になっているだけ。
 
届きましたよ。楽天対応ルーター。
 
こう繋いだ。

 
 
これでPC1とPC2で「いっせいのせ」で速度測定開始。
測定サイトは
 https://www.musen-lan.com/speed/
 BNRスピードテスト
老舗の信頼性高い所ですね。
 
結果がこちら。
ちなみに、混雑時を狙いたかったので
土曜の夕方に実施。1Mぐらいまでしか下がらず。ひどい時はもっと下がるぞ。
PC1(IPv4のPPPoE)
 

 
912Kbps
 
 
PC2(IPv6のIPoE)

 
98.6Mbps
その結果は100倍速いですね。
 
 
 
PC2空いている時間帯。日曜朝

469Mbps←こんな数字見たことない。
 
昔々に光契約してそのままになっている人とかは沢山いると思うけど
それで、満足しているならいいのかもですが、
遅いなーと思っている人は、見直して快適になるのでぜひどうぞ。
 
 

 


JUGEMテーマ:電子工作


ESP32で電力測定したくて、秋月から電流センサーを買って電力を測定する記事です。
 高精度電流センサー(CTセンサー) 分割型 Φ10mm
 [SR-3704-150N]通販コード P-08960
前の記事でESP32で0V~3.3Vのレンジで電圧が測定できることが判明しましたので

 


 

 
 
センサーと接続しつつ、
ちゃんとプログラム組んで電力を表示してみたいと思います。
ポイントは以下の回路図の ここ の所の波形を
 
 

 
ESP32で読み取るという事をするんですが、
センサーを何にも接続しない状態で
まず、可変抵抗でここの電圧を1.6Vぐらいに調整しておきます。
で、センサーからくる信号が交流なので
電圧が合成されるとこんな波形になるんです。
 
 
 

(上の青いほうね。下のは1KHzの矩形波)
ESP32もそうですが、普通にマイコンのADCはマイナスの測定ができないので。
電源電圧を分圧して中心電圧を決めて、合成すると、マイコンに取り込める信号になります。
あとは前にやった方法で電圧を測定して、一定期間の電圧の平均を求めつつ、
上限値と下限値の差から電力を求めます。
実際に測定した結果、ESP32で取得できる値valあたり、5Wぐらいでしたので、
あとは計算値を画面に出力しています。
 

■ソース

 

import utime
import machine

pin36=machine.Pin(36, machine.Pin.IN)
adc0 = machine.ADC(pin36)
adc0.atten(machine.ADC.ATTN_11DB)

while True :
        val = 0
        min = 4096
        max = 0
        for i in range(50):
          total = 0
          count = 0
          for i in range(240):
                val = adc0.read()
                total = total + val
                count = count + 1
          try :
            ave = total / count
            if( min > ave) :
                min = ave
            if( max < ave) :
                max = ave
          except:
            print("dev-err")
        pp = max - min
        if pp<3.3 :
          pp=0
        else :
          pp=pp-0.0
        w = pp*5.4
        print(str(min)+" - "+str(max)+" - "+str(pp)+"-"+str(w)+"W")