Pages: [1]   Go Down
Author Topic: [RESOLU] Communications série/I²C dans une classe  (Read 895 times)
0 Members and 1 Guest are viewing this topic.
Behind you
Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,

Est-ce que quelqu'un sait ou a déjà utilisé les communications séries et I²C dans une classe ? Et pourrait me dire comment faire, malgré tous mes tests je n'aboutis à rien !
Impossible de faire marcher mon MPU6050 par I²C et impossible de voir d'où ça vient parce que je n'arrive pas à faire fonctionner les com série à l'intérieur de ma classe.

Merci d'avance,

Bonne nuit smiley

Si ça peut servir le prog principal et la class incriminée:

Code:
#include <Wire.h>
#include <Servo.h>
#include "configuration.h"
#include "def.h"
#include <RADIOCOMMAND.h>
#include <QUADRICOPTER.h>

RADIOCOMMAND Radio(THROTTLE_PIN, YAW_PIN, PITCH_PIN, ROLL_PIN, MOT_LOCK_PIN);
QUADRICOPTER Quadri(MOT_A_PIN, MOT_B_PIN, MOT_C_PIN, MOT_D_PIN, PULSE_MOTOR_WIDTH_MIN, PULSE_MOTOR_WIDTH_MAX, BATT_PIN, LED_BATT_PIN);

void setup()
{
  /*Serial.begin(9600);
Wire.begin();
  while (!Serial);
  
  Serial.println("TEST");*/
}

void loop()
{
  // Petit Check batterie
  if (Quadri.etatBatterie() == Q_BAT_HS)
    Quadri.LED_etatBatterie(Q_BLINK);
  
  // Condition de mise route
 // if (Quadri.motorsRotate() == false) // si tous les moteurs sont arrêtés
   // while (Radio.isRTF() == Q_NOT_READY_TO_FLY);// et que l'inter est actif : on attend
  
  /***************************/
  /* PHASE DE CONTROL DE VOL */
  /***************************/
  Quadri.setConsignesDeVol(/*quelque chose*/);
  Quadri.CorrectionsDeVol(/* éventuellement quelques chose *unknown 4 the moment* */);
  
  Serial.println("bah ouai ca marche =) ");
  
  delay(1000);
  
}
Code:
#ifndef GYROSCOPE_H
#define GYROSCOPE_H

#include <Arduino.h>
#include <Wire.h>

//définition des adresses de registres
#define MPU6050_GYRO_XOUT_H 0x43   // R  
#define MPU6050_GYRO_XOUT_L 0x44   // R  
#define MPU6050_GYRO_YOUT_H 0x45   // R  
#define MPU6050_GYRO_YOUT_L 0x46   // R  
#define MPU6050_GYRO_ZOUT_H 0x47   // R  
#define MPU6050_GYRO_ZOUT_L 0x48   // R

#define MPU6050_PWR_MGMT_1 0x6B   // R/W
#define GYRO_CONFIG 0x1B  // RW

#define MPU6050_I2C_ADDRESS 0x68

class GYROSCOPE
{
public:
GYROSCOPE(void); // only 4 motors

void Update(void);
void Initialisation(void);

void request_Xout(void);
void request_Yout(void);
void request_Zout(void);

private:
uint16_t Xout;
uint16_t Yout;
uint16_t Zout;
};

#endif //GYROSCOPE_H
Code:
// gyroscope.cpp

#include <Arduino.h>
#include <Wire.h>
#include "gyroscope.h"

GYROSCOPE::GYROSCOPE(void)
{
Serial.begin(9600);
Serial.println("azertyuio");
Wire.begin();
Initialisation();
}

void GYROSCOPE::Update(void)
{
request_Xout();
request_Yout();
request_Zout();
}

void GYROSCOPE::Initialisation(void)
{
//Wire.begin();
// COPIÉ COLLÉ DE MULTI WII
TWBR = ((16000000L / 400000L) - 16) / 2; // change the I2C clock rate to 400kHz
Serial.println("1");
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Serial.println("2");
Wire.write(MPU6050_PWR_MGMT_1);
Serial.println("3");
Wire.write(0x80);
Serial.println("4");
Wire.endTransmission(true);
Serial.println("5");
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_PWR_MGMT_1);
Wire.write(0x03); //PWR_MGMT_1    -- SLEEP 0; CYCLE 0; TEMP_DIS 0; CLKSEL 3 (PLL with Z Gyro reference)
Wire.endTransmission(false);

Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(GYRO_CONFIG);
Wire.write(0x18); //GYRO_CONFIG   -- FS_SEL = 3: Full scale set to 2000 deg/sec
Wire.endTransmission(true);
}

void GYROSCOPE::request_Xout(void)
{
// Récupération des 8 bits de poids fort
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_GYRO_XOUT_H);
Wire.endTransmission(false);

Wire.requestFrom(MPU6050_I2C_ADDRESS, 1, false);
while(Wire.available() < 0);
Xout = Wire.read() << 8;

// Récupération des 8 bits de poids faible
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_GYRO_XOUT_L);
Wire.endTransmission(false);

Wire.requestFrom(MPU6050_I2C_ADDRESS, 1, true);
while(Wire.available() < 0);
Xout |= Wire.read();
}

void GYROSCOPE::request_Yout(void)
{
// Récupération des 8 bits de poids fort
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_GYRO_YOUT_H);
Wire.endTransmission(false);

