Problème bibliothèque Wire.h + GPS

Bonjour, actuellement en terminale S-SI nous devons réaliser un projet durant notre année. Nous aimerions créer un gps à partir d'arduino. Après avoir acquis le module GPS nous avons utilisé les bibliothèques de celui-ci. Nous aimerions maintenant ajouter un écran LCD fonctionnant en I2C (par économie de pins). Cependant notre programme gps tourne en boucle dans le moniteur lorsque nous ajoutons la bibliothèque wire.h (I2C). Il semblerait qu'il se réinitialise en boucle, comment faire?
Merci à ceux qui prendront le temps de nous répondre.
:~ :blush:
Code GPS fonctionnel:

#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <avr/sleep.h>

// Ladyada's logger modified by Bill Greiman to use the SdFat library
//
// This code shows how to listen to the GPS module in an interrupt
// which allows the program to have more 'freedom' - just parse
// when a new NMEA sentence is available! Then access data when
// desired.
//
// Tested and works great with the Adafruit Ultimate GPS Shield
// using MTK33x9 chipset
// ------> http://www.adafruit.com/products/
// Pick one up today at the Adafruit electronics shop 
// and help support open source hardware & software! -ada

SoftwareSerial mySerial(8, 7);
Adafruit_GPS GPS(&mySerial);

// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO true
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY false 

// Set the pins used
#define chipSelect 10
#define ledPin 13

const int buttonPin = 2; // the number of the pushbutton pin
const int led = 3; // the number of the LED pin

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status

File logfile;

// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
if (c < '0')
return 0;
if (c <= '9')
return c - '0';
if (c < 'A')
return 0;
if (c <= 'F')
return (c - 'A')+10;
}

// blink out an error code
void error(uint8_t errno) {
/*
if (SD.errorCode()) {
putstring("SD error: ");
Serial.print(card.errorCode(), HEX);
Serial.print(',');
Serial.println(card.errorData(), HEX);
}
*/
while(1) {
uint8_t i;
for (i=0; i<errno; i++) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
for (i=errno; i<10; i++) {
delay(200);
}
}
}

void setup() {

// initialize the LED pin as an output:
pinMode(led, OUTPUT); 
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT); 

// for Leonardos, if you want to debug SD issues, uncomment this line
// to see serial output
//while (!Serial);

// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
// also spit it out
Serial.begin(115200);
Serial.println("\r\nUltimate GPSlogger Shield");
pinMode(ledPin, OUTPUT);

// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);

// see if the card is present and can be initialized:
//if (!SD.begin(chipSelect, 11, 12, 13)) {
if (!SD.begin(chipSelect)) { // if you're using an UNO, you can use this line instead
Serial.println("Card init. failed!");
error(2);
}
char filename[15];
strcpy(filename, "GPSLOG00.TXT");
for (uint8_t i = 0; i < 100; i++) {
filename[6] = '0' + i/10;
filename[7] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}

logfile = SD.open(filename, FILE_WRITE);
if( ! logfile ) {
Serial.print("Couldnt create "); Serial.println(filename);
error(3);
}
Serial.print("Writing to "); Serial.println(filename);

// connect to the GPS at the desired rate
GPS.begin(9600);

// uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// uncomment this line to turn on only the "minimum recommended" data
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
// For logging data, we don't suggest using anything but either RMC only or RMC+GGA
// to keep the log files at a reasonable size
// Set the update rate
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 or 5 Hz update rate

// Turn off updates on antenna status, if the firmware permits it
GPS.sendCommand(PGCMD_NOANTENNA);

Serial.println("Ready!");
}

void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) { 
// turn LED oFF: 
digitalWrite(led, LOW);

char c = GPS.read();
if (GPSECHO)
if (c) Serial.print(c);

// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences! 
// so be very wary if using OUTPUT_ALLDATA and trying to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false

if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another

// Sentence parsed! 
Serial.println("OK");
if (LOG_FIXONLY && !GPS.fix) {
Serial.print("No Fix");
return;
}

// Rad. lets log it!
Serial.println("Log");

char *stringptr = GPS.lastNMEA();
uint8_t stringsize = strlen(stringptr);
if (stringsize != logfile.write((uint8_t *)stringptr, stringsize)) //write the string to the SD file
error(4);
if (strstr(stringptr, "RMC")) logfile.flush();
Serial.println();
}
}
else {
// turn LED oN:
digitalWrite(led, HIGH); 
}
}

/* End code */

Code Ecran en I2C:

