*Solved* Send/Receive I2C Question

Hi all,

These may be dumb questions but I appreciate the guidance. Feel free to suggest any reading/resources to help me learn more. I am attempting to incorporate an I2C sensor into an Photon/Electron project and ran into a couple things I’m unfamiliar with. I’ve been unable to find resources on it.

1- When using the Arduino IDE serial monitor I am able to communicate with the sensor using the data sheet examples and receive successful results. When using the Particle IDE serial monitor the sensor fails to recognize the command.

2- Part of the loop is to put I2C sensor to sleep after it takes the reading. Using the below code the 'Sleep" command fails to be recognised by the sensor. Again using the Arduino monitor it successfully enters sleep mode but in the below example and, as mentioned, the Particle IDE it fails. The sensor does successfully read ‘r’ command and send data.

Wire.beginTransmission(address);   //enable I2C port.
Wire.write('r');        //transmit the command that was sent through the serial port.
Wire.endTransmission();          //end the I2C data transmission.

delay(900);                    //wait the correct amount of time for the circuit to complete its instruction.

Wire.requestFrom(address, 20, 1); //call the circuit and request 20 bytes (this may be more than we need)
code = Wire.read();             //the first byte is the response code, we read this separately.

    switch (code) {                 //switch case based on what the response code is.
  case 1:                       //decimal 1.
    Serial.println("Success");  //means the command was successful.
    break;                        //exits the switch case.

  case 2:                        //decimal 2.
    Serial.println("Failed");    //means the command has failed.
    break;                         //exits the switch case.

  case 254:                      //decimal 254.
    Serial.println("Pending");   //means the command has not yet been finished calculating.
    break;                         //exits the switch case.

  case 255:                      //decimal 255.
    Serial.println("No Data");   //means there is no further data to send.
    break;                       //exits the switch case.
}

while (Wire.available()) {         //are there bytes to receive.
  in_char = Wire.read();           //receive a byte.
  sen_data[i] = in_char;            //load this byte into our array.
  i += 1;                          //incur the counter for the array element.
  if (in_char == 0) {              //if we see that we have been sent a null command.
    i = 0;                         //reset the counter i to 0.
    Wire.endTransmission();        //end the I2C data transmission.
    break;                         //exit the while loop.
  }
}

sen_float=atof(sen_data);

delay(200);

Wire.beginTransmission(address);
Wire.write('sleep');
Wire.endTransmission();
  1. I am attempting to send a changing floating number to the sensor to compensate its output. I will be honest I have tried multiple attempts at what this should look like but have come up empty. The data sheet specifies this syntax T,n n = any value; floating point or int

    Wire.beginTransmission(address);
    Wire.write(‘T’,); //unsure how this should work and why
    Wire.endTransmission();

@canada7764 We can’t really help you unless you at least tell us the model name of the sensor.

  • Your example looks a little odd in that you send the letter “r” and then wait 900ms. That’s a VERY long time for a microcontroller to do nothing.
  • An I2C command MAY be just an “r” but it’s likely to be more (the datasheet will tell you this).
  • You have a Wire.endTransmission() in your while-loop despite not sending anything
  • At the end you have Wire.endTransmission(address); <- you shouldn’t have “address” here

I would suggest that you start by checking your code against the official Particle documentation https://docs.particle.io/reference/firmware/photon/#wire-i2c- Make sure you’re calling Wire.begin() somewhere at the start of your code. You will probably not need to use setSpeed or stretchClock, so ignore these. To understand how the Wire.available command should work, just read the docs for it https://docs.particle.io/reference/firmware/photon/#available--2

J

1 Like

In addition to the good advice you got above, I will just point out that i2c on Arduino typically does not require pull-up resistors where on Particle devices, pull-up resistors are always required. If you don’t have them add 4.7k ohm resistors from each line to 3.3V. If you don’t have that exact value, anything between about 1k and 10k ohms should work for testing.

Thanks all,

Assuming almost everything in my first post is accurate and I’ve the read Particle’s doc resources before posting I still have not found any solutions.

Wire.endTransmission in loop is from the mfg example code. Have not tried editing that code.

The last endTransmission(address) was my fault from the copy/pasting to forum and is not in the code. Thanks

Data Sheet Link

As per data sheet 4.7k are in. Thanks

OK, I read the data sheet and have some questions:

Is your sensor in “blue” LED mode? Does the LED change to green when you try your command?

According the data sheet, 4.7k ohm external resistors are needed–they are not on the sensor board it self. Hope you have those.

