Problème lecture capteur pression différentielle en I2C

Bonsoir à toutes et tous,

Je bricole l'Arduino depuis quelques temps mais sans vraiment avoir un bon niveau en programmation. Généralement, en cherchant j'arrive toujours à résoudre mes problèmes. Cependant, même si j'ai trouvé une configuration qui fonctionne, je suis obligé de passer par un stratagème que je ne comprends pas du tout et je souhaiterais avoir vos lumières sur le pourquoi du comment.

Mon but est d'enregistrer sur une carte SD les informations suivantes :

  • Différentiel de pression utilisant un capteur approprié
  • Date, heure
  • Vitesse GPS

Le schéma est attaché en PJ de ce message.

Le code suivant fonctionnement parfaitement :

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "SDP6x.h"



File sdcard_file;
int CS_pin = 4;

TinyGPS gps;
SoftwareSerial ss(0, 1);




//Variables pour le GPS
static void print_date(TinyGPS &gps);
unsigned long date;
unsigned long heure;
unsigned long fix_age;
unsigned long speed;


//Variables pour la carte SD
String data;
String virgule = ";";



void setup() {
  Serial.begin(9600); //Setting baudrate at 9600
  ss.begin(4800);

  initialisation_sd_card();

// On écrit les en-têtes
  data = "millis()" + virgule + "date"+ virgule + "heure" + virgule + "fkmph" + virgule + "difPressure";
  Serial.println (data);
  sdcard_file = SD.open("pitot6.txt", FILE_WRITE); //Looking for the data.txt in SD card
  if (sdcard_file) { //If the file is found
    sdcard_file.println(data); //Writing to file
    sdcard_file.close(); //Closing the file
  }
  else {
    Serial.println("Failed to open the file");
  }
}


void loop() {
    initialisation_sd_card();//Lorsque je retire cette ligne, j'ai un problème

  //**********************************************************************GPS**********************************************************************
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  float fkmph = gps.f_speed_kmph();
  gps.get_datetime(&date, &heure, &fix_age);

  //**********************************************************************SD CARD**********************************************************************
  data = millis() + virgule + date + virgule + heure + virgule + fkmph + virgule + SDP6x.GetPressureDiff();
  Serial.println (data);


  sdcard_file = SD.open("pitot6.txt", FILE_WRITE); //Looking for the data.txt in SD card
  if (sdcard_file) { //If the file is found
    sdcard_file.println(data); //Writing to file
    sdcard_file.close(); //Closing the file
  }
  else {
    Serial.println("Failed to open the file");
  }

}

void initialisation_sd_card()
{
  pinMode(CS_pin, OUTPUT);//declaring CS pin as output pin

  if (SD.begin())
  {
    Serial.println("SD card is initialized and it is ready to use");
  } else
  {
    Serial.println("SD card is not initialized");
    return;
  }

}

J'ai le retour "data" suivant :
476017;41119;20444200;1.54;8.54

Cependant, lorsque je retire initialisation_sd_card(); à l'entrée du loop {}, j'ai le retour "data" suivant :
476017;41119;20444200;1.54;-10000000.00

Dans le premier cas, la valeur de 8,54 est la valeur de pression différentielle que je recherche, tout va bien. Dans le second cas, j'ai une valeur fixe de -10000000.00 qui ne veut rien dire du tout.

Je ne comprends absolument pas en quoi il est nécessaire de réutiliser ma fonction initialisation_sd_card(); pour faire fonctionner mon capteur monté en I2C. Certainement un lien avec la ligne pinMode(CS_pin, OUTPUT);, mais je ne comprends pas du tout pourquoi.

Pour info, voici la datasheet du capteur : http://kr.mouser.com/datasheet/2/682/Sensirion_Differential_Pressure_Sensors_SDP600Seri-1511233.pdf

Pour info, voici le code qui ne marche pas :

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "SDP6x.h"



File sdcard_file;
int CS_pin = 4;

TinyGPS gps;
SoftwareSerial ss(0, 1);




//Variables pour le GPS
static void print_date(TinyGPS &gps);
unsigned long date;
unsigned long heure;
unsigned long fix_age;
unsigned long speed;


//Variables pour la carte SD
String data;
String virgule = ";";



void setup() {
  Serial.begin(9600); //Setting baudrate at 9600
  ss.begin(4800);

  initialisation_sd_card();

// On écrit les en-têtes
  data = "millis()" + virgule + "date"+ virgule + "heure" + virgule + "fkmph" + virgule + "difPressure";
  Serial.println (data);
  sdcard_file = SD.open("pitot6.txt", FILE_WRITE); //Looking for the data.txt in SD card
  if (sdcard_file) { //If the file is found
    sdcard_file.println(data); //Writing to file
    sdcard_file.close(); //Closing the file
  }
  else {
    Serial.println("Failed to open the file");
  }
}


void loop() {

  //**********************************************************************GPS**********************************************************************
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  float fkmph = gps.f_speed_kmph();
  gps.get_datetime(&date, &heure, &fix_age);

  //**********************************************************************SD CARD**********************************************************************
  data = millis() + virgule + date + virgule + heure + virgule + fkmph + virgule + SDP6x.GetPressureDiff();
  Serial.println (data);


  sdcard_file = SD.open("pitot6.txt", FILE_WRITE); //Looking for the data.txt in SD card
  if (sdcard_file) { //If the file is found
    sdcard_file.println(data); //Writing to file
    sdcard_file.close(); //Closing the file
  }
  else {
    Serial.println("Failed to open the file");
  }

}

