I2C

Ciao a tutti,
sto realizzando un semplice progetto con Arduino mega e la GSM shield: si tratta di rilevare alcuni semplici parametri ambientali (temperatura, pressione, umidità) con il sensore BME280 e registrarli sul database di un server remoto utilizzando la gsm shield (Quectel M10).
Sia il BME280 che la GSM shield, separatamente, funzionano correttamente mentre unendo il codice per realizzare ciò che desidero la procedura si pianta.
Dopo un po' (forse non la totalità) di controlli mi è venuto in mente che forse c'è un conflitto tra l'uso della comunicazione I2C da parte del BME280 con Arduino e la GSM shield...
E' realista la mia ipotesi? qualcuno ha già verificato questo problema (e risolto)?
Googlando non ho trovato molto quindi confido in una vostra paziente risposta...
Grazie in anticipo

Il sensore usa come indirizzo 0x77 ("By default, the i2c address is 0x77. If you add a jumper from SDO to GND, the address will change to 0x76."), il GSM Shield qual è esattamente e quale indirizzo ha?

Più che altro direi che il GSM usa la seriale, quindi non vedo che conflitti possano esserci

Grazie infinite, Alex, per la risposta (ho aggiunto prontamente un punto al Karma...); purtroppo non capisco cosa intendi per "indirizzo".
La shield è questa...

Grazie anche a te Brunello 22, hai qualche suggerimento alternativo?

gpalmia:
purtroppo non capisco cosa intendi per "indirizzo".
La shield è questa...

Hm, non ho shield GSM ma stando alla documentazione non usa I2C, solo la seriale (pin 2 e 3, più il 7 per reset) come ha detto anche brunello22.
Per cui il problema deve essere un altro, ma per ora non credo sia hardware ma solo software. Se spieghi meglio cosa intendi con "si pianta", e posti anche qualche porzione di codice vediamo di capire.

gpalmia:
... purtroppo non capisco cosa intendi per "indirizzo" ...

... beh, allora sarà il caso che ti studi almeno i fondamenti del I2C prima di usarlo non credi? Prova a leggere QUI :wink:

Guglielmo

Ci provo:
il BME 280 è collegato come indicato in questa pagina;
mentre la GSM shield è posizionata sopra l'arduino mega (come da indicazioni trovate su questo sito il piedino 2 non è infilato sulla scheda arduino ed è stato creato un ponte tra il pin D2 ed il pin D10).
La connessione avviene con (ne più ne meno) il codice di esempio dell'IDE denominato "GSMwebclient" solo che invece di chiamare una pagina web del sito di arduino chiamo una pagina asp.net con dei parametri che sono i dati che devo salvare sul database remoto; la pagina processa i dati e li salva. Se la chiamata è nella routine loop allora tutte le volte che si ripete viene salvato un record sul db.
i parametri sono i dati ricavati dal BME280...
questo più o meno è il codice (naturalmente ci sono tanti 'Serial.print' che mi servono per effettuare il debug della procedura.

// libraries
#include "lib.h"

//SetUp GSM connection
// PIN Number
#define PINNUMBER ""
// APN data
#define GPRS_APN       "wap.myProvider.it" // replace your GPRS APN
#define GPRS_LOGIN     "login"    // replace with your GPRS login
#define GPRS_PASSWORD  "password" // replace with your GPRS password

// URL, path & port (for example: arduino.cc)
char server[] = "www.myServer.it";
int port = 80; // port 80 is the default for HTTP
// connection state
boolean notConnected = true; // 1

//Setup BME280 Meteo
//struct for Meteo data
struct meteo {
  float T;
  float U;
  float B;
};
meteo record;

//instantiate objects
Adafruit_BME280 bme; // Meteo sensor; I2C communication
GSMClient client;
GPRS gprs;
GSM gsmAccess;

void setup() {
  Serial.begin(9600);
  pinMode(7, OUTPUT);
  Spegni();
}

void loop() {



  Accendi();

  Serial.println("Connessione alla rete...");
  while (notConnected) {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
      delay(3000);
      if (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY) {
        notConnected = false;
      }
      else {
        delay(1000);
      }
    }
    else {
      delay(1000);
    }
  }
  Serial.println("...Connesso!");
  Serial.println("Connessione al sito gpalmia.it...");
delay(3000);
meteo record = get_meteo();
  
  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial.println("... connesso al server remoto!");
    Serial.println("Upload dei dati...");
    // Make a HTTP request:
    client.print("GET /Load?T=");
    client.print(record.T);
    Serial.print("Temperatura = ");
    Serial.println(record.T);
    client.print("&B=");
    client.print(record.B);
    Serial.print("Pressione = ");
    Serial.println(record.B);
    client.print("&U=");
    client.print(record.U);
    Serial.print("Umidita' = ");
    Serial.println(record.U);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    client.flush();
    client.stop();
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("Connessione fallita!");
  }

  Serial.println("Upload effettuato! Chiusura della connessione al server.");
  Serial.println("Disconnessione dalla rete e spegnimento della shield...");
  while (notConnected == false) {
    if (gsmAccess.shutdown() == 1) {
      delay(3000);
      notConnected = true;
    }
    else {
      Serial.println("Errori nella disconnessione!");
      delay(3000);
    }
  }
  Serial.println("... disconnesso e shield spenta!");
  Serial.println("Attendere 10 minuti per la riattivazione del sistema.");
  Serial.println("******************************************************");
  Serial.println("");
  delay(600000);
}

