Conflit entre PCD8544 et SD

Salut à tous,

Je me suis dernièrement lancé dans l'aventure Arduino.
Après quelques expériences de base, je m'essaie à un datalogger météo avec affichage des informations sur afficheur LCD NOKIA 5110 (PCD8544) et enregistrement des valeurs sur carte SD (Shield Ethernet/SD).

Le programme permettant d'afficher la pression atmosphérique, température et la courbe historique fonctionne.
Le programme permettant d'enregistrer les valeurs sur carte SD fonctionne également.

MAIS !!!!

Aussitôt que je veux afficher et enregistrer, plus rien ne fonctionne.

Le simple fait d'ajouter #include <SD.h> dans le programme permettant l'affichage sur l'écran LCD plante l'ensemble du programme et plus rien ne fonctionne (plus d'affichage, plus de relevés, plus rien).

J'ai l'impression qu'il s'agit d'un conflit entre librairies.

Ma config actuelle :

  • Arduino Uno Rev 2
  • Arduino Ethernet/SD Shield
  • Capteur pression et température BMP085
  • Afficheur LCD PCD8544

Les librairie utilisées sont les librairie de chez A##fruit.

Help, je tourne en rond sans comprendre l'origine du problème et surtout comment résoudre ce problème. Sauriez-vous m'orienter pour résoudre ce problème ?

Merci par avance.

Fred

fred28:
Help, je tourne en rond sans comprendre l'origine du problème et surtout comment résoudre ce problème. Sauriez-vous m'orienter pour résoudre ce problème ?

lol beaucoup de problème xDD

Bas ecoute moi j'ai déja eu des conflit sur le même shield que toi donc envoie ton code on va voire ça :slight_smile:

La SD et l'écran utilisent tous les 2 le bus SPI.
Donc il faut faire attention à utiliser un chip-select différent pour l'un et pour l'autre.
Et à ne pas les utiliser en même temps dans ton code (alternativement, ce qui ne devrait pas être difficile sur un système mono-tâche).

Bonjour,

je plussoie barbudor, problème de Chip Select, voir peut être problème de câblage du CS.

Code ?
Câblage ?
On n'est pas devins :wink:

Salut,

Tout d'abord merci pour votre aide.

Pour la partie cablage, voici ce que j'ai fait :
POUR LE LCD <--> ARDUINO
Arduino pin 7 = Serial clock out - SCLK
Arduino pin 6 = Sérial dat - SDIN =
Arduino pin 5 = Data/command select - D/C
Arduino pin 2 = LCD chip select - CS
Arduino pin 3 = LCD Reset - RST

Le tout passe via un buffer HEF4050.

POUR LE CAPTEUR BMP085 <--> ARDUINO
VCC --> 3.3v
GND
ARDUINO PIN A4 = SDA
ARDUINO PIN A5 = SCL

Le programme bug complètement dès le démarrage (pas d'affichage, pas d'enregistrement). Si je retire les instructions liées à l'enregistrement, l'affichage fonctionne alors correctement.

Pour le programme, voici ce que j'ai fait (mais qui ne fonctionne pas :~).

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <Adafruit_GFX.h> // Librairie graphique affichage
#include <Adafruit_PCD8544.h> // Librairie affichage
#include <SD.h>


Adafruit_PCD8544 display = Adafruit_PCD8544(7,6,5,2,3); //SCLK, SDIN, D/C, CS, RST
Adafruit_BMP085 bmp;
float suivi[84]; //Tableau enregistrement valeurs historique
float Pbrut; //Variable pression en sortie capteur
float Tbrut; //Variable temperatur en sortie capteur
String dataString = ""; 
const int chipSelect = 4; // CS Ethernet Shield  pin 4. 


/*********************************************************************************************************/
/*********************************************************************************************************/
void setup() {
  Serial.begin(9600);
  bmp.begin();  
 
  display.begin();
  display.clearDisplay(); 
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  
  //Initalisation Carte SD
  display.println("Init SD card..."); 
  display.display();
  delay(2000);
  display.clearDisplay(); 
  pinMode(10, OUTPUT);  
  
  // Vérifie présence carte SD et initialisation
  if (!SD.begin(chipSelect)) {
    display.println("Card failed, or not present");
    display.display();
    delay(2000);
    return; 
  }
  display.println("Card OK.");
  display.display();
  delay(2000);
}
  
/*********************************************************************************************************/
/*********************************************************************************************************/
void loop() {
    Pbrut = (bmp.readPressure());
    Tbrut = (bmp.readTemperature()); 
    display.clearDisplay(); 
    display.setCursor(0,0);
    display.print("P:");  display.print((Pbrut/100), 0); display.print(" T:");  display.print(Tbrut, 1);
    display.display();
    suivi[84]=((Pbrut/100)-985)/1;
    //Serial.print("Pressure = ");
    //Serial.print(suivi[84]);
    //Serial.println();
    
    for (int i=0; i<84; i++){
      suivi[i]=suivi[i+1];
      display.drawPixel(i,48-suivi[i],BLACK);
    }
  display.display();
  
  enregistrement(Pbrut);
  
    delay(1000); //Un relevé toutes les secondes
}

/*********************************************************************************************************/
/*********************************************************************************************************/
void enregistrement (float Pbrut){
    dataString="";
    Pbrut=bmp.readPressure();
    long prespa=Pbrut;
    int preshPa=prespa*0.01;
    int presfract=prespa-(preshPa*100);
    dataString += String(preshPa);
    dataString += ",";
    dataString += String(presfract);
    
    Tbrut = bmp.readTemperature();
    int temp = Tbrut;
    int tempfrac=(bmp.readTemperature()*10)-(temp*10);
    dataString += ";";
    dataString += String(temp);
    dataString += ",";
    dataString += String(tempfrac);
    
    Serial.println(dataString);
    
    File myFile = SD.open("logger.csv", FILE_WRITE);
    myFile.println(dataString);
    myFile.close();
  }

Hummm ça donne quoi sur le Serial Monitor ?

Ps: ouvrir le fichier et le fermer à chaque fois pour écrire une ligne c'est idéal pour fusiller une carte SD en quelques jours :wink:
Dans setup tu ouvre ton fichier csv, dans enregistrement() tu .println() ta ligne, puis tu appelle .sync(), pas plus, ça sera plus rapide, et ta carte sd tiendra beaucoup plus longtemps.

Et vu de ton code je pencherai pour un manque de ram !
Un gros tableau de float + lib SD + lib autres ... ça doit déborder ...

Utilise Arduino Playground - AvailableMemory pour afficher la mémoire ram dispo à la fin du setup() je pense que tu sera surpris :wink:

Salut,

Je ne parviens pas à savoir quelle mémoire il reste. J'ai intégré le test mémoire dans ma programmation. Mais ça reste desespérément bloqué et ne sort rien comme info (ça bloque donc dès le setup)
J'ai en revanche mis le test mémoire dans une ancienne version de ma programmation qui ne gérait pas encore la carte SD. En sortie de enregistrement(), il reste 590 (650 en sortie de setup).

Concernant la gestion de la carte SD, si je comprend bien :
File myFile = SD.open("logger.csv", FILE_WRITE); ==> A déplacer dans le setup afin de maintenir le fichier ouvert
myFile.println(dataString); ==> Je le laisse là ou il est

Par contre, je ne connais pas .sync(). ça consiste en quoi et ou dois-je le mettre ?
Pour myFile.close(); ==> Il faut que je créé un évenement pour générer la cloture du fichier (ex : appui sur bouton poussoir).

En supposant que ce soit le débordement mémoire, que faudrait-il que fasse pour palier à ce problème ?

fred28:
Je ne parviens pas à savoir quelle mémoire il reste. J'ai intégré le test mémoire dans ma programmation. Mais ça reste desespérément bloqué et ne sort rien comme info (ça bloque donc dès le setup)
J'ai en revanche mis le test mémoire dans une ancienne version de ma programmation qui ne gérait pas encore la carte SD. En sortie de enregistrement(), il reste 590 (650 en sortie de setup).

Ajoute des Serial.println("..."); entre les différentes étapes pour repérer celle qui bug :wink:
600 octets de ram, avec le tableau de 84 float ça passe pas.

fred28:
Concernant la gestion de la carte SD, si je comprend bien :
File myFile = SD.open("logger.csv", FILE_WRITE); ==> A déplacer dans le setup afin de maintenir le fichier ouvert
myFile.println(dataString); ==> Je le laisse là ou il est

Déclare File myFile en globale et met juste myFile = SD.open(..... dans setup.

fred28:
Par contre, je ne connais pas .sync(). ça consiste en quoi et ou dois-je le mettre ?

Oups, j'ai trop l'habitude d'utiliser Sdfatlib directement au lieu de SD.h :sweat_smile:
Pas besin de faire un file.sync() aprés avoir écrit avec la lib SD.h elle le fait d'elle même.

fred28:
Pour myFile.close(); ==> Il faut que je créé un évenement pour générer la cloture du fichier (ex : appui sur bouton poussoir).

Oui tu peut mais ça ne devrais pas trop poser de probléme de ne pas fermer le fichier proprement.

fred28:
En supposant que ce soit le débordement mémoire, que faudrait-il que fasse pour palier à ce problème ?

Optimiser à mort, réduire ce qui peut être réduit, et jouer avec les registres au lieux d'utiliser les fonctions arduino, certes simple mais pas du tout optimisé.
Exemple :

  • remplacer le tableau de float par un tableau de byte vu que le but est à la fin d'afficher un malheureux pixel (faire le calcul en float puis le stoqué dans un byte)
  • ne pas utiliser Serial si ce n'est pas nécéssaire.
  • Eviter les librairies en surnombre si il est possible de faire une fonction simple soit même faisant la même chose.

J'ai fait quelques optimisations suivants tes conseils. Il y a un progrès car il y a désormais un affichage à l'écran. en revanche ça tourne en rond sur le setup

Init SD card --> Card OK --> Init SD Card --> Card OK --> Init SD Card --> Card OK............
Le fichier a été créé sur la carte SD, mais est resté vide.
La mémoire pendant le setup est de 78 =(. Donc c'est bien un problème de mémoire ....
Même avec quelques optimisations ça ne passera certainement pas.

Il va falloir que je pense autrement mon projet ..... Pas simple.

Voici la version légèrement optimisée :

#include <MemoryFree.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <Adafruit_GFX.h> // Librairie graphique affichage
#include <Adafruit_PCD8544.h> // Librairie affichage
#include <SD.h>


Adafruit_PCD8544 display = Adafruit_PCD8544(7,6,5,2,3); //SCLK, SDIN, D/C, CS, RST
Adafruit_BMP085 bmp;
int suivi[84]; //Tableau enregistrement valeurs historique
float Pbrut; //Variable pression en sortie capteur
float Tbrut; //Variable temperatur en sortie capteur
String dataString = ""; 
const byte chipSelect = 4; // CS Ethernet Shield  pin 4. 
File myFile;


/*********************************************************************************************************/
/*********************************************************************************************************/
void setup() {
  Serial.begin(9600);
  bmp.begin();  
 
  display.begin();
  display.clearDisplay(); 
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  
  //Initalisation Carte SD
  display.println("Init SD card..."); 
  display.display();
  delay(2000);
  display.clearDisplay(); 
  pinMode(10, OUTPUT);  
  
  Serial.print("freeMemory()=");
  Serial.println(freeMemory());
  
  // Vérifie présence carte SD et initialisation
  if (!SD.begin(chipSelect)) {
    display.println("Card failed, or not present");
    display.display();
    delay(2000);
    return; 
  }
  display.println("Card OK.");
  display.display();
  delay(2000);
 
  
  myFile = SD.open("logger.csv", FILE_WRITE);
  
}
  
/*********************************************************************************************************/
/*********************************************************************************************************/
void loop() {
    Pbrut = (bmp.readPressure());
    Tbrut = (bmp.readTemperature()); 
    display.clearDisplay(); 
    display.setCursor(0,0);
    display.print("P:");  display.print((Pbrut/100), 0); display.print(" T:");  display.print(Tbrut, 1);
    display.display();
    suivi[84]=((Pbrut/100)-985)/1;

    
    for (int i=0; i<84; i++){
      suivi[i]=suivi[i+1];
      display.drawPixel(i,48-suivi[i],BLACK);
    }
  display.display();
  
  enregistrement(Pbrut);
  
    delay(1000); //Un relevé toutes les secondes
}

/*********************************************************************************************************/
/*********************************************************************************************************/
void enregistrement (float Pbrut){
    dataString="";
    Pbrut=bmp.readPressure();
    long prespa=Pbrut;
    int preshPa=prespa*0.01;
    int presfract=prespa-(preshPa*100);
    dataString += String(preshPa);
    dataString += ",";
    dataString += String(presfract);
    
    Tbrut = bmp.readTemperature();
    int temp = Tbrut;
    int tempfrac=(bmp.readTemperature()*10)-(temp*10);
    dataString += ";";
    dataString += String(temp);
    dataString += ",";
    dataString += String(tempfrac);
    
    Serial.println(dataString);
    

    myFile.println(dataString);
  }

Bonsoir,

je suis dans les même problèmes d'optimisation que toi et si tu veux mon avis faut qu'on trouve une fonction pour remplacer la lib SD.h, c'est la plus grosse elle me bouffe tout :s

Skizo ! !

skizoh:
je suis dans les même problèmes d'optimisation que toi et si tu veux mon avis faut qu'on trouve une fonction pour remplacer la lib SD.h, c'est la plus grosse elle me bouffe tout :s

Tu ne risque pas de réduire la librairie SD en une seul fonction :wink:
La librairie gére la communication sécurisé avec la carte SD, le décodage et l'indexation des partitions FAT16/FAT32, etc etc ...

Au mieux tu peut utiliser la lib fat16 Google Code Archive - Long-term storage for Google Code Project Hosting. qui est moins consommatrice de ram mais qui n'acceptera que des carte sd formaté en fat16

lol ok merci ^^ et oui je me doutais que ca pouvait pas ce faire ou du moin difficilement bref tampi je vais continuer à gratter des variable inutile a droite à gauche ^^

Skizo !