Go Down

Topic: Wire.requestFrom() hangs (Read 1 time) previous topic - next topic

soend

Hei,

Im tryng to read SHT25(http://www.sensirion.com/en/pdf/product_information/Datasheet-humidity-sensor-SHT25.pdf) sensor with my arduino UNO. Since SHT25 uses 3.3v i disabled arduino pullup resistors from Wire lib (in twi.c removed   digitalWrite(SDA, 1); and digitalWrite(SCL, 1);) and use my own for 3.3v.

So now here's the code im running:
Code: [Select]
    Wire.beginTransmission(eSHT2xAddress); //begin
    Serial.println("begin done");
    Wire.write(command); //send the pointer location
    Serial.println("write done");
    delay(100);
    Wire.endTransmission();                //end
    Serial.println("end trans done");

    Wire.requestFrom(eSHT2xAddress, 3);
    Serial.println("request from done");
    while(Wire.available() < 3) {
      Serial.println("waiting"); //wait
    }

    //Store the result
    result = ((Wire.read()) << 8);
    result += Wire.read();
result &= ~0x0003;   // clear two low bits (status bits)


I added Serial.println() between the Wire calls to debug whats going on and the result is that program hangs on: Wire.requestFrom(eSHT2xAddress, 3);

Whats also strange is that sometimes it happens on the first run, sometimes it reads the temperature properly couple of times and then hangs.

Do anybody have some ideas what might be going wrong?

soend

Looks like anybody else have'nt had problems with that. But maybe someone can answere and say if its a problem that arduino is running on 5V and my sensor on I2C is running on 3.3V?

dialsc

Hi,

Have you ever get this to work? I'm facing the same problem.

pylon

Quote
Have you ever get this to work? I'm facing the same problem.


So post your full code which the OP hasn't.

damago1

I have the same problem. This function call hangs from time to time. The code is:

Code: [Select]
unsigned int readI2CRegister16bit(int addr, int reg) {
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission();
  delay(40); 
  Wire.requestFrom(addr, 2); //hangs here efery hundred reads
  unsigned int t = Wire.read() << 8;
  t = t | Wire.read();
  return t;
}

every_30_seconds()
{
  lcd.setCursor(0,1); lcd.print("Meter:H,");
  meter0_humidity_lastvalue=readI2CRegister16bit(0x20, 0);
  lcd.print("T,");
}



It works for a few hours with reads every 30 seconds and suddenly hangs.

Maybe some other timers are required? I have this elsewhere in my code

Code: [Select]

#include <avr/sleep.h>
#include <avr/power.h>

void setup()
{
  power_adc_disable();
  power_spi_disable();
  power_timer2_disable();
  power_timer3_disable();
  power_timer4_disable();
  power_timer5_disable();
}


damago1

Ok. I have found potential place where it can be hanging. So: internally
Wire.requestFrom() calls a function twi_readFrom from the file twi.cpp. And that functions's source code is:

Code: [Select]

uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
{
  uint8_t i;

  (...) // some irrelevant code deleted here

  // wait until twi is ready, become master receiver
  while(TWI_READY != twi_state){
    continue;
  }
  twi_state = TWI_MRX;
  twi_error = 0xFF;
  twi_masterBufferIndex = 0;
  twi_masterBufferLength = length-1;  // This is not intuitive, read on...
  // On receive, the previously configured ACK/NACK setting is transmitted in
  // response to the received byte before the interrupt is signalled.
  // Therefor we must actually set NACK when the _next_ to last byte is
  // received, causing that NACK to be sent in response to receiving the last
  // expected byte of data.
  // build sla+w, slave device address + w bit
  twi_slarw = TW_READ;
  twi_slarw |= address << 1;
  // send start condition
  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);

  // wait for read operation to complete
  while(TWI_MRX == twi_state){
    continue;
  }

(...) // some irrelevant code deleted here.

  return length;
}


There are 2 potential places that the code can hang.

robtillaart


Always check the return value of   Wire.endTransmission();  // happens to be the factual sender of the datapacket

if it is not zero there is something wrong. Doing a requestFrom() after a faulty   Wire.endTransmission();  is like building on quicksand.

Yes I know, documentation is poor on this.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

pylon

Apart from what robtillaart wrote, why do you have the delay() after Wire.endTransmission() and Wire.requestFrom()? I doubt that there is a device that needs this.
You also don't test the return value of Wire.requestFrom().

And post complete code, maybe your problem is located somewhere else. If you have a standard setup (one I2C master and one or many slaves), Wire.requestFrom() almost never stays in the loop.
How is the every_30_seconds() called? I hope you don't call that in interrupt context.

Go Up