Je m'excuse d'avance de vous prendre du temps pour mon problème de codage, qui doit être tout simple... je ne sais pas si c'est l'heure ou autre chose, mais ça fait plusieurs heures que je cherche en vain... je suis aveugle ce soir.
J'espère qu'un regard neuf là dessus pourra me sortir de là :~
Je vous laisse voir la screen:
les fichiers correspondant sont en pièces jointes.
Merci !
QUADRICOPTER\QUADRICOPTER.cpp.o: In function QUADRICOPTER': C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/QUADRICOPTER.cpp:8: undefined reference to MOTOR::MOTOR(unsigned char, unsigned int, unsigned int)'
C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/QUADRICOPTER.cpp:9: undefined reference to MOTOR::MOTOR(unsigned char, unsigned int, unsigned int)' C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/QUADRICOPTER.cpp:10: undefined reference to MOTOR::MOTOR(unsigned char, unsigned int, unsigned int)'
C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/QUADRICOPTER.cpp:11: undefined reference to MOTOR::MOTOR(unsigned char, unsigned int, unsigned int)' C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/QUADRICOPTER.cpp:12: undefined reference to GYROSCOPE::GYROSCOPE()'
Maintenant le ino:
#include <Servo.h>
#include <inttypes.h>
#include "configuration.h"
#include "def.h"
#include <RADIOCOMMAND.h>
#include <QUADRICOPTER.h>
RADIOCOMMAND Radio(THROTTLE_PIN, YAW_PIN, PITCH_PIN, ROLL_PIN);
QUADRICOPTER Quadri(MOT_A_PIN, MOT_B_PIN, MOT_C_PIN, MOT_D_PIN, PULSE_MOTOR_WIDTH_MIN, PULSE_MOTOR_WIDTH_MAX);
void setup()
{
}
void loop()
{
// Petit Check batterie
if (Quadri.etatBatterie() == Q_BAT_HS)
Quadri.LED_etatBatterie(Q_BLINK);
// Condition de mise route
while (Radio.isRTF() != Q_READY_TO_FLY);
/***************************/
/* PHASE DE CONTROL DE VOL */
/***************************/
Quadri.setConsignesDeVol(/*quelque chose*/);
Quadri.CorrectionsDeVol(/* éventuellement quelques chose *unknown 4 the moment* */);
}
S'il ne trouvait pas le motor.h il devrait me le dire étend donné que je l'inclus dans QUADRICOPTER.h ?
Dans tous mes essaies j'ai essayé d'inclure directement motor.h dans le QUADRICOPTER.cpp et ça ne change strictement rien :~
Pas facile d'essayer de reproduire ton problème, il manque encore plein de fichiers.
Quoi qu'il en soit j'arrive a compiler QUADRICOPTER et MOTOR
Je ne tombe pas sur ton erreur mais j'ai du bricoler les chemins d'accès aux fichier include pour arriver a compiler quelque chose. Donc je pense que tu as un problème de ce coté là.
Peut être ne va t'il pas chercher le MOTOR.h que tu crois .....
Essaye de créer une erreur volontaire dans ton MOTOR.h pour voir s'il la trouve :
#error Est-qu'il passe par ici ?
Par contre je voit d'autres erreurs plutot graves a corriger :
motor.cpp: In member function 'void MOTOR::writeVitesse(uint8_t)':
motor.cpp:19: warning: division by zero
QUADRICOPTER.cpp: In member function 'boolean QUADRICOPTER::etatBatterie()':
QUADRICOPTER.cpp:25: warning: no return statement in function returning non-void
QUADRICOPTER.cpp:25: warning: control reaches end of non-void function
J'ai rajouté la ptite ligne au milieu de la classe et la compilateur passe bien par là.
In file included from C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/QUADRICOPTER.h:7,
from Helixcopter.ino:6:
C:\Users\HéliX\Documents\Arduino\libraries\QUADRICOPTER/includes\motor.h:17:4: error: #error Est-qu'il passe par ici ?
Au fur et à mesure des tests j'avais des fichiers qui se baladait par tout. J'ai donc tout supprimé et gardé les indispensables. J'ai tout recompilé et j'ai toujours l'erreur.
Pour simplifier ce topic je joins donc tout mon dossier arduino (le projet entier avec les librairies) pour que vous puissiez reproduire ma compilation.
En ce qui concerne la division par zéro je ne sais pas trop quoi dire... 255/1000 ne donne pas zéro pour moi ^^ les autres warning c'est parce que les fonctions ne sont pas encore implémentées.
Reynosa:
En ce qui concerne la division par zéro je ne sais pas trop quoi dire... 255/1000 ne donne pas zéro pour moi ^^ les autres warning c'est parce que les fonctions ne sont pas encore implémentées.
Si, en entier.
255/1000 = 0
255.0 / 1000.0 = 0.255
Note que passer en flottant n'est pas forcément une solution car les calculs flottants sur un micro 8 bits coûtent extrêmement chers en CPU.
De plus ce code présente d'autres problèmes :
Je viens de jeter un coup d'oeil.
L'erreur est une erreur de l'édition de lien, pas de la compilation. C'est le linker qui ne trouve pas le code de Motor.cpp parce que motor.cpp n'est pas dans la lib. Le problème viens de ton arborescence.
Tu met des CPP dans le répertoire "Includes" ce qui semble empecher leur inclusion dans le projet.
Les CPP devraient être dans le répertoire racine de la lib. Tu peux laisser les includes dans "Includes" ou bien tout mettre dans le répertoire racine.
Perso je choisirait de tout mettre dans le répertoire racine de la lib.
Je constate bien que certaines libs standard comme Ethernet utilise bien des sous répertoires mais je ne vois pas la différence avec ton cas. En tout cas si je met tout dans le répertoire racine de la lib, ton code compil beaucoup mieux.
Ensuite, il faut que chaque lib utilisée (même par un sous module d'une autre lib) soit déclarée par un #include dans le INO.
L'environnement Arduino n'ira chercher les includes que dans les répertoires des libs qui ont été déclarées dans le INO.
Par exemple, si tu ne met pas #include <Wire.h> dans le INO, il ne trouvera pas Wire.h lors de la compilation de gyroscope.cpp
Par ailleurs il est préférable d'utiliser <Arduino.h> plutot que <inttypes.h>
A chaque fois que je corrige un problème, je tombe sur un autre.
Par exemple fonctions déclarées comme request_Xout() mais appellée comme requestXout().
J'arrête là, je vais pas chercher a tout corriger.
Je pense qu'il faut que tu repartes d'un squelette propre qui compile et que tu ajoutes les éléments petit a petit au lieu de coder au kilomètre et de te retrouver avec un gros machin qui ne compile pas et qui comporte des problèmes en cascade.
Merci beaucoup d'avoir pris un temps précieux à l'approche du réveillon pour me répondre !
Tout est rentré dans l'ordre ! tout fonctionne à merveille maintenant. À un détail près. Comment doit-on s'y prendre pour passer un nom de méthode d'une classe à "attachInterrupt()" ?
J'ai essayé avec et sans parenthèses, j'ai aussi essayé par le setup avec "Radio.ISR_UpdateInfoCommand" et dans le constructeur de la classe avec "ISR_UpdateInfoCommand" il n'en veut pas dans tous les cas.
C:\Users\HéliX\Documents\Arduino\libraries\RADIOCOMAND\RADIOCOMAND.cpp: In constructor 'RADIOCOMMAND::RADIOCOMMAND(uint8_t, uint8_t, uint8_t, uint8_t)':
C:\Users\HéliX\Documents\Arduino\libraries\RADIOCOMAND\RADIOCOMAND.cpp:18: error: argument of type 'void (RADIOCOMMAND::)()' does not match 'void (*)()'
C:\Users\HéliX\Documents\Arduino\libraries\RADIOCOMAND\RADIOCOMAND.cpp:19: error: argument of type 'void (RADIOCOMMAND::)()' does not match 'void (*)()'
C:\Users\HéliX\Documents\Arduino\libraries\RADIOCOMAND\RADIOCOMAND.cpp:20: error: argument of type 'void (RADIOCOMMAND::)()' does not match 'void (*)()'
C:\Users\HéliX\Documents\Arduino\libraries\RADIOCOMAND\RADIOCOMAND.cpp:21: error: argument of type 'void (RADIOCOMMAND::)()' does not match 'void (*)()'
C:\Users\HéliX\Documents\Arduino\libraries\RADIOCOMAND\RADIOCOMAND.cpp:22: error: argument of type 'void (RADIOCOMMAND::)()' does not match 'void (*)()'
Je dois m'y prendre comme une patate, mais j'ai pas trouvé d'exemple ailleurs...
Il n'est pas possible de passer une fonction membre non-statique de classe comme paramètre de attachInterrupt().
Il faut une fonction statique. Cela veut dire que la fonction ne peut pas accéder aux membres d'une instance.
Par exemple le code ci dessous marche
class MaClasse
{
public:
MaClasse() { a = 0; }
int a;
static int s_b;
static void Interrupt();
};
void MaClasse::Interrupt()
{
s_b++;
}
int MaClasse::s_b = 0; // Initialisation d'une variable statique de classe ~= variable globale de la classe
MaClasse essai;
void setup()
{
attachInterrupt( INT0, MaClasse::Interrupt, RISING );
}
void loop()
{
}
Mais il ne fait peut être pas ce que tu veux car la fonction MaClasse::Interrupt() est statique (donc "globale" à la classe) et ne peut pas accéder à l'instance "essai".
Pour gérer des fonctions d'interruptions associées à une instance d'objet, il faut gérer la passage du contexte.
Par exemple :
#define NB_INTR 2
class MaClasse
{
public:
MaClasse() { a = 0; }
int a;
static int s_b;
static class MaClasse *IntrObject[NB_INTR];
static void s_Interrupt0();
static void s_Interrupt1();
static void setInterrupt( byte intnum, MaClasse *pObject = NULL, byte mode = RISING );
void Interrupt();
};
class MaClasse *MaClasse::IntrObject[NB_INTR] = {0, };
void MaClasse::setInterrupt( byte intnum, class MaClasse *pObject, byte mode )
{
if ( intnum >= NB_INTR )
return;
if ( pObject )
{
IntrObject[intnum] = pObject;
switch( intnum )
{
case 0: attachInterrupt( intnum, s_Interrupt0, mode ); break;
case 1: attachInterrupt( intnum, s_Interrupt1, mode ); break;
}
}
else
{
detachInterrupt( intnum );
IntrObject[intnum] = NULL;
}
}
void MaClasse::s_Interrupt0()
{
if ( IntrObject[0] )
IntrObject[0]->Interrupt();
}
void MaClasse::s_Interrupt1()
{
if ( IntrObject[1] )
IntrObject[1]->Interrupt();
}
void MaClasse::Interrupt()
{
++a;
}
int MaClasse::s_b = 0; // Initialisation d'une variable statique de classe ~= variable globale de la classe
MaClasse essai0;
MaClasse essai1;
void setup()
{
// attachement de l'objet essai0 à INT0
MaClasse::setInterrupt( 0, &essai0 );
// attachement de l'objet essai1 à INT1
MaClasse::setInterrupt( 1, &essai1 );
}
void loop()
{
}
J'ai bien compris le premier exemple et c'est vrai qu'étant liée à la classe la fonction ne répond pas à ce que je veux.
Quant au deuxième exemple... Je ne comprend pas du tout, il fait appel à des connaissances que je n'ai pas...
Par contre sachant que ma classe RADIOCOMMAND n'est instanciée qu'une fois, est-ce que cela revient au même de mettre ses attributs en 'static' ? je pourrais par conséquent utiliser la première méthode, une méthode statique peut modifier des attributs statiques.