SPI avec 2 esclaves

Bonsoir les arduigeeks,

je suis débutant dans la programmation en Arduino, j'ai suivi quelques tuto sur le net et me voila bloqué sur un projet personnel.

Pour interfacer un compteur d'eau à sortie impulsionnel à ma domotique je passe part un arduino pour le comptage d'impulsion. J'ai réalisé un programme pour un serveur web qui envoi un fichier XML et un autre pour sauvegarder sur carte SD l'index du compteur.

Mon problème et que je n'arrive pas à faire fonctionner en même temps ma carte SD en SPI et mon shield Ethernet(ENC28J60) en SPI. La carte SD fonctionne mais pas le shield ethernet.
Si je débranche l'un ou l'autre ça fonctionne bien mais pas les 2 en même temps. J'ai du mal comprendre un truc avec les esclaves en SPI je pense.

Voici mon code:

////////  Bibliothèque  ////////
#include <SPI.h>
#include <SD.h>
#include <UIPEthernet.h>
#include <UIPServer.h>
#include <UIPClient.h>
File monFichier;

const int pinSD = 7; // pin du SPI pour le carte SD
const int pinEth = 53; // pin du SPI pour la carte Ethernet
int index = 0;

//////////////////////////////
/////////  Ethernet  /////////  
//////////////////////////////

/////////  définition variable ethernet /////////  
#define MACADDRESS 0x00,0x01,0x02,0x03,0x04,0x05
#define MYIPADDR 192,168,0,6
#define MYIPMASK 255,255,255,0
#define MYDNS 192,168,0,211
#define MYGW 192,168,0,211
#define LISTENPORT 80
#define UARTBAUD 115200


/////////  Configuration Ethernet  /////////  
uint8_t mac[6] = {MACADDRESS};
uint8_t myIP[4] = {MYIPADDR};
uint8_t myMASK[4] = {MYIPMASK};
uint8_t myDNS[4] = {MYDNS};
uint8_t myGW[4] = {MYGW};

EthernetServer server = EthernetServer(LISTENPORT);


void setup() {
  /////  Initialisation des entrées et sorties /////
  Serial.begin(115200);         // init com série
  pinMode(pinEth, OUTPUT);    // init mode sortie pour la led d'impulsion
  pinMode(pinSD, OUTPUT);    // init mode sortie pour la led d'impulsion

  digitalWrite(pinSD, HIGH);  // Mise à 0 de la sélection de l'esclave shield SD
  digitalWrite(pinEth, HIGH); // Mise à 0 de la sélection de l'esclave shield Ethernet

  initSD();         // FONCTION d'init de la carte SD (voir onglet SD)
  initEthernet();   // FONCTION d'init ethernet (voir onglet ethernet)
}

void loop() {
  serveurEth();
}

void initSD() {
  //// Sélection de l'esclave shield Ethernet
  digitalWrite(pinSD, LOW);
  
  if (!SD.begin(pinSD)) {      // on test la com SD                             
    Serial.println("Erreur init SD");
    return; // stoppe le programme
  }
  Serial.println("SD initialisée !");

  //// Désélection de l'esclave shield Ethernet
  digitalWrite(pinSD, HIGH);
}

void initEthernet() {
  //// Sélection de l'esclave shield Ethernet
  digitalWrite(pinEth, LOW);
  
  //// Initialisation du module ethernet //////
  Ethernet.begin(mac,myIP,myDNS,myGW,myMASK);
  
  //// Démarre serveur + information mode debug ////
  server.begin();
  Serial.print(F("Le serveur est disponible ici : "));
  Serial.println(Ethernet.localIP());
  Serial.println(F("*** Fin de la configuration ***"));

  //// Désélection de l'esclave shield Ethernet
  digitalWrite(pinEth, HIGH);
}

