AMS-5812 pressure sensor family - I2C commands and lock-up?

I’m trying to use a AMS5812-001-D differential pressure sensor with an Arduino UNO over I2C. I’m using a version of the sensor that mounts to a “mini-module” (breakout board) from ControlEverything. The problem I’m having is with a distinct lack of documentation I can find. I can use an I2C scanner to detect the sensor reliably (at address 0x78), but the data sheet I can find for the sensor says very little (to me) about how to communicate with it. As best I can figure, the sensor swaps the 15-bit ADC between the pressure sensor and the temperature sensor on board, uses those values to generate corrected “raw” returns for both, and puts those into four registers (r0 = pressure MSB, r1 = pressure LSB, r2 = temperature MSB, r3 = temperature LSB). So far so good. But just sending a Wire.requestFrom(0x78, 4) results in a single valid read… I get back four bytes, and they form a physically meaningful read, but they never change. It’s like the sensor does a single read and shuts down, never making an updated reading.

Googling I did come across a single thread referencing this “lock up” problem, here on the forums… in German. And they sort of seem to have a solution… but I have NO idea why it’s working, or what it’s doing. Here’s a minimal working code that will seem to drive the sensor:

// AMS5812-0001-D Sensor minimal example

#include <Wire.h>

#define AMS5812_ADDR 0x78 // I2C address of the sensor

// the following are used for conversions... more detail than need
#define rawMax   29491
#define rawMin   3277
#define pMax    103400 
#define pMin    0 
#define tMin    -2500
#define tMax    8500

uint16_t pMSB = 0;  // Two-byte return (MSB, LSB) for pressure
uint16_t pLSB = 0;
uint16_t tMSB = 0;  // Two-byte return (MSB, LSB) for temperature
uint16_t tLSB = 0;

uint8_t add = 0;    // Here is the magic...

void setup()

void loop () 
  Wire.beginTransmission(AMS5812_ADDR); //
  Wire.write(add);                      // Don't know what this does
  Wire.endTransmission();               //
  delay(30);                            // Delay to process?
  if (Wire.available()) 
    pMSB =;
    pLSB =;
    tMSB =;
    tLSB =;
  uint16_t pRaw = constrain( ( pMSB << 8 ) + pLSB , rawMin, rawMax);
  uint16_t tRaw = constrain( ( tMSB << 8 ) + tLSB , rawMin, rawMax);

  uint32_t p1 = ( pRaw - rawMin) * (pMax-pMin);
  uint32_t p2 = ( rawMax - rawMin );
  uint32_t p3 = p1 / p2;
  uint32_t p = p3 + pMin;
  long t = map( tRaw, rawMin, rawMax, tMin, tMax);
  add++;      //
  if (add==3) // also shamelessly copied
  {           //   without this sensor seems
    add=0;    //   to lock up
  }           //

Running that while varying the pressure applied to the sensor generates an output that looks something like this:


The pressure is changing, and there’s some variation in the temperature as well. But… if you remove the chunk of code that iterates ‘add’ through 0,1,2,0,1,2,0,etc… the sensor locks up after the first read. If you remove the opening sequence of Wire.write() stuff at the start of loop()… the sensor locks up after one read. You end up with a Serial stream that looks like this:


Wire.request continues to report success grabbing 4 bytes… but it’s always the same four bytes (no matter how the pressure or temperature of the sensor is varied). If I remove the “delay to process” the sensor will sometimes lock up which I interpret as not waiting politely for the I2C exchange to take place, but the sensor will sometimes come back from that. Keeping ‘add’ at 0, or iterating it through other numbers (e.g., 0,1,2,3,4,0,1,2,3,4,etc.), or removing the initial Wire.write() command all seem to result in a sensor lock-up… one that even reseting the Arduino doesn’t seem to get it out of (only depowering the whole thing seems to reset the mess).

Ideas? Thoughts?

Q: What is that initial ‘Wire.write(add)’ doing? Just what is that supposedly telling this sensor? And why the heck does telling it the next time to send 1, and then to send 2, have a positive effect?

Am I not understanding the sensor? Or is there something I’m missing in the data speed? Or am I just clinically thick? I’ve tried the University of Google, and it led me to a confusing approach in German that still, even after translation, didn’t make sense (to me).

(Note: my 1st post here, so if I’m doing something wrong posting-wise, Please Tell Me!)

I can suggest you to try this code in arduino for AMS_5812_0050 D B .


Just replace the following formula for pressure conversion for your sensor in the above code:
pressure = ((pressure - 3277.0) / ((26214.0) / 0.15)) - 5.0;

It would then Divide it by 0.15 instead of 10 as in the code in the link because the ranges are different for the two sensors.
I think this would work. Comments are also there with which you can understand that which command is for which purpose.
Good luck!