Comment puis faire avec deux fichiers .cpp en une librairie

Bonjour à tous,
Ma question peu parraire bizard.

Dans mon dossir Libraries j'ai ceci

/Libraries/Sim908/Sim908.h
/Libraries/Sim908/Sim908.cpp
/Libraries/Sim908/gps.h
/Libraries/Sim908/gps.cpp

Dans la Sim908.h, j'ai toutes les fonctions qui gèrent le module, comme power_up
Dans la seconde j'ai les fonctions qui gèrent le gps, évidemment.

Dans Sim908.cpp, qui fonctionne, j'ai ceci (je mets pas tout mais ce qui est lié avec mon problème).
J'attire votre attention sur sendATcommand() qui doit etre appelée depuis gps.cpp.

#include "Arduino.h"
#include "Sim908.h"

SIM908::SIM908(int pin_gsm, int pin_gps, int pin_power, bool debug, int baute_rate)
{
  _baute_rate = baute_rate;
  _debug = debug;
  _pin_gsm = pin_gsm;
  _pin_gps = pin_gps;
  _pin_power = pin_power;
}

/* 2) Initilizing */
void SIM908::begin(void){
    [.. code ..]
}

bool SIM908::power_up(int attempt){
[... code ...]
}

uint8_t SIM908::sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout, boolean ln, boolean getResponse, boolean debug_buff,boolean bufferBy_Line)
{ 
    uint8_t x=0, answer=0;
    unsigned long previous;

    memset(buffer, '\0', BUFFERSIZE);    // Initialize the string

    delay(100);

    while(Serial1.available() > 0) Serial1.read();    // Clean the input buffer
    
    if(ln)
    {
      Serial1.println(ATcommand);    // Send the AT command 
    }
    else
    {
      Serial1.print(ATcommand);
    }

    //x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(Serial1.available() > 0){
          if(x < BUFFERSIZE-1) // Do not fill the buffer more the it size
          {
            buffer[x] = Serial1.read(); // response
            x++;
            // check if the desired answer is in the response of the module
            
            if(!debug_buff)
            {
              if (strstr(buffer, expected_answer1) != NULL)    
              { 
                 answer = 1;
              }
            }
            
          }
        }
        // Waits for the asnwer with time out
    }
    
    while((answer == 0) && ((millis() - previous) < timeout));   

    if(debug_buff){
    
      if (strstr(buffer, expected_answer1) != NULL)    
      {
        answer = 1;
      }
      
      Serial.println(F("\n*** RESPONSE ***"));
      Serial.println(buffer);
      Serial.println(F("****************\n"));
    }
    
    if(bufferBy_Line || getResponse)
    {
      bufferByLine(buffer,buffer_by_line);
    }
    
    if(getResponse)
    {
      sprintf(buffer,buffer_by_line[2]);
    }
    else
    {
      //strcpy(buffer,response);
    }
    delay(100);
    return answer;
}

Voilà, dans gps.cpp, la fonction sendATcommand est nécéssaire, mais je ne veux pas la copiée.
J'ai vu dans d'autre librairire que je peux faire

sim908.sendATcommand();

Alors j'ai fait comme ceci (là je mets plus de code :slight_smile: )

/*
  gps.h - Library 
*/

#ifndef gps_h
#define gps_h


#include "Arduino.h"
#include "Sim908.h"

class GPS{
	private:
		bool _bebug_gps;
		
	public:
		GPS(bool debug_gps);
		bool gps_start(void);
		
};
#endif

et là, le sujet de mon problème.
Vous voyez, que j'essaye de faire appel à sendATcommande en mettant comme préfix sim908.sendATcommand.
Je ne sais pas trop comment faire. J'ai ajouter

#include "Sim908.h"

aussi bien dans gps.h et gps.cpp. Ai-je besoin de le faire dans gps.h aussi?

#include "Arduino.h"
#include "Sim908.h"
#include "gps.h"

