Calculating charging/discharging curves of a RC circuit by integration

I'm trying to calculate the charging and discharging of a RC circuit by integrating a differential equation. Here is my code:

import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import Cursor from scipy.integrate import odeint def equa_diff(E, tab_t, tau, t): return E/(R*C) fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, facecolor="#FFFFCC") cursor = Cursor(ax, useblit=True, color='blue', linewidth=1) #Les paramètres physiques E = 5 R = 1000.0 C = 1e-6 tau = R * C u0 = 0 cond_init = [0, E / R] #Les paramètres numériques t_min = 0.0 t_max = 10e-3 n_t = 100 tab_t = np.linspace(t_min, t_max, n_t) tab_t1 = tab_t + 0.01 tab_u = odeint(equa_diff, u0, tab_t, args=(tau, E)) tab_u1 = odeint(equa_diff, E, tab_t1, args=(tau, 0)) u_max = max(tab_u) #La charge du condensateur ax.plot(tab_t, tab_u, 'r', label='uc(t)') ax.plot(tab_t, np.ones(100) * E, 'black', label='e(t)') ax.plot(tab_t, tab_t / tau, 'b', label="tangente à l'origine") ax.plot(tab_t, -tab_u + E, 'green', label='ur(t)') #La décharge du condensateur ax.plot(tab_t1, tab_u1, 'r') ax.plot(tab_t1, np.zeros(100), 'black') ax.plot(tab_t1, -tab_u1 + E, 'green') plt.xlabel('t') plt.ylabel('u') plt.title('Circuit en série RC') plt.ylim(0, u_max * 1.2) plt.legend(loc=4) plt.show() 

I would like to have this: I would like to have this But I have this: But I have this I've tried my best, but I couldn't manage to correct it.

2,133 2 2 gold badges 22 22 silver badges 29 29 bronze badges asked Dec 27, 2020 at 20:49 11 3 3 bronze badges In other words, you have no difficulty in drawing the curves, but in calculating the correct values. Commented Dec 27, 2020 at 20:56

Yes, I have some problems with this chapter. I have some issues finding the correct differential equation. I don't even know where I am wrong.

Commented Dec 27, 2020 at 21:00

If you need some help with the equations, this PDF (page 6 in particular) has the math to solve the differential equations and then you can manually program those functions instead. If you still need any help, please let me know!

Commented Dec 28, 2020 at 0:14

Hello and thanks for your answer ! But I am supposed to solve my differential equation with the function "odeint", and I really don't understand how it works. Here is my equation : dUc/dt + Uc/RC = E/RC. Thanks for your help

Commented Dec 28, 2020 at 18:56

1 Answer 1

You must take into account that charging and discharging are described by

dUc/dt + Uc/RC = E/RC => dUc / dt = 1/RC * ( E - Uc) 
dUc/dt + Uc/RC = 0 => dUc / dt = -Uc/RC 

Your function is missing the -Uc/RC , you can keep it as one function in python if you wish, but I split it into a charging and discharging form out of personal preference. I also had to modify your tangent line at t=0 for the charging process, as it wasn't giving me the correct slope.

import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import Cursor from scipy.integrate import odeint #Les paramètres physiques E = 5 R = 1000.0 C = 1e-6 tau = R * C u0 = 0 def RC_Circuit_Charging(u, t): return (E - u )/(R*C) def RC_Circuit_Discharging(u, t): return -u/(R*C) fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, facecolor="#FFFFCC") cursor = Cursor(ax, useblit=True, color='blue', linewidth=1) #Les paramètres numériques t_min = 0.0 t_max = 10e-3 n_t = 100 tab_t = np.linspace(t_min, t_max, n_t) tab_t1 = tab_t + 0.01 tab_u = odeint(RC_Circuit_Charging, u0, tab_t) tab_u1 = odeint(RC_Circuit_Discharging, E, tab_t1) u_max = max(tab_u) #La charge du condensateur ax.plot(tab_t, tab_u, 'r', label='uc(t)') ax.plot(tab_t, np.ones(100) * E, 'black', label='e(t)') ax.plot(tab_t, E * tab_t / tau, 'b', label="tangente à l'origine") # tangent line du/dt at t = 0 so E - u(0) / RC = E / RC ax.plot(tab_t, -tab_u + E, 'green', label='ur(t)') #La décharge du condensateur ax.plot(tab_t1, tab_u1, 'r') ax.plot(tab_t1, np.zeros(100), 'black') ax.plot(tab_t1, -tab_u1 + E, 'green') plt.xlabel('t') plt.ylabel('u') plt.title('Circuit en série RC') plt.ylim(0, u_max * 1.2) plt.legend(loc=4) plt.show()