void initialisation_sd_card()
{
  pinMode(CS_pin, OUTPUT);//declaring CS pin as output pin

  if (SD.begin())
  {
    Serial.println("SD card is initialized and it is ready to use");
  } else
  {
    Serial.println("SD card is not initialized");
    return;
  }

}

Si quelqu'un a une explication pour que je comprenne, je suis preneur!

D'avance merci à vous!

Vous avez quel arduino ? Ce code est louche SoftwareSerial ss(0, 1);car les pins 0 et 1 sont souvent réservées à Serial (le port série matériel)

Bonjour,

Voici la raison de la valeur de -10000000 :

float SDP6xClass::GetPressureDiff(void)
{
int16_t res;
if (readSensor(ePresHoldCmd, (uint16_t*)&res)) {
return ((float)(res)/SCALEFACTOR);
} else {
return -10000000;
}
}

Elle apparait dès lors qu'une mesure du capteur n'a pas fonctionné.

Renvoyer une valeur aussi grosse pour déclarer une erreur est inutile.

Voici ce que dit la documentation Arduino :

"Initializes the SD library and card. This begins use of the SPI bus (digital pins 11, 12, and 13 on most Arduino boards; 50, 51, and 52 on the Mega) and the chip select pin, which defaults to the hardware SS pin (pin 10 on most Arduino boards, 53 on the Mega). Note that even if you use a different chip select pin, the hardware SS pin must be kept as an output or the SD library functions will not work."

J’ai une Arduino Nano. Le ss serial est là pour le gps.

Merci pour l’info, effectivement j’aurais pu aller fouiner dans la bibliothèque moi même...

Par contre, je n’ai peut-être pas saisi quelque chose, mais je ne comprends pas pourquoi est-ce qu’il rentre dans l’erreur, car je ne vois pas en quoi le fait de ne pas déclarer mon petit bout de programme au début de loop pose un problème pour le capteur.

salut

Note that even if you use a different chip select pin, the hardware SS pin must be kept as an output or the SD library functions will not work."

google trad et moi ne sommes pas daccord .

ici je comprends que meme si on utilise une pin differente , la carte doit garder le pin en tant que sortie pour fonctionner .

du coup vous pouvez faire un essai simplement en gardant l' activation de la pin CS ou SS mais pas la gestion de la carte SD , si ca fonctionne vous aurez pourquoi :smiley:

pinMode(CS_pin, OUTPUT);

J'ajouterai que cette ligne est inutile. La librairie SD configure la pin CS d'elle-même.
Cela n'a probablement aucun rapport avec le problème.

Que cela ne fonctionne pas sans initialiser la SD dans la loop est étrange.
As-tu essayé en virant les lignes de code en rapport avec la SD ?

Quand on fait SD.begin(), on initialise la librairie SD pour utiliser le bus SPI. Sur un UNO ça va occuper donc les pins 11, 12, et 13 ou sur un MEGA les pins 50, 51 et 52 en plus de la pin dite "chip select". Si on ne met pas de paramètre à l'appel de la fonction, alors la librairie prend par défaut celle matérielle, donc la SS pin 10 sur le UNO ou 53 sur le MEGA.

Si vous voulez utilisez la pin D4, qui n'est pas la pin standard, alors il faut la passer en paramètre lors de l'appel à SD.begin() en faisant

const byte CS_pin = 4;
...
  if (SD.begin(CS_pin)) {
    ...

mais comme le dit iznobe il faut aussi s'assurer de mettre la pin hardware en sortie, donc dans le setup un pinMode(SS, OUTPUT); // SS est prédéfinie à 10 sur un UNO ou 53 sur un MEGA

Extrait de Sd2Card.cpp :

uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin, int8_t mosiPin, int8_t misoPin, int8_t clockPin) {
  writeCRC_ = errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
  chipSelectPin_ = chipSelectPin;
  mosiPin_ = mosiPin;
  misoPin_ = misoPin;
  clockPin_ = clockPin;
  // 16-bit init start time allows over a minute
  uint16_t t0 = (uint16_t)millis();
  uint32_t arg;

  // set pin modes
  pinMode(chipSelectPin_, OUTPUT);
  chipSelectHigh();

La pin chipSelect est bien configurée en OUTPUT.
Le faire soi-même avant d'appeler SD.begin() ne sert à rien, mais il n'y a pas d'inconvénient.

hbachetti:
La pin chipSelect est bien configurée en OUTPUT.
Le faire soi-même avant d'appeler SD.begin() ne sert à rien, mais il n'y a pas d'inconvénient.

le point ici c'est qu'il veut utiliser la pin 4 (qui sera effectivement mise en OUTPUT s'il la passait dans le begin()) et que ce n'est pas la pin hardware par défaut.

ou je rate un truc ?

Non, il n'y a pas de ratage, il doit simplement appeler SD.begin(4).
Et la pin 4 sera bien configurée en OUTPUT par la librairie.

OK - on est d'accord

et il ne faut pas oublier dans ce cas dans le setup() de faire aussi pinMode(SS, OUTPUT); // SS est prédéfinie à 10 sur un UNO ou 53 sur un MEGA