/*********************

Example code for the Adafruit RGB Character LCD Shield and Library

This code displays text on the shield, and also reads the buttons on the keypad.
When a button is pressed, the backlight changes color.

**********************/

// include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

void setup() {
// Debugging output
Serial.begin(9600);
// set up the LCD's number of columns and rows: 
lcd.begin(16, 2);

// Print a message to the LCD. We track how long it takes since
// this library has been optimized a bit and we're proud of it 
int time = millis();
lcd.print("Hello, world!");
time = millis() - time;
Serial.print("Took "); Serial.print(time); Serial.println(" ms");
lcd.setBacklight(WHITE);
}

uint8_t i=0;
void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);

uint8_t buttons = lcd.readButtons();

if (buttons) {
lcd.clear();
lcd.setCursor(0,0);
if (buttons & BUTTON_UP) {
lcd.print("UP ");
lcd.setBacklight(RED);
}
if (buttons & BUTTON_DOWN) {
lcd.print("DOWN ");
lcd.setBacklight(YELLOW);
}
if (buttons & BUTTON_LEFT) {
lcd.print("LEFT ");
lcd.setBacklight(GREEN);
}
if (buttons & BUTTON_RIGHT) {
lcd.print("RIGHT ");
lcd.setBacklight(TEAL);
}
if (buttons & BUTTON_SELECT) {
lcd.print("SELECT ");
lcd.setBacklight(VIOLET);
}
}
}
#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <avr/sleep.h>

Vous utilisez beaucoup de librairies pour faire tourner ce programme. Dont la librairie SD qui est très gourmande en ressources mémoire. En ajoutant en plus la librairie de l'écran vous devez sans doute exploser la RAM.

J'ai même pas envie d'essayer de comprendre le code ... Pas de balise et plus com que de code ... Illisible

Comment faire donc pour réparer ce problème? J'ai modifié les balises, excusez moi pour le retard. Est-ce vraiment une histoire de RAM sur la arduino UNO?

Voir là:
http://playground.arduino.cc/Code/AvailableMemory
un outil qui permet d'afficher la mémoire disponible.
Il faut faire des appels à cette fonction et imprimer la valeur retournée à différents endroits du logiciel pour suivre la consommation de la mémoire. L'idéal étant de faire une première "mesure" à la fin du setup() pour voir la quantité de mémoire disponible après initialisation. Ensuite il faut adapter en fonction du programme.

Déjà avez-vous besoin de la librairie SD? Comptez-vous enregistrer les valeurs relevées par le GPS? Cette librairie à besoin de pas mal de mémoire car elle maintient un buffer de lecture/écriture puisque les accès à la carte mémoire se font par paquets.

Je vais essayer l'affichage de mémoire, malheureusement on utilise bien la librairie SD. On enregistre sur la carte les données à une fréquence de 1hz .. Cependant comment afficher la mémoire? Le programme fonctionne parfaitement sans l'écran, et rien que le fait d'ajouter la ligne: #include <Wire.h> fait boucler le programme sur "Ultimate GPSlogger Shield" dans le moniteur série..
J'ai peur que vous ayez raison, après lancement du programme test: freeMemory()=420 avec le GPS uniquement
Comment faire? Est-il possible d'ajouter de la ram?

Bonjour,

abarbeau:
Comment faire? Est-il possible d'ajouter de la ram?

Pas possible de rajouter de la RAM mais tu peux changer de carte.
Si UNO passe à MEGA par exemple.
Tu peux voir les caractéristiques ici : http://arduino.cc/en/Main/Products

Ok merci, vraiment aucun moyen pour la ram?.. Je regrette les barettes mémoires de mon pc ^^ Bon bah faut agir, vous connaissez un site où on peut acheter une arduino méga avec un temps record pour la recevoir? Car on a une échéance dans une semaine et demi..

Commander une carte et la recevoir en une semaine c'est quasiment mission impossible.
Tu ferais mieux de regarder si tu ne trouves pas un revendeur dans ta région ce serait cent fois plus rapide.

Merci du conseil, je pense que pour le moment on va abandonner l'idée de l'I2C et garder l'écran malgré tous les pins utilisés.. Merci à tous ceux qui ont pu poster sur cette discussion, bonne journée à vous. :slight_smile:

Si tu as suffisamment de broches autant commander l'écran directement.
Autrement une solution moins onéreuse serait d'utiliser une autre carte arduino "classique" pour gérer l'affichage, la communication entre les 2 cartes étant assurée par la liaison série. Cela n'ajoute pas de librairie à la partie GPS puisque la liaison série est déjà dans le programme.