Wire.requestFrom(MPU6050_I2C_ADDRESS, 1, false);
while(Wire.available() < 0);
Yout = Wire.read() << 8;

// Récupération des 8 bits de poids faible
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_GYRO_YOUT_L);
Wire.endTransmission(false);

Wire.requestFrom(MPU6050_I2C_ADDRESS, 1, true);
while(Wire.available() < 0);
Yout |= Wire.read();
}

void GYROSCOPE::request_Zout(void)
{
// Récupération des 8 bits de poids fort
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_GYRO_ZOUT_H);
Wire.endTransmission(false);

Wire.requestFrom(MPU6050_I2C_ADDRESS, 1, false);
while(Wire.available() < 0);
Zout = Wire.read() << 8;

// Récupération des 8 bits de poids faible
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
Wire.write(MPU6050_GYRO_ZOUT_L);
Wire.endTransmission(false);

Wire.requestFrom(MPU6050_I2C_ADDRESS, 1, true);
while(Wire.available() < 0);
Zout |= Wire.read();
}
« Last Edit: January 12, 2013, 08:45:50 pm by Reynosa » Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 23
Posts: 2054
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il n'y a pas de soucis pour utiliser de l'I2C dans une classe.
J'ai moi même une classe qui encapsule le PCF8574 (attachée) et Skywodd en a aussi une autre sur son blog.
Je te laisse y jeter un coup d'oeil.

* pcf8574.zip (2.39 KB - downloaded 18 times.)
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Behind you
Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour !

Quand le téléchargement du zip nous renvoie une magnifique erreur 503 on doit faire quoi ^^
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 23
Posts: 2054
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Prier ?
Crier sur le modo ?
Aller à la concurrence ?

smiley-lol
http://www.barbudor.net/files/pcf8574.zip
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Behind you
Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm j'hésite !

Je vais me contenter de cliquer sur le petit lien je crois x)
Logged

Behind you
Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai étudié les deux lib pour le pcf (skywodd et toi),

Chez skywodd il n'y a pas le Wire.begin() dans le constructeur. Chez toi il n'y a pas de Wire.begin() tout court  smiley-lol

J'ai donc fait plein de test et les résultats de tous mes tests indiquent que de l'I²C dans le constructeur de ma classe ça ne marche pas du tout... le programme plante tout le temps (même quand je met pas le Wire.begin()).
La seule solution que j'ai trouvé est de d'initialiser tout ça à la main, hors constructeur... J'aime pas je trouve pas ça très propre  smiley-sad

Une idée pour pouvoir utiliser l'i²C dans le constructeur ?

PS: ligne 40 de ta lib est-ce normal les double point virgule ? " return Wire.read();; "
Logged

France
Offline Offline
Faraday Member
**
Karma: 52
Posts: 5341
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il n'y a pas de soucis pour utiliser de l'I2C dans une classe.
J'ai moi même une classe qui encapsule le PCF8574 (attachée) et Skywodd en a aussi une autre sur son blog.
Je te laisse y jeter un coup d'oeil.
Je conseille celle de Barbudor, du moins pour le moment smiley-mr-green
La mienne est vraiment pas optimisé et plein de truc sont à reprendre, c'était ma toute première librairie arduino et ça se ressent au niveau code ...
Une nouvelle version est en cours de préparation mais il va me falloir un peu de temps pour tout finir smiley-sweat

J'ai donc fait plein de test et les résultats de tous mes tests indiquent que de l'I²C dans le constructeur de ma classe ça ne marche pas du tout... le programme plante tout le temps (même quand je met pas le Wire.begin()).
La seule solution que j'ai trouvé est de d'initialiser tout ça à la main, hors constructeur... J'aime pas je trouve pas ça très propre  smiley-sad
En I2C tu peut avoir plusieurs modules sur un même bus.
Tu peut donc avoir plusieurs objet PCF8574 instancié dans un même code.
Mettre Wire.begin() dans le constructeur reviendrai à initialiser le bus I2C plusieurs fois inutilement.
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 23
Posts: 2054
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

PS: ligne 40 de ta lib est-ce normal les double point virgule ? " return Wire.read();; "

fôte de phrape

Le Wire.begin n'est pas dans la lib car on peut avoir plusieurs instances ou plusieurs chips sur l'I2C
Donc dans mon exemple d'utilisation il est dans setup()

De même je n'accède pas à l'I2C dans le constructeur.

En effet il faut être conscient que pour tous les objets instanciés en variable globale, le constructeur est appellé AVANT setup() !!!!!

Je pense que ton problème est là.

Je suggère :

1) Vire tout accès à l'I2C des constructeurs de tes classes. Dans les constructeurs ne touche pas au hard d'une manière générale (même pas pinmode ou digitalRead/digitalWrite), contente toi d'initialiser tes variables uniquement.
Met toute l'init hard dans une fonction begin().

2) dans setup() appelle Wire.begin
puis appelle la fonction begin() de tes objets.
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Behind you
Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonne nuit =)

Hé bien voici une de magnifiques réponses !  smiley

C'est vrai que du point de vue "qui est fait quand" c'est tout à fait logique !
Je pense qu'il va falloir que j'adopte cette manière de raisonner moi  smiley-wink

Encore merci !
Logged

Pages: [1]   Go Up
Jump to: