I want a deeper understanding of the Si7021's driver

I have the Si7021 temperature and pressure sensor which I want to control via one of two SoftWire I2C busses on a Pro Micro. I know there is a driver for this device although it appears to be for the hardware I2C. I studied the Si7021 spec sheet plus the commands for SoftWire. My goal is to use these commands to control the Si7021 and not use a driver. I’ll understand a lot more this way.

I did study the Adafruit driver and tried to extract the Wire commands after failing to get my code to work. I must be missing something because my code still doesn’t work.

Reference: Si7021-A20, Rev 1.2 spec sheet page 20, bottom figure.

Any help would be greatly appreciated.

Rick Sparber

Here is what I wrote:

#include <SoftWire.h>

#include <AsyncDelay.h>

int sda0Pin = 8;

int scl0Pin = 9;

int sda1Pin = 16;

int scl1Pin = 10;

SoftWire sw0(sda0Pin, scl0Pin);//define the two I2C busses

SoftWire sw1(sda1Pin, scl1Pin);

// These buffers must be at least as large as the largest read or write you perform.

char sw0TxBuffer[16];//used by SoftWire bus 0

char sw0RxBuffer[16]; //used by SoftWire bus 0

char sw1TxBuffer[16];//used by SoftWire bus 1

char sw1RxBuffer[16];//used by SoftWire bus 1

sw0.setTxBuffer(sw0TxBuffer, sizeof(sw0TxBuffer));

sw0.setRxBuffer(sw0RxBuffer, sizeof(sw0RxBuffer));

sw0.setDelay_us(5);

sw0.setTimeout(1000);

sw0.begin();

sw1.setTxBuffer(sw1TxBuffer, sizeof(sw1TxBuffer));

sw1.setRxBuffer(sw1RxBuffer, sizeof(sw1RxBuffer));

sw1.setDelay_us(5);

sw1.setTimeout(1000);

sw1.begin();

readInterval.start(2000, AsyncDelay::MILLIS);

void Si7021Driver()

{

byte Si7021AddressReadByte = 0x41;// 7 bit base address is 0x40 with the LSB = 1 for read to make 8 bits

byte Si7021AddressWriteByte = 0x40;// 7 bit base address is 0x40 with the LSB = 0 for write to make 8 bits

byte measureTempByte = 0xF3;

byte byteCountByte = 0;

unsigned long startTimeULong = millis();

const byte timedOutByte = 4;

sw0.beginTransmission(Si7021AddressWriteByte);

sw0.write(measureTempByte);

sw0.endTransmission();

delay(20);

w0.requestFrom(Si7021AddressReadByte,2);

while(1)

{//read the MS Byte and LS Byte

if(sw0.available() < 1)

{//nothing in buffer at the moment

if((millis() - startTimeULong) > 200)

{

receivedDataByte[16] = timedOutByte;

receivedDataByte[0] = 44;//make it obvious I timed out

receivedDataByte[1] = 44;

return;//give up on sensor after waiting 200 ms

}

}else //something is in the buffer

{

receivedDataByte[byteCountByte] = sw0.read();//first pass we get MS Byte; second pass we get LS Byte

byteCountByte++;//advance to second byte

}

if(byteCountByte > 1)break;//we have read the two bytes so leave while(1)

}

receivedDataByte[16] = successByte;//populate status byte

}

I was able to study the SoftWire.h and SoftWire.cpp files and gained the understanding I needed. I plan to write this up as an unofficial guide to SoftWire since I never did find an official guide. Knowing the names of the functions is inadequate for taking a spec sheet and producing its driver.

Excellent work! Feel free to share your write-up guide here when you do!

That is great news. It will need review for clarity and accuracy.

Here is my first draft of an unofficial user’s guide to SoftWire: https://rick.sparber.org/AnUnofficialSo … rGuide.pdf