高校物理も出来ない僕がLPFのシミュレータを作るまでのメモ帳

# タイトルは上記

## LPF ?
RC回路にて実現したい。

基本的な電気/電子回路を勉強しきれなかったので、
オペアンプとかマジ無理


## RC回路
?
これでいいのかな？
![totalc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/207b778a-ce5c-65a7-8645-345a8ec88a7c.png)

## 前提知識
コンデンサの過渡現象すらよくわからない
知っているのは
E=RI

# コンデンサの過渡現象について
コンデンサ：単位は F (ファラド:farad)

```math
F = \frac{Q}{V} = \frac{電荷}{電圧}
```

電荷 : 単位は C (クーロン:coulomb)

```math
Q = A・s = 電流・時間
```

時刻tにおけるコンデンサの電荷量をQ(t)とすると、

```math
Q(t) = \int_{0}^{t} I(t) dt
```
とか書けそう。つまり、
電流と電荷量の関係は

```math
I(t) = \frac{dQ(t)}{dt} [A]
```
と表されるらしい。
電流は直列回路では一定であるため、
抵抗での電圧降下 Vr は

```math
V_r(t) = RI(t) = R\frac{dQ(t)}{dt} [V]
```
となる ( V = RI )。

コンデンサにおける電圧降下は

```math
E-V_r(t) = \frac{Q(t)}{C}
```
ここで

```math
Q(t) : [c]\\
C : [\frac{c}{v}]
```
なので単位的にVになる。

したがって、
キルヒホッフの法則から回路方程式は

```math
E = R\frac{dQ(t)}{dt} + \frac{Q(t)}{C}
```
となる（らしい）。

## 解をもとめる
ではこの回路方程式を説いてみる。

```math
E = R\frac{dQ(t)}{dt} + \frac{Q(t)}{C}
```
は、変数分離型の一回線形微分方程式らしい。
（講義でやったようなやってないような）

で解は、

```math
Q(t) = CE(1-e^{-\frac{1}{RC}t})\\
I(t) = \frac{dQ(t)}{dt} = \frac{E}{R}e^{-\frac{1}{RC}t}
```
となるようです。
したがって、抵抗での電圧降下は

```math
V_r = RI(t) = Ee^{-\frac{1}{RC}t}
```
であり、コンデンサ電圧は

```math
V_c = E- V_r
```
となります。

※公式があるようです。

```math
V_c = V・(1-e^{-\frac{1}{RC}t})
```
V : 印加電圧

## RC過渡現象シミュレータコード
ということで、ここまでをコーディングしてみます。

```main.go
package main

import (
	"fmt"
	"math"
	"os"
	"strconv"
)

func main() {
	if len(os.Args) < 4 {
		fmt.Println("ARG ERR E C R")
		return
	}

	e, _ := strconv.ParseFloat(os.Args[1], 64)
	c, _ := strconv.ParseFloat(os.Args[2], 64)
	r, _ := strconv.ParseFloat(os.Args[3], 64)
	fmt.Println("#e :", e)
	fmt.Println("#c :", c)
	fmt.Println("#r :", r)

	for i := 0; i < 10; i++ {
		//fmt.Println(qt(3.0, 0.000001, 10.0, float64(i) * 0.001))
		//fmt.Println(it(3.0, 0.00001, 1.0, float64(i) * 0.0001))
		fmt.Println(float64(i) * 0.1, vc(e, c, r, float64(i) * 0.0001))
	}
}

func qt (e, c, r, t float64) float64 {
	return c * e * (1.0 - math.Exp(-t / (r * c)))
}

func it (e, c, r, t float64) float64 {
	return e * math.Exp(-t / (r * c)) / r
}

func vc (e, c, r, t float64) float64 {
	return e - r * it(e, c, r, t)
}
```
コードはこんな感じ。難しさのかけらもない。

```plot.txt
set terminal png size 800, 600
set out "res.png"
set title "E=3V C=1uF"

set xlabel 'time [ms]'
set ylabel 'Vc [V]'
set yrange [0:3.5]
set grid 

plot "plot1" smooth sbezier title "1ohm" linewidth 2 lc rgb "#ff0000", \
	"plot10" smooth sbezier title "10ohm" linewidth 2 lc rgb "#00ff00", \
	"plot100" smooth sbezier title "100ohm" linewidth 2 lc rgb "#0000ff", \
	"plot1000" smooth sbezier title "1kohm" linewidth 2 lc rgb "#808000", \
	"plot10000" smooth sbezier title "10kohm" linewidth 2 lc rgb "#800080", \
```
gnuplot用ファイルはこんな感じ。

```Makefile
default	:
	go build main.go
	./main 3 0.000001 1 > plot1
	./main 3 0.000001 10 > plot10
	./main 3 0.000001 100 > plot100
	./main 3 0.000001 1000 > plot1000
	./main 3 0.000001 10000 > plot10000
	gnuplot plot.txt
	eog res.png
```
Makefile はこんな感じ。

## プロット結果
![res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/736e9c6e-4468-dd79-a051-0b35a7703da5.png)
 
# 放電時過渡計算
放電時、下記の公式が示される（らしい）。

```math
V_c = V・e^{-\frac{1}{RC}t}
```
なお、Vはコンデンサの初期電圧である。

## コード

```main.go
package main

import (
	"fmt"
	"math"
	"os"
	"strconv"
)

func main() {
	if len(os.Args) < 4 {
		fmt.Println("ARG ERR E C R")
		return
	}

	e, _ := strconv.ParseFloat(os.Args[1], 64)
	c, _ := strconv.ParseFloat(os.Args[2], 64)
	r, _ := strconv.ParseFloat(os.Args[3], 64)
	fmt.Println("#e :", e)
	fmt.Println("#c :", c)
	fmt.Println("#r :", r)

	for i := 0; i < 10; i++ {
		fmt.Println(float64(i) * 0.1, vc(e, c, r, float64(i) * 0.0001))
	}
}

func vc (v, c, r, t float64) float64 {
	return v * math.Exp(-t / (r * c))
}
```
ほとんど変わっていない。
## プロット結果
![res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/3f5bc67e-091a-a0c8-1f0c-3d412f3d96e0.png)