GPS::GPS(bool debug_gps)
{
	_bebug_gps = debug_gps;
}

bool GPS::gps_start(void){
	boolean gpspwr = false;  

	if(sim908.sendATcommand("AT+CGPSPWR=1","OK",4000, true, false,false,false))
  	{
    	gpspwr = true;
    	#ifdef DEBUG_GPS
      		Serial.println(F("> Powering GPS => OK"));
    	#endif
  	}
  	else
  	{
    	gpspwr = false;
    	#ifdef DEBUG_GPS
      		Serial.println(F("> Powering GPS => KO"));
    	#endif
  	}
    
  	/* Reseting GPS in autonomy mode */  
  	boolean gpsrst = false;
  	if(sim908.sendATcommand("AT+CGPSRST=1","OK",4000,true,false,false,false))
  	{
    	#ifdef DEBUG_GPS
      		Serial.println(F("> Reset GPS in Autonomy mode => OK"));
    	#endif
    	gpsrst = true;
  	}
  	else
  	{
    	#ifdef DEBUG_GPS
      		Serial.println(F("> Reset GPS in Autonomy mode => KO"));
    	#endif
    	gpsrst = false;
  	}      

  
  	if(gpspwr && gpsrst)
  	{
    	return true;
  	}
  	else
  	{
    	return false;
  	}
    
}

Pour info dans mon fichier .ino, j'ai ceci. J'attire votre attention sur if(gps.gps_start() ==0)
Cette ligne semble fonctionner. (lire plus bas)

#include <SoftwareSerial.h>
#include <Sim908.h>
#include <gps.h>


int baute_rate = 9600;
int pin_power = 5;
int pin_gsm = 3;
int pin_gps= 4;
boolean debug = 1;
boolean debug_gps = 1;

#define DEBUG

SIM908 sim908(pin_gsm, pin_gps, pin_power, debug, baute_rate);
GPS gps(debug_gps);

void setup() {
  // put your setup code here, to run once:
  sim908.begin();
  if(sim908.power_up(5))
  {
    #ifdef DEBUG 
      Serial.println(F("  Module is started"));
    #endif
    
    if(gps.gps_start() ==0)
    {
    }
    
  }

}

void loop() {
  // put your main code here, to run repeatedly:

}

Cette ligne

if(gps.gps_start() ==0)

semble fonctionner car mon terminal m'affiche ce messag d'erreur:

/Users/pierrot/Documents/Arduino/libraries/Sim908/gps.cpp: In member function 'bool GPS::gps_start()':
/Users/pierrot/Documents/Arduino/libraries/Sim908/gps.cpp:14:5: error: 'sim908' was not declared in this scope
if(sim908.sendATcommand("AT+CGPSPWR=1","OK",4000, true, false,false,false))

Donc il va bien dans cette fonction, mais il stoppe dans sim908.sendATcommand().

Pourriez-vous me corriger dans l'utilisation de deux fichiers d'une librairie?

Je vous remercie

Bonjour,

Ce que tu essayes de faire n'est pas du tout logique.

