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
}