I2C wire methods crashing Spark Core

I am not sure i selected the right category but i trying to get my Spark Core to work with a I2C sensor and using Wire methods.

But when i trying to get values the Spark Core crashing and reboots.

I using codes that i finding in this community forum and on github and other places tried many diffferent examples but all do the same.

Is there a isssue with Wire and Spark Core?

One of the codes i tested is this code and when i call the CloudRequest function its crashing (red led and rebooting):

#define MOISTURE_SENSOR_I2C_ADDR 0x20
#define CAPACITIVE_MEAS_AVERAGING 10
#define CAPACITIVE_THRESHOLD 400
#define MAINLOOP_BASE_DELAY_MS 100
#define MOISTURE_CHECK_DELAY_MS 300000  //5 minutes

volatile unsigned long int MoistureDelayAccu=0;
volatile int LastMoistureMeasured=0;

char tmp[200];

int CloudRequest(String req);
int Capa=0;
int Moisture=0;

int getCapa(void){
  Wire.beginTransmission(MOISTURE_SENSOR_I2C_ADDR); // give address
  Wire.write(0x00);            // sends instruction byte
  Wire.endTransmission();     // stop transmitting
  Wire.requestFrom(MOISTURE_SENSOR_I2C_ADDR, 2);
  while (!Wire.available())
    delay(2);
  char a=Wire.read(); // receive a byte as character
  while (!Wire.available())
    delay(2);
  char b=Wire.read(); // receive a byte as character
  Capa=((a<<8)+b);
  return Capa;
}

int MoistureValue(void){
  int acc=0;
  getCapa();//dummy Capa read in order to finally get a current value
  for(int i=0;i<CAPACITIVE_MEAS_AVERAGING;i++)
  {
    acc+=getCapa();
  }
  acc=acc/CAPACITIVE_MEAS_AVERAGING;
  LastMoistureMeasured=acc;
  Moisture=acc;
  return Moisture;
}

bool isHungry(void){
  if(MoistureValue()<CAPACITIVE_THRESHOLD)
    return true;
  return false;
}

int CloudRequest(String req)
{
    return MoistureValue();
}

void setup() {
    Wire.begin();
    Particle.function("CloudRequest", CloudRequest);
}

void loop() {
    
}

I dont need to have the sensor connected to get the spark core to crash but maybe good.

The common first question in connection with I2C is: “Have you got your pull-up resistors in place?”

Also what red crash code do you see?

Have you got a clue which instruction in particular causes the crash?
Add some Serial.print() statements to narrow things down.

You should also avoid to call interrupt heavy functions (like the Wire calls) from within a Particle.function().

I’d rather just set a flag inside the function, deal with the flag in loop() and expose your result as Particle.variable()

Video on the red crash code if it says you anything: https://www.dropbox.com/s/jax322lt3a6fdsk/2016-05-17%2019.56.51.mp4?dl=0

The pull-up resistors are in place like on this sketch: https://raw.githubusercontent.com/yerpj/SmartWatering/master/wiring.jpg

Not my picture but from a github page i finding some code from to this i2c sensor.

If i not using function instead have it in the loop and publish i getting the same result.

I ahve not debug with serial print but going todo.

I have tried your code without a sensor and with some other I2C device since I haven’t got one of these sensors, but I don’t see a hard fault (which your red SOS indicates) but only see steady cyan which ends in white breathing and a restart.
Still not good, but different to your issue :confused:

okej, did you use a Spark Core?

Yup - one of the first white ones :wink:
Just like yours.

As a substitute for the sensor I used a SparkFun Photon IMU Shield and changed the address accordingly and now I even get a good reading from it.
No SOS and no restart.

Could you try 4k7 pull-ups instead of 10k?

The same result with 4k7 resistors instead of 10k

Now also tested one other Spark Core that get the same problem with same code.

Hmm, that’s odd :confused:
What sensor are you using exactly?
What firmware version are you targeting?
I’ve used 0.5.0 and 0.5.1-rc.1

Just wondering out loud here: Is calling delay() from within a Particle subscription handler allowed? Would delayMicroseconds(2000) be better?

https://docs.particle.io/reference/firmware/core/#delaymicroseconds-

This sensor is it i trying to get values from: https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/

But like i writen i dont need it connected to the sensor and it breaks when i calling the function.

I have firmware 0.5.0

I can test 0.5.1-rc1 and see.

It is allowed (at least in 0.4.9+) and my Core doesn’t crash with exactly that code :wink:

Only if the I2C device doesn’t return two bytes in time the while(!Wire.available()) might pose a problem, since the handler will never be leaving and subsequent calls will be eating up the stack.

Same problem with 0.5.1-rc-1 firmware

As I said, my device doesn’t like that either but doesn’t SOS but only restart.

Have you managed to locate the offending line via Serial.print()?
How are you triggering the function?
Could it be that the stack issue I pointed out above hits due to multiple calls but the function never returning?
Can you try to swap SCL/SDA round?