meteo get_meteo() {
  meteo result;
  result.T = bme.readTemperature();
  result.U = bme.readHumidity();
  result.B = (bme.readPressure() / 100.0F);
  return result;
}

void Spegni() {
  Serial.println("Spengo la shield...");
  digitalWrite(7, LOW);
  delay(1000);
  digitalWrite(7, HIGH);
  delay(2000);
  digitalWrite(7, LOW);
  Serial.println("... spenta!");
}

void Accendi() {
  Serial.println("Accendo la shield...");
  digitalWrite(7, HIGH);
  delay(1000);
  digitalWrite(7, LOW);
  delay(2000);
  digitalWrite(7, HIGH);
  Serial.println("... accesa!");
}

NB: dentro a lib.h ci sono le librerie per la GSM shield e per il BME280.

... dimenticavo, la procedura si pianta prima dell'upload dei dati... dopo la connessione con il server

Non capisco la cosa del ponte tra pin 2 e 10, comunque sia a questo punto secondo me hai collegato il BME in SPI e non I2C, per cui va in conflitto proprio il pin 10 che per SPI è il CS. O Non fai il ponte tra 2 e 10, o colleghi il BME in I2c come indicato in quella pagina Adafruit.

La "cosa" del ponte è scritta qui...
mentre il collegamento con il BME280 è sicuramente quello indicato come i2C, anche perchè ho solo due jumper che lo legano alla scheda (oltre all'alimentazione) piuttosto che quattro come indicato nel collegamento SPI... :frowning:

Beh più che il numero di fili direi che conta quali hai collegato, sia sul modulo sia su Arduino non ti pare? :wink:

Quindi confermi che hai collegato solo SDA/SCL ad A4 e A5 e che non c'è nulla sui pin da 10 in avanti tranne il GSM? Se così fosse, non mi spiego quali siano i problemi, mi spiace...

No... non è così (accidenti!) dopo il pin 10 c'è qualcosa: ci sono i pin SCL e SDA della scheda Arduino Mega che sono collegati rispettivamente ai pin SCK e SDI del sensore...
A leggere con attenzione sembrerebbe però che che questi due pin del sensore, sul mega, devono essere collegati al D20 e D21... che sia così? O devo collegarli come dici tu all'A4 e A5?
Quello che non capisco è che se io utilizzo solo il BME senza scheda GSM il sensore funziona perfettamente e mi manda sul seriale i dati che registra essendo collegato ai pin SCL e SDA della scheda mega.
:confused:

Ci posti anche il contenuto della lib.h?

Te lo chiedo perché ho il sospetto che ci sia qualche conflitto di interrupt, in rete ho trovato questo:

The pins 20 and 21 which are input hardware interrupts to Int2 and Int3 pins, also is used for the I2C interface (SDA and SCL signals respectively).
When using the Wire library and have ISR attached to interruptions 3 or 2 (Pin 20 or 21) a call to ISR will occur every time the ISR signals SDA and SCL signals are activated
This will cause a behavior not desired in software and hardware. If the ISR routine consumes time raised the Arduino Mega 2560 may crash and will require a restart. Is incompatible use the I2C bus and Int2 Int3 or interruptions at same time.

E visto che stai usando la serial su pin 2 e (soprattutto) 3 mi suona di incompatibilità hardware tra I2C e lo shield GSM, a meno che tu non rinunci ad usarlo come shield e lo cabli per avere RX/TX su altri pin del Mega.

Ma lascio la parola a chi è più esperto di me e che ha già smanettato con questo problema...

il file lib.h contiene i riferimenti a queste librerie:

#include <OneWire.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <GSM.h>
#include "HX711.h"