Xenon cannot read the MS5803-14BA sensor

The below code compiles ok in the Particle IDE. It also runs perfectly on an Arduino Mega2560. (I just tried it again.) The xenon does not read data from the sensor. I have the appropriate pins connected to SDA and SCL, with 10k pullups to 3.3v. Same breadboard as used with the Arduino, about 4" from the Ethernet featherwing.
I have a nice scl pulse and data on the sda signal as observed on my O scope, so the sensor is sending data to the xenon. The load of my O scope lead affects the serial data showing in the particle serial monitor. With the scope lead connected to the SCL signal, it reads some data but it is very incorrect. Without the scope lead loading the SCL signal, it reads no data from the sensor. I suspect something is wrong with the timing. Any ideas on how to fix this?
The code is from the sparkfun library found on Github.

#include <Wire.h>
#include <MS5803_I2C.h>

// Begin class with selected address
// available addresses (selected by jumper on board) 
// default is ADDRESS_HIGH

//  ADDRESS_HIGH = 0x76
//  ADDRESS_LOW  = 0x77

MS5803 sensor(ADDRESS_HIGH);  

//Create variables to store results
float temperature_c, temperature_f;
double pressure_abs, pressure_relative, altitude_delta, pressure_baseline;

// Create Variable to store altitude in (m) for calculations;
double base_altitude = 1655.0; // Altitude of SparkFun's HQ in Boulder, CO. in (m)

void setup() {
    Serial.begin(9600);
    //Retrieve calibration constants for conversion math.
    sensor.reset();
    sensor.begin();
    
    pressure_baseline = sensor.getPressure(ADC_4096);
    
}

void loop() {
  
  // To measure to higher degrees of precision use the following sensor settings:
  // ADC_256 
  // ADC_512 
  // ADC_1024
  // ADC_2048
  // ADC_4096
    
  // Read temperature from the sensor in deg C. This operation takes about 
  temperature_c = sensor.getTemperature(CELSIUS, ADC_512);
  
  // Read temperature from the sensor in deg F. Converting
  // to Fahrenheit is not internal to the sensor.
  // Additional math is done to convert a Celsius reading.
  temperature_f = sensor.getTemperature(FAHRENHEIT, ADC_512);
  
  // Read pressure from the sensor in mbar.
  pressure_abs = sensor.getPressure(ADC_4096);
  
  // Let's do something interesting with our data.
  
  // Convert abs pressure with the help of altitude into relative pressure
  // This is used in Weather stations.
  pressure_relative = sealevel(pressure_abs, base_altitude);
  
  // Taking our baseline pressure at the beginning we can find an approximate
  // change in altitude based on the differences in pressure.   
  altitude_delta = altitude(pressure_abs , pressure_baseline);
  
  // Report values via UART
  Serial.print("Temperature C = ");
  Serial.println(temperature_c);
  
  Serial.print("Temperature F = ");
  Serial.println(temperature_f);
  
  Serial.print("Pressure abs (mbar)= ");
  Serial.println(pressure_abs);
   
  Serial.print("Pressure relative (mbar)= ");
  Serial.println(pressure_relative); 
  
  Serial.print("Altitude change (m) = ");
  Serial.println(altitude_delta); 


  delay(1000);

  }
  
  
// Thanks to Mike Grusin for letting me borrow the functions below from 
// the BMP180 example code. 

 double sealevel(double P, double A)
// Given a pressure P (mbar) taken at a specific altitude (meters),
// return the equivalent pressure (mbar) at sea level.
// This produces pressure readings that can be used for weather measurements.
{
	return(P/pow(1-(A/44330.0),5.255));
}


double altitude(double P, double P0)
// Given a pressure measurement P (mbar) and the pressure at a baseline P0 (mbar),
// return altitude (meters) above baseline.
{
	return(44330.0*(1-pow(P/P0,1/5.255)));
}

Powering the xenon off and on, and leaving the probe on the SCL signal now gives me accurate data from the sensor. I will try different value pull up resistors for the I2c communications to see if this makes a difference. (Tomorrow).

Try some stronger pull-ups (4k7 or 2k2).

That was my plan when I quit last night. However, I found this morning that decreasing the resistance only made it worse. I tried 4.7k and 2.2k. No help.
First, I will say that a 10k resistor pullup on the SDA works fine under all combinations of what I do with the SCL signal. However...
Through testing this morning, I found that I could get good readings if I had only my scope probe hanging on the SCL signal (even with the 10k scope probe disconnected from the Oscope!).
So, I set about to try to duplicate what the Oscope is (with my limited test equipment). I tried higher resistances...20k, 30k, 50k and 100k. Still no good readings. Then I began adding various capacitors to the circuit, knowing that the scope lead has capacitance issues, because we tune the probe impedance with a variable cap in the probes. What I found works is an interesting circuit. Connected to the SCL signal is a 50k resistor, in series with a 100k resistor, connected to the 3.3v. Also, connected to the junction of the two resistances is a 1 nf ceramic cap which is connected to ground. This RC network shapes the SCL similar to what the Oscope probe does, and I get good readings from the pressure sensor.

