import matplotlib.pyplot as plt
import time
from tkinter import *
import pickle
from serial import *

def reponse():
    return int(eval(str(portSerie.readline()).replace(';',''))) #lecture de la réponse

def lancerMesure():
    global valIvert,valUvert,valTemps,valUalim,timeStart,x0,y0
    print ("lancement de la mesure")
    valIvert[:] = [] # vide la liste pour nouvelle mesure
    valUvert[:] = [] # vide la liste
    valTemps[:] = [] # vide la liste
    valUalim[:] = [] # vide la liste
    timeStart = time.time()   # mesure de l'instant initial (t=0)
    x0=0 #abcisse du graphe du canevas
    y0=300 #point de départ du graphe
    Canevas.delete(ALL) #effacement du graphe (pour nouvelle mesure)
    portSerie.write(b'P06200#') # demarrage axe vertical
    mesurer() #lance la mesure

def mesurer():
    global timer,valIvert,valUvert,valUalim,valTemps,timeStart,x0,x1,y0,y1
    #mesure de la tension d'alimentation sur A6
    portSerie.write(b'A06#F#') 
    Ualim = 3.3 * (reponse()*(5/1023)) #conversion en volt
    # de la tension du moteur vertical sur A3
    portSerie.write(b'A03#F#') 
    tension= 13 - 3.3 * reponse() * (5/1023) #conversion en volt
    # mesure du courant du moteur vertical sur A4
    portSerie.write(b'A04#F#') 
    courant=((reponse() *(5/1023))-2.5)/0.185 #conversion en Ampère
    #ajout des mesures aux listes des mesures
    valUalim.append(Ualim)
    valIvert.append(courant)
    valUvert.append(tension)
    #lste des temps (abcisse)
    Tmesure=time.time()-timeStart  #calcul du temps ecoule depuis l'instant initial
    valTemps.append(Tmesure)       # ajout de l'instant T a la liste des valeurs
    #dessin du graphe en direct
    x1 = x0+1 # on passe au point suivant en abscisse
    y1 = 300-(valIvert[len(valIvert)-1])*20 #ordonnée (départ :0,300 echelle y 20)
    Canevas.create_line(x0, y0, x1, y1, width=2, fill='red') # dessin d'une ligne entre deux points
    x0=x1 #le point de d'arrivée devient le prochain point de départ
    y0=y1 #le point de d'arrivée devient le prochain point de départ
    timer = fenetre.after(1, mesurer) #le timer relance la mesure jusqu'à STOP

def stop():
    global timer
    if timer: # arret du timer, fin des mesures
        fenetre.after_cancel(timer)
        timer = None
    portSerie.write(b'P06000#') # Arrêt du moteur
    print ("Fin des mesures")

def graphe():
    global valIvert,valUvert,valUalim,valTemps
    fig = plt.figure(1, figsize=(10, 5)) # taille de la fenetre
    plt.ylabel("Valeurs")   #nom de l'axe des ordonnées
    plt.xlabel("Tempts en seconde") #nom de l'axe des abcisses
    plt.grid(True) #affichage de la grille
    plt.title("Courbes de courant et tension") #titre de la fenetre
    plt.plot(valTemps,valUalim,"y",linewidth=0.8, label='U alim')  # mise en place du label
    plt.plot(valTemps,valIvert,"r",linewidth=0.8, label='I moteur')  # mise en place du label
    plt.plot(valTemps,valUvert,"b",linewidth=0.8, label='U moteur')  # trace la courbe rouge largeur 0.8
    plt.legend(loc="upper left")
    plt.show()


def enregistrer():
    global nomFichier,valIvert,valUvert,valUalim,valTemps
    print ("enregistrement des mesures")
    # création d'une liste de listes de mesures
    dataMesures = [valIvert,valUvert,valTemps]
    fichier = open(nomFichier,'wb')
    # enregistrement de la liste
    pickle.dump(dataMesures,fichier)    
    fichier.close()

def lireFichier():
    global nomFichier,valIvert,valUvert,valUalim,valTemps
    print ("lecture du fichier des mesures")
    # lecture de la liste du fichier
    dataMesures = pickle.load(open(nomFichier, 'rb'))
    #extraction des listes de mesures
    valIvert = dataMesures[0]
    valUvert = dataMesures[1]
    valTemps = dataMesures[2]




def indiceFichier():
    global nomFichier
    # modification de l'indice du nom de fichier
    nomFichier = 'dataMesures' + str(int(indice.get()))
    texte.set(nomFichier)

#Debut du programme principal
#============================
portSerie = Serial(port="COM13",baudrate=115200)
time.sleep(2)
portSerie.write(b'H10#') #relais mode piloté


#tables des valeurs à  tracer
#===========================
valIvert=[]  #table des grandeurs à mesurer (I vertical)
valUvert=[]  #(U vertical)
valUalim=[]  #(U alim)
valTemps=[]  #table du temps (abcisses)
nomFichier = 'dataMesures0' # nom par défaut


# Création de la fenÃªtre principale
fenetre = Tk()

fenetre.title('Mesures')
fenetre.geometry('700x400+400+400')

Canevas = Canvas(fenetre, width = 500, height =300, bg ='white')
Canevas.pack(padx =5, pady =10)

# Création et positionnement d'un bouton MESURER
BoutonMesurer = Button(fenetre, text ='Mesurer', command = lancerMesure)
BoutonMesurer.pack(side = LEFT, padx = 5, pady = 5)

# Création d'un bouton STOP
BoutonStop = Button(fenetre, text ='STOP', command = stop)
BoutonStop.pack(side = LEFT, padx = 5, pady = 5)

# Création d'un bouton ENREGISTRER
BoutonEnregistrer = Button(fenetre, text ='Enregistrer', command = enregistrer)
BoutonEnregistrer.pack(side = LEFT, padx = 5, pady = 5)

# Création d'un bouton LIRE FICHIER
BoutonlireFichier = Button(fenetre, text ='Lire Fichier', command = lireFichier)
BoutonlireFichier.pack(side = LEFT, padx = 5, pady = 5)

# Création d'un bouton GRAPHE
BoutonGraphe = Button(fenetre, text ='Graphe', command = graphe)
BoutonGraphe.pack(side = LEFT, padx = 5, pady = 5)

# Création d'un bouton QUITTER
BoutonQuitter = Button(fenetre, text ='Quitter', command = fenetre.destroy)
BoutonQuitter.pack(side = LEFT, padx = 5, pady = 5)

# Création d'un widget Label pour le nom de fichier
texte = StringVar()
LabelFichier = Label(fenetre, textvariable = texte, fg ='red', bg ='white')
LabelFichier.pack(side = LEFT, padx = 5, pady = 5)
texte.set(nomFichier)

# Création d'un widget Spinbox pour changer l'indice du nom de fichier
indice = StringVar()
boite = Spinbox(fenetre,from_=0,to=99,increment=1,textvariable=indice,width=5,command=indiceFichier)
boite.pack(side = LEFT, padx = 5, pady = 5)

# boucle de la fenètre graphique
fenetre.mainloop()