I²C - requestFrom gives value although nothing connected

Hey everyone, I've got an odd problem with I²C and the Wire Library.
Short description of my project:
I have an Arduino Due, which is responsible for most of the operations (TFT, temperature sensor ...) and an extra GSM Module on an Arduino Uno. I connected these two with I²C. At first, the Due needs to check, if the GSM Module is already connected to a net. So it sends a special "Op-Code" (In my case: "A") to tell the Uno, the next request it has to send back the gsm status. Every 5 seconds it will be checked.

That works fine: When the Uno is not connected, the Due prints a (GSM Module not connected. "0"), when I turn the Uno on, it prints (GSM Module not connected to net yet. "1") and when it's connected, it says connected ("2"). But when I plug it off again, it still says, it's connected, Wire.read() returns a "2". That cant be since there's no other slave on the bus. What's happening here?
Even when the GSM module loses the connection and goes to state 1, the Due gets state 2...
the fact that Wire.available() returns a non-zero value irritates me, since he CANT get an answer.
I don't know whats wrong here:
I cut out irrelevant parts.
Master (Due):

loop() {
 if (gsmcounter - gsmcounterold > 5000) {
    gsmcounterold = gsmcounter;
    w_Writer('A');
    Wire.requestFrom(4, 1);
  }
      if (Wire.available()>=1) {
        gsmConnected = Wire.read();
        Serial.println(gsmConnected);
        if (gsmConnected == 1) {
          Serial.println("GSM-Modul noch nicht mit Netz verbunden!");  //GSM module not connected to net
        } else if (gsmConnected == 2) {    
          Serial.println("GSM-Modul verbunden!"); //GSM module connected
        } else {
          Serial.println("GSM-Modul nicht erreichbar!");  //GSM module not reachable
        }
  }
}
void w_Writer(char c) {
  Wire.beginTransmission(4);
  Wire.write(c);
  Wire.endTransmission();
  delay(5);
}

Slave (Uno):

void receiveEvent(int m) {
  switch (state) {
    case 0:
      c = Wire.read();
.
.
.
}

void requestEvent() {
  switch (c) {
    case 'A':
      if (notConnected) {
        Wire.write(1);
        Serial.println("1");
      } else {
        Wire.write(2);
        Serial.println("2");
      }
      break;
  }
}

Do you have a logic level shifter between the arduino and due?
You need one of the UNO activates its internal pull up resistors.

Shit, I completely ignored that point, somehow I thought I²C uses generic levels (What obv is not the fact).
I hope the ports at the Due survived the 5V torture :open_mouth:
Thanks for the hint, I will build up a level shifter and see if that's the problem (I'll reply then).
Til then.

That obviously wasn't the source of the issue, but I'm glad someone came up with it...
Btw., just using some "external" pull-up resistors to pull the bus to 3,3V could've worked too or am I wrong? (If the Uno still recognizes ~3,3V as high.)
Although I got myself a logic level shifter with I2C support.

Any other suggestions? It can't be that the signals stay on the bus forever :frowning:

You can use a pull up to 3V3 so long as you do not enable the internal pull up resistors. This means hacking into the standard libary or using one that doesn't enable them by default.

Sorry no other insights.

Okay, the problem just occurs, when you unplug the Uno / the wires.
I found out a protocol way to distinguish if the value provided is still on the line (bcs of disconnect) or if it's really sent by the Uno. I just added a synchronize Byte between the status checks.
So Uno is always sending the status byte and after that the synchro byte. The Due receives the status Byte but when the synchro byte doesn't follow, it knows the Uno is disconnected.

Topic can be closed.