Bonsoir,
Je suis plutôt débutant en arduino et je me suis lancé dans la conception d'un cadence mètre muni d'un gps (et si possible d'un capteur cardiaque).
J'avais un code d'une quatre-centaine de ligne mais je ne m'y retrouvais plus du tout, j'ai donc essayé (en vain puisque que ça ne compile pas) de créer des fichiers .h et .cpp. J'ai eu beaucoup de mal à trouver des exemples sur internet c'est pourquoi je sollicite votre aide
Je voulais également savoir si si je déclare une variable globale ( je sais ce n'est pas bien ... mais je ne trouve pas d'alternatives) "distance" qui s'ajouterait à la "distance" précédente, elle est accessible dans tous mes .cpp? (et aussi "cadence" et "heart")
prend bien "choix" comme paramètre? C'est à dire qui je pourrais agir en fonction de "choix" dans Run()?Code:void Run(int choix)
Après cela concerne plus les interruptions? (le programme contient un bon bout du code adafruit d'où les commentaires en aglais ...)
-Est-ce qu'il vaut mieux que j'appelle le gps avec "usingInterrupt" ou dans le loop par rapport à mon programme?
-Est-ce que je peux faire une interruption pour ma fonction "Affich()" ou ma méthode actuelle convient?
-J'appelle régulièrement la fonction dans "pagaie.cpp" qui reçoit un message par un recepteur 433MHz mais je bloque le programme par100 millisecondes, je pense que c'est problématique mais là aussi je ne sais pas quoi faire... (Interruption sur une broche?)Code:vw_wait_rx_max(100);
Désolé pour ce bloc de question d'un coup mais tous ces problèmes arrivent en même temps (et je n'ai pas encore vu les problèmes qui surviendront après la compilation)
.ino
GPS.cpp il me reste à compléter la fonction distance)Code:#include <SPI.h> #include "affich.h"; #include "GPS.h" #include "log.h" #include "pagaie.h" #include "run.h" SoftwareSerial mySerial(3, 2); //port serie virtuel (TX=3, RX=2) //HardwareSerial mySerial = Serial1; //port serie sur mega Adafruit_GPS GPS(&mySerial); #define GPSECHO true boolean usingInterrupt = false; void useInterrupt(boolean); //broches de l'écran cs et dc #define TFT_CS 10 #define TFT_DC 9 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); //rotation ecran #define SCREENROTATION 3 //boutons #define boutonOk 13 #define boutonNext 12 unsigned long previousMillis; void setup() { Serial.begin(115200); //mise en place de la liaison serie arduino/ordinateur //RX vw_setup(2000); // Bits par seconde vw_rx_start(); vw_set_rx_pin(RECEIVE_PIN); GPS.begin(9600); //mise en place de la liaison serie arduino/gps GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //trames RMC et GGA seulement GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); //Fraquence de rafraichissement GPS.sendCommand(PGCMD_ANTENNA); //utilisation d'une antenne externe useInterrupt(true); //gps utilise les interruptions delay(100); mySerial.println(PMTK_Q_RELEASE); //ecran tft.begin(); tft.fillScreen(BACKGROUNDCOLOR); //remplissage de l'ecran avec la couleur par defaut tft.setRotation(SCREENROTATION); //inclinaison del'ecran tft.setTextSize(3); //CS pinMode(CSSREEN, OUTPUT); //cs pour l'ecran pinMode(CSSD, OUTPUT); //cs pour la sd //boutons pinMode(boutonOk,INPUT); //initialisation des boutons pinMode(boutonNext,INPUT); digitalWrite(boutonOk, HIGH); digitalWrite(boutonNext, HIGH); } //Interrupt est appelé toutes les millisec, verifie si des nouvelles trames sont recues et les stocke SIGNAL(TIMER0_COMPA_vect) { char c = GPS.read(); #ifdef UDR0 if (GPSECHO) if (c) UDR0 = c; // UDRO = Serial.print en plus rapide mais caractere par caractere #endif } void useInterrupt(boolean v) { if (v) { // Timer0 is already used for millis() - we'll just interrupt somewhere // in the middle and call the "Compare A" function above OCR0A = 0xAF; //timer pour l'interruption TIMSK0 |= _BV(OCIE0A); usingInterrupt = true; } else { // ne plus rappeler la fonction COMPA TIMSK0 &= ~_BV(OCIE0A); usingInterrupt = false; } } uint32_t timer = millis(); //timer utilisé par le GPS void loop(){ // au cas où usingInterrupt == false, appel manuel de la fonction if (! usingInterrupt) { //lecture des donnees du gps char c = GPS.read(); if (GPSECHO) // if (c) Serial.print(c); // if a sentence is received, we can check the checksum, parse it... if (GPS.newNMEAreceived()) { // a tricky thing here is if we print the NMEA sentence, or data // we end up not listening and catching other sentences! // so be very wary if using OUTPUT_ALLDATA and trytng to print out data //Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false return; // we can fail to parse a sentence in which case we should just wait for another } } // ouvre le menu choix si un appui est detecté if(digitalRead(boutonOk)==LOW) Choix(); if((millis()-previousMillis)>=200||(millis()-previousMillis)>=400||(millis()-previousMillis)>=600||(millis()-previousMillis)>=800) { LogSd(); //5 fois par seconde if((millis()-previousMillis)>=1000) { //Une fois toutes les secondes previousMillis=millis(); LogSd(); //enregistrement des données sur la sd Affich(); //affichage des données sur l'ecran } }
GPS.hCode:#include "GPS.h" double Vitesse() { double vitesse =GPS.speed*1.85; return vitesse; } double Allure() { double allure = GPS.speed*32.397408207623; return allure; } double Distance() { } boolean FixGps() { boolean fix = GPS.fix; return fix }
affich.cppCode:#ifndef GPS_h #define GPS_h #include <Adafruit_GPS.h> #include <SoftwareSerial.h> double Vitesse(); double Distance(); double Allure(); boolean FixGps(); #endif
affich.hCode:#include "affich.h" void Affich() { //Chrono tft.fillRect(100, 0, 100, 25, BACKGROUNDCOLOR); tft.setCursor(100, 0); tft.print((millis() / 1000) % 60); tft.print(":"); tft.print((millis() / 60000) % 60); //cadence tft.setCursor(30, 50); tft.print("Cadence"); tft.fillRect(50, 75, 25, 25, BACKGROUNDCOLOR); tft.setCursor(50, 75); tft.print(Cadence()); //heart tft.setCursor(150, 50); tft.print("Coeur"); tft.fillRect(140, 75, 25, 25, BACKGROUNDCOLOR); tft.setCursor(140, 75); tft.print(Heart()); //si le gps est pret if (FixGps() == 1) { //include gps? //allure tft.setCursor(250, 50); tft.print("Allure"); tft.fillRect(240, 75, 25, 25, BACKGROUNDCOLOR); tft.setCursor(240, 75); tft.print(Allure()); //vitesse tft.setCursor(90, 150); tft.print("Vitesse"); tft.fillRect(80, 175, 25, 25, BACKGROUNDCOLOR); tft.setCursor(80, 175); tft.print(Vitesse()); //distance tft.setCursor(190, 150); tft.print("Distance"); tft.fillRect(180, 175, 25, 25, BACKGROUNDCOLOR); tft.setCursor(180, 175); tft.print(Distance()); } } void Draw() { tft.setTextSize(2); // mise en place de la legende tft.setCursor(120, 200); tft.setTextColor(ILI9341_RED); tft.print("Coeur "); tft.setTextColor(ILI9341_GREEN); tft.print("Cadence "); tft.setTextColor(ILI9341_BLUE); tft.print("Vitesse"); tft.setTextColor(TEXTCOLOR); //couleur de text par defaut tft.setTextSize(3); tft.fillRect(0, 0, 320, 240, ILI9341_BLACK); int addr = 0; //adresse de l'eeprom à lire (ordonnée) int i = 0; //abscisse pour le graphique while (EEPROM.read(addr) != 1) { i++; //incrémentation de l'abscisse addr += 3; //+3 car 3 types de valeurs tft.drawPixel(j, EEPROM.read(addr), ILI9341_RED); } i = 0; addr = 1; while (EEPROM.read(addr) != 1) { i++; //incrémentation de l'abscisse addr += 3; //+3 car 3 types de valeurs tft.drawPixel(j, EEPROM.read(addr), ILI9341_GREEN); } i = 0; addr = 2; while (EEPROM.read(addr) != 1) { i++; //incrémentation de l'abscisse addr += 3; //+3 car 3 types de valeurs tft.drawPixel(j, EEPROM.read(addr), ILI9341_BLUE); } } void Choix() { int choix = 0; tft.fillRect(0, 0, 320, 240, BACKGROUNDCOLOR); tft.setCursor(0, 0); tft.setTextColor(TEXTCOLOR); tft.setTextSize(3); tft.print("*"); tft.setCursor(20, 0); tft.println("200 metres"); tft.setCursor(20 , 40); tft.println("500 metres"); tft.setCursor(20 , 80); tft.println("1000 metres"); tft.setCursor(20, 120); tft.println("retour"); tft.setCursor(0, 140); tft.println("Mauvais choix?\n Cliquez sur \n\"Valider\"!"); while (digitalRead(boutonOk) == HIGH) //detecte l'appui et valide { if (digitalRead(boutonNext) == LOW && choix == 0) { //selectionne le 200m if (digitalRead(boutonNext == HIGH)) { tft.fillRect(0, 0, 20, 140, BACKGROUNDCOLOR); tft.setCursor(0 , 40); tft.print("*"); choix++; delay(150); } } if (digitalRead(boutonNext) == LOW && choix == 1) { //selectionne le 500m if (digitalRead(boutonNext == HIGH)) { tft.fillRect(0, 0, 20, 140, BACKGROUNDCOLOR); tft.setCursor(0 , 80); tft.print("*"); choix++; delay(150); } } if (digitalRead(boutonNext) == LOW && choix == 2) { //selectionne le 100m if (digitalRead(boutonNext == HIGH)) { tft.fillRect(0, 0, 20, 140, BACKGROUNDCOLOR); tft.setCursor(0 , 120); tft.print("*"); choix++; delay(150); } } if (digitalRead(boutonNext) == LOW && choix == 3) { //selectionne "retour" if (digitalRead(boutonNext == HIGH)) { tft.fillRect(0, 0, 20, 140, BACKGROUNDCOLOR); tft.setCursor(0 , 0); tft.print("*"); choix = 0; delay(150); } } } tft.fillRect(0, 0, 320, 240, BACKGROUNDCOLOR); if (choix < 3) { tft.setCursor(40, 50); tft.println("Depart dans"); tft.setCursor(60, 130); tft.println("secondes"); tft.setCursor(110, 90); tft.print("10"); delay(5000); tft.fillRect(100, 90, 80, 30, BACKGROUNDCOLOR); tft.setCursor(110, 90); tft.print("5"); delay(3000); tft.fillRect(0, 0, 320, 240, BACKGROUNDCOLOR); tft.setCursor(80, 80); tft.print("READY"); delay(1000); tft.setCursor(95, 140); tft.print("SET"); delay(1000); tft.fillRect(0, 0, 320, 240, BACKGROUNDCOLOR); tft.setCursor(150, 110); tft.println("GO!\n \t"); if (choix == 1) tft.print("200 metres"); if (choix == 2) tft.print("500 metres"); if (choix == 3) tft.print("1000 metres"); tft.fillRect(0, 0, 320, 240, BACKGROUNDCOLOR); Run(choix); //envoie la variable choix a void Run() } } void RunAffichMenu() { tft.setTextSize(2); tft.setCursor(50, 80); tft.print("Cadence"); tft.setCursor(100, 80); tft.print("Allure"); tft.setCursor(50, 170); tft.print("Coeur"); tft.setCursor(100, 170); tft.print("Distance"); tft.setTextSize(4); } unsigned long RunAffich(chrono) { tft.setCursor(30,100); tft.print("\t\t\t"); tft.setCursor(30,100); tft.print(Cadence()); tft.setCursor(80,100); tft.print("\t\t\t"); tft.setCursor(80,100); tft.print(Allure()); tft.setCursor(30,180); tft.print("\t\t\t"); tft.setCursor(30,180); tft.print(Heart()); tft.setCursor(80,180); tft.print("\t\t\t"); tft.setCursor(80,180); tft.print(Distance2); //variable gobale? }
log.cppCode:#ifndef affich_h #define affich_h #include <Adafruit_GFX.h> #include <Adafruit_ILI9341.h> #include <Adafruit_STMPE610.h> #include <EEPROM.h> #define BACKGROUNDCOLOR ILI9341_BLUE #define TEXTCOLOR ILI9341_WHITE void Affich(); void Draw(); void Choix(); unsigned long RunAffich(chrono); void RunAffichMenu(); #endif
log.hCode:#include "log.h" void LogSd() { //stockage des données sur la sd on permanance digitalWrite(CSSREEN, LOW); // on deselectionne l'ecran pour le bus spi digitalWrite(csSd, HIGH); //on selectionne la sd sur le bus spi dataFile = SD.open("datalog.txt", FILE_WRITE); dataFile.print("m"); dataFile.print(millis()); dataFile.print("h"); dataFile.print(heart); dataFile.print("c"); dataFile.print(cadence); dataFile.print("v"); dataFile.println(GPS.speed*1.85); dataFile.close(); digitalWrite(csSd, LOW); //on deselectionne la sd sur le bus spi digitalWrite(CSSREEN, HIGH); // on selectionne l'ecran pour le bus spi } void LogEeprom() { //stockage des données dans eeprom si distance spécifique activée EEPROM.write(address,heart); address++; EEPROM.write(address,cadence); address++; EEPROM.write(address,GPS.speed*1.85); address++; } void WriteStart() { dataFile = SD.open("datalog.txt", FILE_WRITE); dataFile.print("S"); dataFile.close(); } void WriteEnd() { dataFile = SD.open("datalog.txt", FILE_WRITE); dataFile.print("E"); dataFile.close(); } unsigned long WriteChrono(chrono) { dataFile = SD.open("datalog.txt", FILE_WRITE); dataFile.print("C"); dataFile.print(unsigned long chrono); dataFile.close(); }
(la suite en commentaire)Code:#ifndef log_h #define log_h #include <SD.h> #include <EEPROM.h> #define CSSREEN 10 #define CSSD 4 File dataFile; void LogSd(); void LogEeprom(); void WriteStart(); void WriteEnd(); unsigned long WriteChrono(unsigned long chrono); #endif
Merci pour votre aide
Guillaume
-----