Obviously, this is not a good fix. It is a work-around for a problem that exists somewhere in the Xenon interface...either hardware or software. This I2c code works fine with the Arduino Mega and the MS5803 pressure sensor, with 10k pullups in the i2c interface.
Could someone explore a good fix?

I am wondering what is going to be done with this issue. Will it just fall off the radar? Should I bring it to one of the Particle support guys directly? I recall a couple of others having basically the same problem and I am not aware that the issue has been fixed.

The MS5803 is an important sensor for many applications and it works well with Arduino platforms.

Can someone give me some direction?

Hi @TomEldredge

It sounds like you have an electrical or speed problem with this sensor. One of the many differences between Particle devices and typical Arduino devices is that Particle devices have hardware i2c interfaces that are fast relative to slower software emulation of i2c used on many Arduino devices.

I believe from looking at the sensor datasheet that it has a small micro-controller inside acting as the i2c slave and that typically means it runs more slowly.

I would switch to 4.7k pullups and try doing Wire.setSpeed(20000); to set the i2c speed down from the default 100kHz to 20kHz in setup. You will have to arrange for this to be called before the sensor library calls Wire.begin();

1 Like

Thank you. I;ll give it a try.

Hi bko,
I found where I could enter the line of code you suggested in the MS5803_I2c.ccp library, but how can I add the code? The particle IDE will not let me change the code. It does not respond to my keyboard. I guess this makes sense. People like me would surely mess it up.
You said,

Now I see why you said I'd have to "arrange" for this to be called...
How do I make such an arrangement?

I would use the “circle-plus” at the top of the web IDE to add new .h/.cpp files and cut and paste the library files into there so you can modify them.

I would just start with a new sketch (.ino) and copy your code into that too so you don’t drag the old library into the problem again.

1 Like

Sorry, bko, I don’t understand. I selected the circle plus icon, but don’t see how this enables me to add new .h/.cpp files.

The circle-plus at the top creates new “tabs” in the web IDE. When you click the circle-plus on the far right (circled), it creates the new tabs for lib1.cpp and lib1.h (also circled).

1 Like

thank you bko. I’ll try to proceed. I will try a little while, but will soon quit until Monday.

Thanks again for clarifying the next step!

Tom

The problem is that most libraries are not supplied/maintained by Particle but were contributed by individuals. Quite often once done so, the libraries get abandoned by their original contributors as they move on to different projects but still own sole access for updates on these libraries.
Consequently you'd need to file an issue on the contributors GitHub repository (if there is one).
In this case you are in luck and can file one here and maybe also ping @hl68fx direct

1 Like

Thank you ScruffR,
I will post my issue on his Github forum after I try his particular library, if it does not fix the problem. I will also try modifying the .ccp file per bko’s advice.

Thanks again,
Tom

Hi bko, I think I tried what you suggested. I am including a screenshot of the changed .ccp library. The code compiles, and I changed the pullup to 4.7k, but the data being read is erroneous. I also tried solutions I found posted in the past (you can see my commented out lines below your suggestion. Any other ideas?

Hi @TomEldredge

Let’s go back to some basics then.

  • How long are the wires you are using for SCL and SDA?
  • What else is going on around the parts and wiring? Any sources of large electrical noise such as a big motor or similar?
  • Can you show us a picture of your wiring? How is ground connected between the sensor and the Xenon? How is power connected?

Thank you for responding. I estimate my wires are ~ 10" long total. Nothing that would cause interference is nearby. Picture attached.
Remember, it works with my RC network, or with the scope lead connected to the SCL signal

IMG_2704 with a 4.7 k pullup.

IMG_2711

Thank you for thinking about this with me.
Power from the xenon featherwing is attached to the power connections on the breadboard.

I plan to stick with this project this afternoon for the next four hours, so any help at this time would be appreciated. I’m just not sure what to do next.

I had our company’s best programmer look at my modifications to the header file and the .cpp file, and he thought I did what you suggested. The code compiled and loaded well too. I can clearly see the data communications with the oscope, and with your modification to the speed, I can tell that the frequency of the transmissions is lower, but the SCL pulse width is the same. The scope is set at 5 us/second.

I take that back about the frequency (how often it sends a burst of data). It appears the same, and the negative pulse is still aroung ~5 us /second with or without the code change.

The “Wire.setSpeed(20000);” statement does not seem to make any difference in the SCL pulse. Even if I set it to “Wire.setSpeed(200);” Maybe it needs to be placed somewhere else in the .ccp file?