Si tu as besoin d'utiliser la fonction sendAtCommand() de ton autre classe tu DOIS :

  • soit lui fourni une instance de la classe en question (Sim908) pour pouvoir appeler la fonction (qui devra être publique, ou privée avec une déclaration "friend" pour l'autre classe).
    --> Appeler une fonction d'instance comme une fonction de classe n'est pas possible. Et même si c'était bien une fonction de classe, tu l’appellerait avec la syntaxe : NomDeLaClasse::nomDeLaFonction(); et non pas avec une "sim908.sendATcommand(...)".

  • soit faire hériter la classe gps de la classe sim908 mais ça ne me parait pas logique (en réalité le simple fait d'avoir deux classes ne me parait pas logique. Tu devrais revoir entièrement ton architecture de classe).

Dans tout les cas tu devrais :

  • Reprendre ton architecture de classe, il y a manifestement un gros problème de dépendance. Astuce : papier + crayon + uml + réflexion.
  • Revoir les bases du C++, en particulier les notions de membres de classe et membres d'instances de classe. Tu as manifestement sauté un chapitre :wink:

Salut,
Je te rejoins dans tout ton commentaire,

En effet, j'utilisais une librairie qui elle avait plusieurs librairies dans son dossier.
par exemple, il y avait le fichier gps.h et gsm.h et dans gps.cpp, il y avait un truc comme gsm.une fonction()

J'ai voulu faire la meme chose dans le but de séparer mon code. Et c'est aussi vrai qu'il y 2 mois je ne savais pas faire une librairire.

avant de lire ton post, j'ai abandoné cette idée et j'ai tout dans le meme fichier sim908.h et sim908.cpp. Je distingue mes fonctions avec un préfixe gsm_, gps_, ou gprs_

A la lecture de ton post, je pense que j'ai bien fait.

  • Revoir les bases du C++, en particulier les notions de membres de classe et membres d'instances de classe. Tu as manifestement sauté un chapitre

Ca je ne peux pas te contrdire.
Je suis parti de zéro. Je ne savais meme pas comment uploader du code dans un microcontroller, Il y a deux ans. J'ai tout fait en autodidact en me documentant sur le net. J'ai refais 7 fois mon code au fur et à mesure que j'apprenais. Maintenant j'ai presque terminer mon prototype et je peux gérer mon phone directory, gerer-recevoir-envoyer des sms, recevoir les positions GPS et les envoyer sur on serveur. Donc je suis assez content de mon investissement.

Cenpendant, c'est vrai qu'en avacant comme ceci on loupe des chapitres et quand mon proto sera à 100% terminer, j'ai décidé de prendre cours C++ pour compléter, ce qu'il me manque.

Mais tes remarques sont pertinente. :slight_smile:
Bonne soirée

pierrot10:
avant de lire ton post, j'ai abandoné cette idée et j'ai tout dans le meme fichier sim908.h et sim908.cpp. Je distingue mes fonctions avec un préfixe gsm_, gps_, ou gprs_

En prog il faut toujours se poser la question de qui fait quoi (responsabilité), qui utilise quoi (dépendance), qui stock quoi (modèle de données).
C'est l'étape de conception, la plus importante de toutes les étapes.
Et pour ça les meilleurs outils au monde sont : une feuille de papier, un crayon (et une gomme) et des schémas (uml ou autre). Ya pas mieux :grin:

pierrot10:
Cenpendant, c'est vrai qu'en avacant comme ceci on loupe des chapitres et quand mon proto sera à 100% terminer, j'ai décidé de prendre cours C++ pour compléter, ce qu'il me manque.

Regarde ici : Les meilleurs livres C++
(attention, ça va du livre pour débutant, au cahier de spécifications de norme C++ ;))

En fait ce qui n'est pas logique dans ton architecture c'est que le GPS accède au modem.
C'est le travail de l'application de vérifier que les périphériques fonctionne nominalement ce n'est pas aux périphériques de se tester mutuellement.
Si des composants communiquent entre eux cela doit se faire sous le contrôle de l'application principale. Sinon, elle n'a aucune vue de l'état du système et cela complique la gestion/remontée des erreurs.

En fait ce qui n'est pas logique dans ton architecture c'est que le GPS accède au modem.
C'est le travail de l'application de vérifier que les périphériques fonctionne nominalement ce n'est pas aux périphériques de se tester mutuellement.

Hello,
que veux tu dire par là.
J'utilise un sim908
http://www.gsmlib.org/
qui comprend un GPS et GSM/GPRS.
Dans la doc de commande AT, il y a une commande

AT+CGPSINF=0

qui retourne les positions GPS.

Que veux tu dire par "c'est que le GPS accède au modem". Heu j'aurais tendence a te repondre, "ben oui" vu que c'est "all in one".