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

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

製作編は下記を参照
[ゲインアンプ付きA/Dコンバータ(SX8725C)を用いた簡易地震計の製作 1（製作編）](https://qiita.com/pirotan628/items/9ca181ee34e998c7dd24)

![DSC_3648.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/316ec2b7-0f99-56cd-05bf-06fb29d160d8.jpeg)

# スパイクノイズ問題

製作編では良く分からずPGA3をガンガン持ち上げていたところ、スパイクノイズに悩まされた (縦軸：[mV], 横軸：10 [msec])。地震計未接続の状態でも乗ってくる。
![スクリーンショット 2022-11-10 9.32.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/3bcc9413-656b-cc80-9b5b-f59d9cf979fd.png)

RaspberrryPi Pico の電源ノイズについて色々調べて試したのは２つ。
- RT6150BをスリープにしてLDOでPicoに3.3Vを給電してみた。
- SX8725CとPicoの物理的距離を変えた 

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

次に、SX8725Cの内部でなんとかできないか考えた。SX8725Cのデータシートを見るとPGA2とPGA3は基準電圧の影響を受けそうだが、前段のPGA1は独立していそうだ。
![スクリーンショット 2022-11-11 9.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/d194eea9-e14f-fc6a-68c6-652554f2ee46.png)

色々試したところ、PGA2もしくはPGA3で倍率を上げると問題のスパイクが乗ることが分かった。一方でPGA1のみだと現れない事が分かり、PGA2以降の段は1倍で使う事にした（Disableにはしていない）。地震計未接続の状態。
![スクリーンショット 2022-11-11 8.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/7795270c-1633-986a-f2a6-964728b6c8d9.png)

地震計を接続した状態。1Hzの発振っぽいノイズはPC関連機器から遠ざけると弱まった。
![スクリーンショット 2022-11-11 9.00.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/8713d80b-e6f9-d3a0-90a3-a676897bccf5.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/38b6f959-122d-f917-0f66-c1c838c8550e.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)

```