0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ゲインアンプ付きA/Dコンバータ(SX8725C)を用いた簡易地震計の製作 2(ノイズ対策)

Last updated at Posted at 2022-11-11

デモ用の地震計を作りたい

製作編は下記を参照
ゲインアンプ付きA/Dコンバータ(SX8725C)を用いた簡易地震計の製作 1(製作編)

DSC_3648.JPG

スパイクノイズ問題

製作編では良く分からずPGA3をガンガン持ち上げていたところ、スパイクノイズに悩まされた (縦軸:[mV], 横軸:10 [msec])。地震計未接続の状態でも乗ってくる。
スクリーンショット 2022-11-10 9.32.55.png

RaspberrryPi Pico の電源ノイズについて色々調べて試したのは2つ。

  • RT6150BをスリープにしてLDOでPicoに3.3Vを給電してみた。
  • SX8725CとPicoの物理的距離を変えた

今回は5Vを使っているためか、3.3Vの低ノイズ化のノウハウは効果が無かった。また距離も関係なさそうだったので、Pico側から侵入してくるとしたら電源ラインかGNDから直接っぽい。

次に、SX8725Cの内部でなんとかできないか考えた。SX8725Cのデータシートを見るとPGA2とPGA3は基準電圧の影響を受けそうだが、前段のPGA1は独立していそうだ。
スクリーンショット 2022-11-11 9.34.43.png

色々試したところ、PGA2もしくはPGA3で倍率を上げると問題のスパイクが乗ることが分かった。一方でPGA1のみだと現れない事が分かり、PGA2以降の段は1倍で使う事にした(Disableにはしていない)。地震計未接続の状態。
スクリーンショット 2022-11-11 8.59.33.png

地震計を接続した状態。1Hzの発振っぽいノイズはPC関連機器から遠ざけると弱まった。
スクリーンショット 2022-11-11 9.00.19.png

最終的に決定したレジスタの設定は 16bit, 差動入力, ゲインアンプ使用(Pga:x10, Pga2:x1, Pga3:12/12), 5[V]給電, 内部基準電圧(1.22[V])リファレンスとした。

regist.py
ValACCfg0 = b'\x1E' #30   #0b00011110
ValACCfg1 = b'\xFF' #255  #0b11111111
ValACCfg2 = b'\x00' #0    #0b00000000 #PGA2x1
ValACCfg3 = b'\x8C' #140  #0b10001100 #PGA1x10 PGA3 12/12
ValACCfg4 = b'\x00' #0    #0b00000000 #PGA3OFF 0 
ValACCfg5 = b'\x03' #3    #0b00000011 #diff, Vref
ValMode   = b'\x88' #132  #0b10000100 #pump off

後る課題

AD関係で残っているのは、オフセット電圧をPythonで微修正して誤魔化している点。レジスタのバイアスやオフセットの値を変えるも、微調整が難しく思い通りにできていない。

これでやっとスタートラインに立ったところで、後は地震計そのものの調整に入ることになる。一定時間測定して、ダンピング係数を確認したり、、、しかしちゃんとした地震観測に使う機材が手元に無いので、振幅等のキャリブレーションはしばらく難しい。

スクリーンショット 2022-11-11 9.01.04.png

MicroPythonコード

SX8725C.py
import utime
import machine

led = machine.Pin(25, machine.Pin.OUT)
RT6150_PS = machine.Pin(23, machine.Pin.OUT)
timer = machine.Timer()

led.value(1)
utime.sleep(0.5)
led.value(0)
utime.sleep(0.5)

i2c_bus_number  = 0
i2c_sda=machine.Pin(0)
i2c_scl=machine.Pin(1)
i2c=machine.I2C(i2c_bus_number,sda=i2c_sda, scl=i2c_scl, freq=100000)

#if we use only one i2c device, this code is useful to find the address.
addrlist = i2c.scan()
print( "address is :" + str(hex(addrlist[0])) )

addr = addrlist[0]
#addr = 0x48  # Default address of SX8725C
i2c_address = addr

Vref = 1.22  # for internal refernce
#Vref = 5.00   # for Vbatt reference
conversion_factor = Vref / (65535)
zero_shift = -3.7
#zero_shift = 0


# Define registers
RegACOutLsb = 0x50
RegACOutMsb = 0x51
RegACCfg0 = 0x52
RegACCfg1 = 0x53
RegACCfg2 = 0x54
RegACCfg3 = 0x55
RegACCfg4 = 0x56
RegACCfg5 = 0x57
RegMode   = 0x70

# Define values
ValACCfg0 = b'\x1E' #30   #0b00011110
ValACCfg1 = b'\xFF' #255  #0b11111111
ValACCfg2 = b'\x00' #0    #0b00000000 #PGA2x1
ValACCfg3 = b'\x8C' #140  #0b10001100 #PGA1x10 PGA3 12/12
ValACCfg4 = b'\x00' #0    #0b00000000 #PGA3OFF 0 
#ValACCfg5 = b'\x02' #2    #0b00000010 #diff, VBATT
ValACCfg5 = b'\x03' #3    #0b00000011 #diff, Vref
ValMode   = b'\x88' #132  #0b10000100 #pump off

reglist = []
reglist = list(range(0x50, 0x50+8))
reglist.append(0x70)

# --- Check default values (not required) ---
data=[]
for reg in reglist:
    readdata = i2c.readfrom_mem(addr,reg,1)
    data.append(int.from_bytes(readdata,'big'))
print(data)
#--------------------------------------------

#init
i2c.writeto_mem(addr,RegACCfg0,ValACCfg0)
i2c.writeto_mem(addr,RegACCfg1,ValACCfg1)
i2c.writeto_mem(addr,RegACCfg2,ValACCfg2)
i2c.writeto_mem(addr,RegACCfg3,ValACCfg3)
i2c.writeto_mem(addr,RegACCfg4,ValACCfg4)
i2c.writeto_mem(addr,RegACCfg5,ValACCfg5)
i2c.writeto_mem(addr,RegMode,ValMode) 

# --- Check current values (not required) ---
data=[]
for reg in reglist:
    readdata = i2c.readfrom_mem(addr,reg,1)
    data.append(int.from_bytes(readdata,'big'))
print(data)
#--------------------------------------------


def sign16(x):
    return ( -(x & 32768) | (x & 32767) );

#main
def readdata(timer):
    data = []
    for reg in (RegACOutLsb, RegACOutMsb):
        readdata = i2c.readfrom_mem(addr,reg,1)
        data.append(int.from_bytes(readdata,'big'))
    data16 = (data[1]<<8 | data[0])

    dataDiff = sign16(int(hex(data16),16))
    mVol = 1000 * dataDiff * conversion_factor
    var = "{:0=+12.4f}".format(mVol + zero_shift)
    print (var)

led.value(1)
RT6150_PS.value(1)
timer.init(freq=100, mode=machine.Timer.PERIODIC, callback=readdata)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?