import numpy as np
import matplotlib.pyplot as plt

# initialisation des valeurs des composants

R=1000
C=1e-7
tau=R*C

# durée du domaine de calcul et nombre de points
duree=tau*5
N=10000
dt=duree/N

# valeur de la tension l'alimentation des portes (Vdd ou Vcc...)
Vdd=10

# tableaux vides : correspondants aux notations du cours
VD=np.zeros(N)
VA=np.zeros(N)
VB=np.zeros(N)
uc=np.zeros(N)
# valeurs du temps
t=np.linspace(0,duree,N)

# conditions initiales
uc[0]=0
VA[0]=0
VB[0]=Vdd
VD[0]=Vdd

# Méthode d'Euler------------------------------------------------------------
for i in range(N-1):

    uc[i+1]=uc[i]+(VB[i]-VA[i]-uc[i])/tau*dt # évolution du uc(t), equ diff.

    VD[i+1]=VB[i]-uc[i]                      # tension qui fait basculer la
                                             # porte 1

    if VD[i+1]>=Vdd/2:  # commande le basculement de la porte 1 et donc de 2
        VA[i+1]=0
        VB[i+1]=Vdd

    else:

        VA[i+1]=Vdd
        VB[i+1]=0
#-----------------------------------------------------------------------------

# Mesure de la fréquence f ---------------------------------------------------
periode=[]           # liste vide

for i in range(N-1): # on balaie les N valeurs de VB
    if VB[i+1]>VB[i]:# si VB bascule de 0 à Vdd on enregistre le temps
        periode.append(t[i+1])

# la période mesurée est alors la durée totale entre la première bascule
# et la dernière, divisée par le nombre de bascule - 1.
# pour la fréquence on prend l'inverse et on arrondit

T=(periode[len(periode)-1]-periode[0])/(len(periode)-1)
f=round(1/T,1)
#------------------------------------------------------------------------------

# Affichage
plt.figure(figsize=(10,4))
plt.plot(t,uc,'b',label="uc(t)")
plt.plot(t,VD,'g',label="retroaction VD(t)")
plt.plot(t,VB,'r',label="VB(t) en sortie")
plt.legend()

titre="Astable à porte NAND, fréquence mesurée : "+str(f)+"Hz soit T = "+str(round(1/(f*tau),1))+" tau soit 2.tau.ln(3)"
plt.title(titre)

plt.xlabel("t en s")
plt.ylabel("VB")
plt.grid()

plt.show()



