From 952c47bf02daa80ffdb04369dc2ef2e1724376ec Mon Sep 17 00:00:00 2001 From: lilian Date: Sun, 6 Jun 2021 14:37:19 +0200 Subject: [PATCH 1/6] =?UTF-8?q?lecture=20float=20arduino=20et=20flushInput?= =?UTF-8?q?=20du=20serial=20Arduino=20avant=20boucle=20reception=20donn?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/data.py | 4 ++-- main.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bin/data.py b/bin/data.py index 328bb9c..95e029d 100644 --- a/bin/data.py +++ b/bin/data.py @@ -127,7 +127,7 @@ class Arduino_data(): if(coma_places == -1 and len(raw_data_txt) < 2): print("Donnees non transmises par l'Arduino.") elif(coma_places == -1 and len(raw_data_txt) > 2): - raw_data_temp[0,0] = int(raw_data_txt) + raw_data_temp[0,0] = float(raw_data_txt) if(len(coma_places) != self.nb_captor_signals-1): if(len(coma_places) < self.nb_captor_signals-1): print("Il y a moins de donnees transmises que de capteurs. Vérifiez les donnees transmises.") @@ -138,7 +138,7 @@ class Arduino_data(): coma_places.insert(0,-1) coma_places.append(len(raw_data_txt)) for i in range(min(len(coma_places)-1, self.nb_captor_signals)): - self.raw_data_temp[0,i] = int(raw_data_txt[coma_places[i]+1:coma_places[i+1]]) + self.raw_data_temp[0,i] = float(raw_data_txt[coma_places[i]+1:coma_places[i+1]]) self.data_array = np.append(self.data_array, self.raw_data_temp, axis=0) def create_data_file(self): diff --git a/main.py b/main.py index 7abe064..e9d7351 100755 --- a/main.py +++ b/main.py @@ -12,6 +12,10 @@ parameters_path = os.path.abspath(os.path.dirname(__file__)) + "/parameters.txt" data_nb = 10 captors_path = os.path.abspath(os.path.dirname(__file__)) + "/captors.txt" serial_path = fc.read_line_file(parameters_path) +#si '\n' a l'interieur du lien, peut ne pas fonctionner, donc a enlever +bad_path_enter_place = serial_path.find("\n") +if(bad_path_enter_place > 0): + serial_path = serial_path[0:bad_path_enter_place]+serial_path[bad_path_enter_place+2:] #Variables cachees @@ -72,6 +76,7 @@ while(flag_state > 0): figures.create_figure(titles_list) data_buff_nb = 0 arduino_data.create_data_file() + arduino_ser.flushInput() time_0 = time.time()-1 while(flag_state == 2): #boucle de reception des donnees time_0 = time_0+1 @@ -90,6 +95,7 @@ while(flag_state > 0): data_buff_nb +=1 data_buff = data_buff + str(raw_data_txt)[2:-5] + "\n" #add 1 data line in buffer #procedure extraction donnees pour affichage + #print(str(raw_data_txt)[2:-5], "azerty") arduino_data.extract_data_to_array(str(raw_data_txt)[2:-5]) From c3ac1f6b7dbf04661725d6d155d5b006a5b0da38 Mon Sep 17 00:00:00 2001 From: lilian Date: Tue, 8 Jun 2021 11:12:25 +0200 Subject: [PATCH 2/6] remplacement du module getch par readchar --- bin/functions.py | 4 ++-- main.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/functions.py b/bin/functions.py index a510a0d..d5e8e33 100644 --- a/bin/functions.py +++ b/bin/functions.py @@ -1,7 +1,7 @@ import os from multiprocessing import Process, Queue if(os.name == "posix"): - import getch as gt #clavier linux + import readchar as gt #clavier linux else: import msvcrt as gt #clavier linux; à tester! @@ -23,7 +23,7 @@ def press_key(caracters, numbers, actual, queue = None): état (actual) à l'un de ceux contenus dans numbers, et déclenchés par leur caractère correspondant.""" - pressed_key = gt.getch() #detection de touche pressee (blocant) + pressed_key = gt.readchar() #detection de touche pressee (blocant) place = caracters.find(pressed_key) if(queue != None): #si dans un thread (press_key_timeout) if(place == -1): diff --git a/main.py b/main.py index e9d7351..5df92d7 100755 --- a/main.py +++ b/main.py @@ -77,6 +77,7 @@ while(flag_state > 0): data_buff_nb = 0 arduino_data.create_data_file() arduino_ser.flushInput() + print("Enregistrement en cours. Arrêtez avec MAJ + P.\n") time_0 = time.time()-1 while(flag_state == 2): #boucle de reception des donnees time_0 = time_0+1 From 6c10b3f1d8ae5c4b51bb2473aab9f8aade92bd07 Mon Sep 17 00:00:00 2001 From: lilian Date: Tue, 8 Jun 2021 15:00:04 +0200 Subject: [PATCH 3/6] =?UTF-8?q?bug=20corrig=C3=A9=20pour=20un=20nombre=20d?= =?UTF-8?q?e=20capteurs=20>2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/data.py | 4 ++-- bin/functions.py | 22 ++++++++++++++++++++-- main.py | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/bin/data.py b/bin/data.py index 95e029d..a321608 100644 --- a/bin/data.py +++ b/bin/data.py @@ -52,7 +52,7 @@ class Arduino_data(): coma = "," capt.captor_name = str(input("Nom du capteur : ")) - while(capt.captor_name.find(coma) != -1): + while(capt.captor_name.find_all(coma) != -1): capt.captor_name = str(input("Nom du capteur ("," non accepté): ")) capt.unit = str(input("Unité : ")) while(capt.unit.find(coma) != -1): @@ -121,7 +121,7 @@ class Arduino_data(): """Lecture d'une ligne envoyée par Arduino, et parsing des données par rapport aux virgules dans un tableau""" coma = "," - coma_places = raw_data_txt.find(coma) + coma_places = fc.find_all(raw_data_txt, coma) if(type(coma_places) == type(int())): coma_places = [coma_places] if(coma_places == -1 and len(raw_data_txt) < 2): diff --git a/bin/functions.py b/bin/functions.py index d5e8e33..95d4652 100644 --- a/bin/functions.py +++ b/bin/functions.py @@ -1,7 +1,7 @@ import os from multiprocessing import Process, Queue if(os.name == "posix"): - import readchar as gt #clavier linux + import getch as gt #clavier linux else: import msvcrt as gt #clavier linux; à tester! @@ -23,7 +23,7 @@ def press_key(caracters, numbers, actual, queue = None): état (actual) à l'un de ceux contenus dans numbers, et déclenchés par leur caractère correspondant.""" - pressed_key = gt.readchar() #detection de touche pressee (blocant) + pressed_key = gt.getch() #detection de touche pressee (blocant) place = caracters.find(pressed_key) if(queue != None): #si dans un thread (press_key_timeout) if(place == -1): @@ -53,3 +53,21 @@ def read_line_file(path): line = file.readline() #lis la 1e ligne file.close() #fermer avant de renvoyer la valeur return line + +def find_all(string, substring): + + """ Méthode find mais retourne toutes les places au lieu d'une seule.""" + + if(string.count(substring) == 0): + return -1 + else: + if(string.count(substring) == 1): + return string.find(substring) + else: + result = [string.find(substring)] + for i in range(string.count(substring)-1): + string = string[result[-1]+1:] + string.find(substring) + temp = string.find(substring) + result[-1]+1 + result.append(temp) + return result diff --git a/main.py b/main.py index 5df92d7..a7da31f 100755 --- a/main.py +++ b/main.py @@ -96,7 +96,7 @@ while(flag_state > 0): data_buff_nb +=1 data_buff = data_buff + str(raw_data_txt)[2:-5] + "\n" #add 1 data line in buffer #procedure extraction donnees pour affichage - #print(str(raw_data_txt)[2:-5], "azerty") + #print(str(raw_data_txt), "azerty") arduino_data.extract_data_to_array(str(raw_data_txt)[2:-5]) From 0050c9fc5a57d8ced92eb04f85138b1868d8c3e6 Mon Sep 17 00:00:00 2001 From: lilian Date: Mon, 5 Jul 2021 22:24:52 +0200 Subject: [PATCH 4/6] =?UTF-8?q?correction=20erreurs=20dans=20l'affichage?= =?UTF-8?q?=20des=20donn=C3=A9es=20et=20ajout=20attente=20d'initialisation?= =?UTF-8?q?=20de=20l'Arduino.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/data.py | 2 +- bin/figures.py | 8 +++--- bin/functions.py | 8 +++--- main.py | 64 ++++++++++++++++++++++++++++++++---------------- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/bin/data.py b/bin/data.py index a321608..84ff83a 100644 --- a/bin/data.py +++ b/bin/data.py @@ -52,7 +52,7 @@ class Arduino_data(): coma = "," capt.captor_name = str(input("Nom du capteur : ")) - while(capt.captor_name.find_all(coma) != -1): + while(capt.captor_name.find(coma) != -1): capt.captor_name = str(input("Nom du capteur ("," non accepté): ")) capt.unit = str(input("Unité : ")) while(capt.unit.find(coma) != -1): diff --git a/bin/figures.py b/bin/figures.py index d5db599..6625c7f 100644 --- a/bin/figures.py +++ b/bin/figures.py @@ -55,7 +55,7 @@ class Figures(): if(nb_plots > 6): for i in range(6,nb_plots): # parcours des cases de la figure de droite à gauche puis de haut en bas, suivant la grille - self.repartition.append(self.repartition[i%self.nb_curves]) + self.repartition.append(self.repartition[((i+1)%6)-1]) def create_figure(self, titles_list): """Creation de la fenêtre contenant les plots. @@ -64,8 +64,8 @@ class Figures(): actualiser les données.""" plt.ion() self.fig, self.axes = plt.subplots(self.plots_grid[0], self.plots_grid[1]) - if(self.plots_grid[0] < 2): # si 1 seule ligne, empaqueter dans une liste pour - # y acceder de la meme facon dans tous les cas + if(self.plots_grid[0] < 2): # si 1 seule ligne de figures, empaqueter dans une + # liste pour y acceder de la meme facon dans tous les cas self.axes = [self.axes] for j in range(self.plots_grid[0]): for i in range(self.plots_grid[1]): @@ -83,7 +83,7 @@ class Figures(): self.axes[i//100-1][(i//10)%10-1].clear() self.axes[i//100-1][(i//10)%10-1].title.set_text(self.titles[(i//100-1)*self.plots_grid[1]+(i//10)%10-1]) for i in range(self.nb_curves): - self.axes[self.repartition[i]//100-1][(self.repartition[i]//10)%10-1].scatter(self.time, data_array_t[i]) + self.axes[self.repartition[i]//100-1][(self.repartition[i]//10)%10-1].scatter(self.time, data_array_t[i], marker = '.') plt.show() plt.pause(0.05) diff --git a/bin/functions.py b/bin/functions.py index 95d4652..c69191f 100644 --- a/bin/functions.py +++ b/bin/functions.py @@ -56,7 +56,7 @@ def read_line_file(path): def find_all(string, substring): - """ Méthode find mais retourne toutes les places au lieu d'une seule.""" + """ Méthode find mais retourne toutes les occurences au lieu d'une seule.""" if(string.count(substring) == 0): return -1 @@ -66,8 +66,8 @@ def find_all(string, substring): else: result = [string.find(substring)] for i in range(string.count(substring)-1): - string = string[result[-1]+1:] - string.find(substring) - temp = string.find(substring) + result[-1]+1 + temp_string = string[result[-1]+1:] + temp_string.find(substring) + temp = temp_string.find(substring) + result[-1]+1 result.append(temp) return result diff --git a/main.py b/main.py index a7da31f..2b2883e 100755 --- a/main.py +++ b/main.py @@ -24,7 +24,20 @@ data_buff_max = 10 data_buff_nb = 0 data_buff = "" pressed_key = '' -flag_state = 1 # etat neutre + +flag_erreur_serial = -1 +flag_afficher_menu = 1 +flag_enregistrer = 2 +flag_afficher_ss_menu = 3 +flag_choix_menu_principal = 4 +flag_choix_ss_menu = 5 +flag_init_arduino = 6 + +flag_state = 6 # etat initialisation, puis etat neutre (1) + + + + #Programme principal @@ -35,40 +48,49 @@ try: arduino_ser = serial.Serial(serial_path, 9600) #communication avec Arduino except serial.serialutil.SerialException: print("SerialException : la carte Arduino n'est pas connectee ou est connectee sur au autre port (actuel : "+ serial_path+").") - flag_state = -1 + flag_state = flag_erreur_serial exit() else: arduino_data = data.Arduino_data() arduino_data.add_captors_from_file(captors_path) - print("PoDoCor est pret a enregistrer les donnees") + print("\nPoDoCor a initialisé la communication avec l'Arduino.") while(flag_state > 0): - if(flag_state == 1): #afficher le menu + if(flag_state == flag_init_arduino): #initialisation de l'arduino + print("\nInitialisation des capteurs Arduino, veuillez patienter.") + arduino_ser.flushInput() + arduino_ser.write(bytes('0','utf-8')) + time.sleep(5) + test = arduino_ser.readline() + print("Initialisation terminée, enregistrement possible.") + flag_state = flag_afficher_menu + arduino_ser.flushInput() + if(flag_state == flag_afficher_menu): #afficher le menu print("_________________________________\n\nMAJ + P : Enregistrement des donnees\nMAJ + N : Gerer les capteurs\nMAJ + X : Arrêt du programme (ne fonctionne pas pendant l'enregistrement)\n_________________________________\n") - flag_state = 4 time.sleep(2) # attente de la bonne communication avec Arduino - elif(flag_state == 4): # appui clavier pour les choix du menu principal - flag_state = fc.press_key('XPN', [0, 2, 3], flag_state) #detection de touche pressee (demarrage procedure acquisition) + flag_state = flag_choix_menu_principal + elif(flag_state == flag_choix_menu_principal): # appui clavier pour les choix du menu principal + flag_state = fc.press_key('XPN', [0, flag_enregistrer, flag_afficher_ss_menu], flag_state) #detection de touche pressee (demarrage procedure acquisition) - elif(flag_state == 3): # afficher le ss-menu capteurs + elif(flag_state == flag_afficher_ss_menu): # afficher le ss-menu capteurs print(" _________________________________\n MAJ + U : Lister les capteurs\n MAJ + A : Ajouter un capteur\n MAJ + E : Supprimer un capteur\n MAJ + T : Changer l'ordre des capteurs\n MAJ + Q : Menu principal\n _________________________________\n") - flag_state = 5 - elif(flag_state == 5): # apui clavier pour les choix du ss-enu capteurs - flag_state = fc.press_key('AETUQ', [31, 32, 33, 34, 1], flag_state) #detection de touche pressee (demarrage procedure acquisition) + flag_state = flag_choix_ss_menu + elif(flag_state == flag_choix_ss_menu): # appui clavier pour les choix du ss-enu capteurs + flag_state = fc.press_key('AETUQ', [31, 32, 33, 34, flag_afficher_menu], flag_state) #detection de touche pressee (demarrage procedure acquisition) if(flag_state == 31): arduino_data.add_captor_manually(captors_path) - flag_state = 3 + flag_state = flag_afficher_ss_menu elif(flag_state == 32): arduino_data.del_captor(captors_path) - flag_state = 3 + flag_state = flag_afficher_ss_menu elif(flag_state == 33): arduino_data.change_captors_order(captors_path) - flag_state = 3 + flag_state = flag_afficher_ss_menu elif(flag_state == 34): arduino_data.captors_print_list(captors_path) - flag_state = 3 + flag_state = flag_afficher_ss_menu - elif(flag_state == 2): # enregistrement des données + elif(flag_state == flag_enregistrer): # enregistrement des données titles_list = [] for i in range(arduino_data.nb_captor_signals): titles_list.append(arduino_data.captors[i].captor_name) @@ -79,7 +101,7 @@ while(flag_state > 0): arduino_ser.flushInput() print("Enregistrement en cours. Arrêtez avec MAJ + P.\n") time_0 = time.time()-1 - while(flag_state == 2): #boucle de reception des donnees + while(flag_state == flag_enregistrer): #boucle de reception des donnees time_0 = time_0+1 time_1 = time_0+0.6 arduino_ser.write(bytes('1','utf-8')) #envoi de '1' a l'Arduino (acquisition donnees) @@ -87,16 +109,15 @@ while(flag_state > 0): arduino_ser.write(bytes('2','utf-8')) #envoi de '2' (réception donnees) time.sleep(0.05) raw_data_txt = arduino_ser.readline() #format des donnees: data1,data2,data3\n - #print(str(raw_data_txt)[2:-5]) if(raw_data_txt == ''): # si aucune donnée reçue print("Arduino n'envoie aucune donnee, veuillez verifier le code televerse.") - flag_state = -1 + flag_state = flag_erreur_serial data_buff_nb = 0 else: data_buff_nb +=1 data_buff = data_buff + str(raw_data_txt)[2:-5] + "\n" #add 1 data line in buffer #procedure extraction donnees pour affichage - #print(str(raw_data_txt), "azerty") + #print(str(raw_data_txt)) arduino_data.extract_data_to_array(str(raw_data_txt)[2:-5]) @@ -108,7 +129,8 @@ while(flag_state > 0): # plot figures.plot_data(arduino_data.data_array) - flag_state = fc.press_key_timeout('P', [1], flag_state) + + flag_state = fc.press_key_timeout('P', [flag_afficher_menu], flag_state) time.sleep(max(time_0+1-time.time(), 0)) # while end From 06c91c842b15cee315d0f80fac53025225636333 Mon Sep 17 00:00:00 2001 From: Lilian RM Date: Mon, 5 Jul 2021 21:35:18 +0100 Subject: [PATCH 5/6] =?UTF-8?q?Transf=C3=A9rer=20les=20fichiers=20vers=20'?= =?UTF-8?q?'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exemple de fichier Arduino pour 5 capteurs: - 1 capteur multicanaux, I2C (4 capteurs) - 1 capteur O2, analogique - 1 capteur CO2 MH-Z19B, UART (+ température intégrée) - 1 thermocouple, lecture analogique - 1 sonde de température Onewire, numérique. --- Exemple_code_Arduino.ino | 119 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 Exemple_code_Arduino.ino diff --git a/Exemple_code_Arduino.ino b/Exemple_code_Arduino.ino new file mode 100644 index 0000000..5729c3d --- /dev/null +++ b/Exemple_code_Arduino.ino @@ -0,0 +1,119 @@ +/***************************************************************************************************************************** + Auteur : FDES et LilianRM + Pour LowTech Bordeaux + *****************************************************************************************************************************/ + +// setup des librairies et des variables globales + +#include + +#include +#include +#include +#include +#include +GAS_GMXXX gas; +#include +#include + +int MHZ19B_PREHEATING_TIME = 3 * 60; + +#define O2_WIRE A2 +#define ONE_WIRE_BUS 2 + +HighTemp ht(A1, A0); +OneWire oneWire(ONE_WIRE_BUS); +DallasTemperature dallasTemp(&oneWire); +uint8_t tempAddress[8] = {0x28,0x46,0xBF,0x31,0x08,0,0,0x1B}; + +char data_sent[100]; +char incomingInt; +String data_string; + +MHZ co2capt(4,5, MHZ19B); // RX, TX, type + +// fonctions de conversion + +int Float2Int(float number){ + return (int)number/1; +} + +int Coma2Int(float number, int nbAfterComa){ + number = number - (int)number; + if(number < 0){ + return (int)((-number)*pow(10, nbAfterComa)/1); + }else{ + return (int)(number*pow(10, nbAfterComa)/1); + } +} + + +void setup() // setup des capteurs +{ + delay(20000); + for(int i = 0;i<10;i++){ + co2capt.calibrate400ppm(); + delay(10); + } + gas.begin(Wire, 0x08); // use the hardware I2C + ht.begin(); + dallasTemp.begin(); + dallasTemp.setResolution(12); + delay(10000); + Serial.begin(9600); + delay(20); + Serial.println('0'); +} + +void loop() { + if(Serial.available() > 0){ // wait for serial to have data + incomingInt = Serial.read() - '0'; + if(incomingInt == 1){ // read data from captors and construct string + Serial.flush(); + + // GM102B NO2 sensor + int val102 = gas.getGM102B(); + // GM102B alcool? sensor + int val302 = gas.getGM302B(); + // GM502B VOC sensor + int val502 = gas.getGM502B(); + // GM702B CO sensor + int val702 = gas.getGM702B(); + + int valOxygen = analogRead(O2_WIRE); + + int gazco2ppm = co2capt.readCO2UART(); + int tempco2ppm = co2capt.getLastTemperature(); + + float thermoCpl = ht.getThmc(); + + dallasTemp.requestTemperatures(); + int onewireTemp = dallasTemp.getTemp(tempAddress); + + data_string = String(valOxygen) + "," + + String(val102) + "," + + String(val302) + "," + + String(val502) + "," + + String(val702) + "," + + String(gazco2ppm) + "," + + String(tempco2ppm) + "," + + String(Float2Int(thermoCpl)) + "." + String(Coma2Int(thermoCpl,1)) + "," + + String(Float2Int(onewireTemp)); + data_string.toCharArray(data_sent, 100); + + + }else if(incomingInt == 2){ // send data + + delay(10); + Serial.flush(); + Serial.println(data_sent); + + }else if(incomingInt == 0){ // send ready signal + Serial.flush(); + Serial.println('0'); + + }else{ + Serial.flush(); + } + } +} From f9f68239b6bc4eff0ef7eb7352574eece586027c Mon Sep 17 00:00:00 2001 From: Lilian RM Date: Mon, 5 Jul 2021 21:36:16 +0100 Subject: [PATCH 6/6] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'Exemple=5Fcode?= =?UTF-8?q?=5FArduino.ino'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Exemple_code_Arduino.ino | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Exemple_code_Arduino.ino b/Exemple_code_Arduino.ino index 5729c3d..6148849 100644 --- a/Exemple_code_Arduino.ino +++ b/Exemple_code_Arduino.ino @@ -1,6 +1,12 @@ /***************************************************************************************************************************** Auteur : FDES et LilianRM Pour LowTech Bordeaux + Exemple de fichier Arduino pour 5 capteurs: +- 1 capteur multicanaux, I2C (4 capteurs) +- 1 capteur O2, analogique +- 1 capteur CO2 MH-Z19B, UART (+ température intégrée) +- 1 thermocouple, lecture analogique +- 1 sonde de température Onewire, numérique. *****************************************************************************************************************************/ // setup des librairies et des variables globales