void serveurEth() {
  //// Sélection de l'esclave shield Ethernet
  digitalWrite(pinEth, LOW);
  
  if (EthernetClient client = server.available()) //on écoute le port
  {
    if (client) { //si client connecté
      Serial.println("Client en ligne\n"); //on le dit...
      if (client.connected()){ //si client connecté
        while (client.available()) { //tant qu'il y a des infos à transmettre
          char c=client.read(); //on lit le caractère
          Serial.write(c); //on écrit le caractère sur le moniteur série
          delay(1); //délai d'écriture
         }
        //Réponse au client
        client.println("HTTP/1.1 200 OK"); // type du HTML
        client.println("Content-Type: text/xml"); //type de fichier et encodage des caractères
        client.println("Connection: close");  // fermeture de la connexion quand toute la réponse sera envoyée
        client.println(); //saut de ligne obligatoire avant la suite
        client.println("<root>"); 
        client.println("<indexEau>"); 
        client.println("</indexEau>");
        client.println("</root>"); 
        client.stop(); //on déconnecte le client
        Serial.println("Fin de communication avec le client");
      }
    }
  }
  //// Désélection de l'esclave shield Ethernet
  digitalWrite(pinEth, HIGH);
}

Merci d'avance pour votre aide :wink:

Les librairies le font pour vous normalement. Ne jouez pas avec les pins de sélection des esclaves car il y a des tâches asynchrones donc vous ne savez pas quand il faut les modifier

Merci pour le conseil. Je viens d'essayer, et toujours la même chose grrrrr

Quand je connecte les 2, la carte SD s'initialise bien (j'arrive même à reprendre la valeur sur le carte SD). Puis le serveur ethernet s'initialise bien, mais dès que j'essaye de taper mon adresse IP pour voir XML, rien ne ce passe (même dans ma console).
Alors que quand je déconnecte les pin de la carte SD, mon serveur fonctionne bien.

Je suis un peu perdu !!!

////////  Bibliothèque  ////////
#include <SPI.h>
#include <SD.h>
#include <UIPEthernet.h>
#include <UIPServer.h>
#include <UIPClient.h>
File monFichier;

const int pinSD = 7; // pin du SPI pour le carte SD
const int pinEth = 53; // pin du SPI pour la carte Ethernet
int index = 0;

//////////////////////////////
/////////  Ethernet  /////////  
//////////////////////////////

/////////  définition variable ethernet /////////  
#define MACADDRESS 0x00,0x01,0x02,0x03,0x04,0x05
#define MYIPADDR 192,168,0,7
#define MYIPMASK 255,255,255,0
#define MYDNS 192,168,0,211
#define MYGW 192,168,0,211
#define LISTENPORT 80
#define UARTBAUD 115200


/////////  Configuration Ethernet  /////////  
uint8_t mac[6] = {MACADDRESS};
uint8_t myIP[4] = {MYIPADDR};
uint8_t myMASK[4] = {MYIPMASK};
uint8_t myDNS[4] = {MYDNS};
uint8_t myGW[4] = {MYGW};

EthernetServer server = EthernetServer(LISTENPORT);


void setup() {
  /////  Initialisation des entrées et sorties /////
  Serial.begin(115200);         // init com série

  initSD();         // FONCTION d'init de la carte SD (voir onglet SD)
  initEthernet();   // FONCTION d'init ethernet (voir onglet ethernet)
}

void loop() {
  serveurEth();
}

void initSD() {
    
  if (!SD.begin(pinSD)) {      // on test la com SD                             
    Serial.println("Erreur init SD");
    return; // stoppe le programme
  }
  Serial.println("SD initialisée !");

}

void initEthernet() {
    
  //// Initialisation du module ethernet //////
  Ethernet.begin(mac,myIP,myDNS,myGW,myMASK);
  
  //// Démarre serveur + information mode debug ////
  server.begin();
  Serial.print(F("Le serveur est disponible ici : "));
  Serial.println(Ethernet.localIP());
  Serial.println(F("*** Fin de la configuration ***"));

}

void serveurEth() {
  
  if (EthernetClient client = server.available()) //on écoute le port
  {
    if (client) { //si client connecté
      Serial.println("Client en ligne\n"); //on le dit...
      if (client.connected()){ //si client connecté
        while (client.available()) { //tant qu'il y a des infos à transmettre
          char c=client.read(); //on lit le caractère
          Serial.write(c); //on écrit le caractère sur le moniteur série
          delay(1); //délai d'écriture
         }
        //Réponse au client
        client.println("HTTP/1.1 200 OK"); // type du HTML
        client.println("Content-Type: text/xml"); //type de fichier et encodage des caractères
        client.println("Connection: close");  // fermeture de la connexion quand toute la réponse sera envoyée
        client.println(); //saut de ligne obligatoire avant la suite
        client.println("<root>"); 
        client.println("<indexEau>"); 
        client.println("</indexEau>");
        client.println("</root>"); 
        client.stop(); //on déconnecte le client
        Serial.println("Fin de communication avec le client");
      }
    }
  }
}

Quels sont vos shields ? Photo du câblage ?

Voici les éléments:

-SODIAL(R) SPI Lecteur Micro Memoire SD TF carte memoire carte Module Bouclier pour Arduino

Avec le câblage ci-joint :

Alimentation 5V à partir de l'arduino (du port USB de mon PC) : est elle suffisante pour les 2 modules ?

  • MOSI (51), MISO(50) et SCK(52) le tout relier ensemble
  • SS ethrnet en 53 , et SS SD en 46

Avec le code suivant:

////////  Bibliothèque  ////////
#include <SPI.h>
#include <SD.h>
#include <UIPEthernet.h>
#include <UIPServer.h>
#include <UIPClient.h>
File monFichier;

const int pinSD = 46; // pin du SPI pour le carte SD
const int pinEth = 53; // pin du SPI pour la carte Ethernet
int index = 0;

//////////////////////////////
/////////  Ethernet  /////////  
//////////////////////////////

/////////  définition variable ethernet /////////  
#define MACADDRESS 0x00,0x01,0x02,0x03,0x04,0x05
#define MYIPADDR 192,168,0,7
#define MYIPMASK 255,255,255,0
#define MYDNS 192,168,0,211
#define MYGW 192,168,0,211
#define LISTENPORT 80
#define UARTBAUD 115200


/////////  Configuration Ethernet  /////////  
uint8_t mac[6] = {MACADDRESS};
uint8_t myIP[4] = {MYIPADDR};
uint8_t myMASK[4] = {MYIPMASK};
uint8_t myDNS[4] = {MYDNS};
uint8_t myGW[4] = {MYGW};

EthernetServer server = EthernetServer(LISTENPORT);


void setup() {
  /////  Initialisation des entrées et sorties /////
  Serial.begin(115200);         // init com série
  //pinMode(pinEth, OUTPUT);    // init mode sortie pour la led d'impulsion
  //pinMode(pinSD, OUTPUT);    // init mode sortie pour la led d'impulsion

  //digitalWrite(pinSD, HIGH);  // Mise à 0 de la sélection de l'esclave shield SD
  //digitalWrite(pinEth, HIGH); // Mise à 0 de la sélection de l'esclave shield Ethernet

  initSD();         // FONCTION d'init de la carte SD (voir onglet SD)
  initEthernet();   // FONCTION d'init ethernet (voir onglet ethernet)
}

void loop() {
  serveurEth();
}

void initSD() {
  //// Sélection de l'esclave shield Ethernet
  //digitalWrite(pinSD, LOW);
  
  if (!SD.begin(pinSD)) {      // on test la com SD                             
    Serial.println("Erreur init SD");
    return; // stoppe le programme
  }
  Serial.println("SD initialisée !");

  //// Désélection de l'esclave shield Ethernet
  //digitalWrite(pinSD, HIGH);
}

void initEthernet() {
  //// Sélection de l'esclave shield Ethernet
  //digitalWrite(pinEth, LOW);
  
  //// Initialisation du module ethernet //////
  Ethernet.begin(mac,myIP,myDNS,myGW,myMASK);
  
  //// Démarre serveur + information mode debug ////
  server.begin();
  Serial.print(F("Le serveur est disponible ici : "));
  Serial.println(Ethernet.localIP());
  Serial.println(F("*** Fin de la configuration ***"));

  //// Désélection de l'esclave shield Ethernet
  //digitalWrite(pinEth, HIGH);
}

void serveurEth() {
  //// Sélection de l'esclave shield Ethernet
  //digitalWrite(pinEth, LOW);
  
  if (EthernetClient client = server.available()) //on écoute le port
  {
    if (client) { //si client connecté
      Serial.println("Client en ligne\n"); //on le dit...
      if (client.connected()){ //si client connecté
        while (client.available()) { //tant qu'il y a des infos à transmettre
          char c=client.read(); //on lit le caractère
          Serial.write(c); //on écrit le caractère sur le moniteur série
          delay(1); //délai d'écriture
         }
        //Réponse au client
        client.println("HTTP/1.1 200 OK"); // type du HTML
        client.println("Content-Type: text/xml"); //type de fichier et encodage des caractères
        client.println("Connection: close");  // fermeture de la connexion quand toute la réponse sera envoyée
        client.println(); //saut de ligne obligatoire avant la suite
        client.println("<root>"); 
        client.println("<indexEau>"); 
        client.println("</indexEau>");
        client.println("</root>"); 
        client.stop(); //on déconnecte le client
        Serial.println("Fin de communication avec le client");
      }
    }
  }
  //// Désélection de l'esclave shield Ethernet
  //digitalWrite(pinEth, HIGH);
}

Comme ils disent dans le lien, il semble que le module enc28j60 est en 3.3V... le brancher sur 5V c'est risqué.... et le brancher sur la pin 3.3V n'aura pas assez de puissance

j'en ai un qui supporte 5V cependant (HanRun HR911105A)

est-ce le cas du votre?

Oui c'est exactement le même c'est marqué 5V

Vous pensez que c'est matériel ou programmation ?
Il faudrait peut être changer de bibliothèque pour l'ethernet ?

Pour info : j'ai testé une alimentation supérieur et ça ne change rien

Bon c'est tout j'ai investit dans un shield compatible avec la bibliothèque officiel avec Ethernet et SD.

et ça fonctionne?

Ma commande devrait pas tardé, je vous tiens au courant dès que j'aurais fait mes essais;)

J'ai les mêmes 2 composants que vous je regarderai ce week end si ça fonctionne

Ok merci c'est cool :wink:
Car je n'arrive vraiment pas à comprendre pourquoi les 2 ensembles ne fonctionnent pas alors que séparément aucun soucis.
Et je n'ai pas d'autres modules SPI juste de l'I2C pour faire un test avec d'autres modules.

j'ai essayé et effectivement ça ne fonctionne pas, même en branchant juste le lecteur SD en ayant sa pin CS à HIGH ça ne passe plus...

j'ai pas trop cherché plus loin - L'ENC28J60 est connu comme n'étant pas terrible comme composant et créant des pb donc pas trop surpris...

il se peut que ce soit lié à la consommation courant - 200mA pour la carte SD et parfois plus de 200/300 pour le ENC28J60 on est à la limite de ce que l'alimentation USB fournit

Sinon sur le UNO la mémoire était super remplie avec la libraire SD et Ethernet, donc il se peut que cela crée aussi des pb - j'ai eu la flemme mais faudrait tester sur une MEGA par exemple

Merci pour tes essais :wink:
J'ai une carte Mega et j'ai les mêmes soucis, même en alimentant avec une alimentation externe assez costaud.
Je vais laisser tomber ce module ethernet ou je m'en servirai quand j'aurais seulement un shield ethernet à mettre.

J'ai reçu une copie du Shield officiel (SD et Ethernet sur le même shield) qui fonctionne avec la bibliothèque officiel et je viens de tester.
Et la aucun soucis :slight_smile: J'ai même rajouté un module RTC en I2C et le tout fonctionne ensemble.

Je vais pouvoir mettre en place mon installation :slight_smile:
J'ai un arduino mega, un shield ethernet et SD, un module RTC en i2C qui seront reliés à ma domotique et mon compteur d'eau à sortie impulsionnelle. Et un progamme pour remonté en XML sur ma domotique le comptage et un système d'alarme qui détecte les fuites.

Merci encore pour ton aide :wink:

super projet !