Did you set the i2c address to 99. (0x63) as in the examples? Whatever you set via the UART command is what you should be using.

It is pretty clear that the sensor has a processor that using some kind of soft-i2c mode. The Particle devices have hardware i2c and programming in these delays is very unusual–normally the slave just holds off the master until it is ready. You may end up having to use a soft-i2c implementation on Particle to match, but I’m not sure there is one right now (since no one else really needs it).

Thanks for taking the time to read that @bko!

Correct everything is implemented as per the data sheet. It will report the data and has been for hours running the above code. The problem arises in the sleep command and particle ide.

It will make the appropriate LED indications including RED when the particle sends the ‘sleep’ command and returns ‘failed’ (in particle IDE only)

Interesting, so software on the sensor board that imitates real I2C. Could you point me to more info about soft I2C?

Again thanks for taking the time, I initially thought it may be a setting or some return to follow the command.

Have you checked out this thread on these PH sensors?

@canada7764 I think the example does not really mean that you should wait 900ms. The datasheet tells that reading the sensor will return 254 if no new conversion is ready. It’s better to have your code check the return on a more regular basis (looping) and rather determine what to do based on that return value?

if( returnedValue == 255 ){
    // we're done converting or idle, start new conversion here
} else if( returnedValue == 2 ){
    // something went wrong, handle it here
} else if( returnedValue == 1 ){
    // We got the data, so parse it out here
} else {
    // Should only happen for return code 254
    return;
}

By doing this instead, your Particle can do other things while waiting.

Keep in mind that you could also use Serial communication on any Particle pin using the “ParticleSoftSerial” library, so if I2C poses a problem, that’s a good solution.

Thanks again @RWB I have read that and they seem to be able to do the same as I but no mention of using any command other than ‘r’. Maybe they ran into the same communication problem as I. I did calibrate off the Photon/Arduino serial monitor where I believe he used an Uno. What are your goals on the water purifier?

Thank you @jenschr for taking the time. I will be sure to change those, great suggestion BTW , down the road . I don’t know tho if that could be the cause. The Photon sends the ‘r’, EZO flashes cyan and returns accurate data. The Photon sends ‘sleep’ and the ezo flashes red. I’d like to keep I2C for future expansion.
My Current Dashboard

Thanks guys, I am a commercial pilot by trade but have always been fascinated with manufacturing. I’m under 35 so I was caught off guard when I could no longer fly, I love flying, so I have been diving head deep trying to find a new education/career path… This community has had a part in motivating me to learn something new and go back to school. Any positive critique, comments and guidance are appreciated. I’m always looking for recommendations on books/videos/anything to help. I don’t really read novels after years of systems manuals and regulations :smile:

Hehe. I guess this is a book we all should read https://www.elsevier.com/books/if-i-only-changed-the-software-why-is-the-phone-on-fire-embedded-debugging-methods-revealed/simone/978-0-7506-8218-3 :wink:

If I were you I’d just communicate via serial for now and rather revisit this once you run out of pins. If you’re thinking about making a product, you could also use the P1 module that has many more usable I/O pins.

Cool! I knew nothing about microcontrollers 2 years ago but decided to dive in after wanting the ability to build better and more sophisticated products than what I currently was able to do. After much help from the forum and lots of trial and error, I have come a long way and feel really good about what I’m able to accomplish on my own now. Still, this forum and the people willing to help out is what makes the Particle platform so valuable.

There is tons of opportunity now and in the future for connected devices and electronics in general so this is a skill set that has the potential to provide you with some revenue.

I’ve learned tons by just buying all the sensors I could find that looked interesting and just getting them up and working by their self and together with other sensors at the same time.

Having a project you want to build and deciding to dive in is a great way to learn.

The only electronics book I actually read was for how to work with XBee radios, all the other learning was from the forums and Adafruit & Sparkfun sensor setup tutorials. Adafruit and their tutorials really got me started successfully and gave me confidence that I could do this and then I received my first Spark Core which was a frustrating experience mostly but the Photon more than made up for that with its stability over the long term.

Keep with it and just look for ways to actually put this stuff to use in a way that can cover the bills :smile:

1 Like

@RWB EXACTLY! And the best learning experiences have come from not having the answer on a golden platter. Also when you think it’s a fail and you’re ready to take the advice of others @jenschr and start over (go serial) it comes to you. Anyway solved my I2C problem.

Thanks again all

        Wire.beginTransmission(phaddress);
        Wire.write("sleep");
        Wire.endTransmission();

2 Likes