Library to read/write Sensirion SF04 based gas/liquid flow sensors.
Dependents: TestBenchSerenity-proto_F429ZI TestBenchFlow HSPFLOW1 TestBenchFlow1 ... more
sensirion_sf04.h@7:0c1bbd80bec3, 2021-09-16 (annotated)
- Committer:
- dmwahl
- Date:
- Thu Sep 16 20:46:51 2021 +0000
- Revision:
- 7:0c1bbd80bec3
- Parent:
- 4:edf2c4870bbf
Added static_cast<char>(____) to line 188 of sensirion_sf04.cpp
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dmwahl | 1:e2ad8ac3cdb7 | 1 | /// Start of sample code-------------------------------------------------------- |
dmwahl | 1:e2ad8ac3cdb7 | 2 | /* |
dmwahl | 1:e2ad8ac3cdb7 | 3 | #include "mbed.h" |
dmwahl | 1:e2ad8ac3cdb7 | 4 | #include "sensirion_sf04.h" |
dmwahl | 1:e2ad8ac3cdb7 | 5 | |
dmwahl | 1:e2ad8ac3cdb7 | 6 | #define SFM7033_ADDR 0x40 |
dmwahl | 1:e2ad8ac3cdb7 | 7 | |
dmwahl | 1:e2ad8ac3cdb7 | 8 | // an I2C sub-class that provides a constructed default |
dmwahl | 1:e2ad8ac3cdb7 | 9 | class I2CPreInit : public I2C |
dmwahl | 1:e2ad8ac3cdb7 | 10 | { |
dmwahl | 1:e2ad8ac3cdb7 | 11 | public: |
dmwahl | 1:e2ad8ac3cdb7 | 12 | I2CPreInit(PinName sda, PinName scl, int freq) : I2C(sda, scl) { |
dmwahl | 1:e2ad8ac3cdb7 | 13 | frequency(freq); |
dmwahl | 1:e2ad8ac3cdb7 | 14 | //start(); |
dmwahl | 1:e2ad8ac3cdb7 | 15 | }; |
dmwahl | 1:e2ad8ac3cdb7 | 16 | }; |
dmwahl | 1:e2ad8ac3cdb7 | 17 | |
dmwahl | 1:e2ad8ac3cdb7 | 18 | //I2CPreInit gI2C1(I2C_SDA, I2C_SCL, I2C frequency); |
dmwahl | 2:67b7c9defdfc | 19 | //I2CPreInit gI2C1(PB_9, PB_8, 100000); |
dmwahl | 2:67b7c9defdfc | 20 | I2CPreInit gI2C2(PB_3, PB_10, 100000); |
dmwahl | 1:e2ad8ac3cdb7 | 21 | //I2CPreInit gI2C3(PB_4, PA_8); |
dmwahl | 1:e2ad8ac3cdb7 | 22 | |
dmwahl | 2:67b7c9defdfc | 23 | // (I2C object, address, cal field(0-4), resolution(9-16bit)) |
dmwahl | 2:67b7c9defdfc | 24 | SF04 sfm(gI2C2, SFM7033_ADDR, 0, 16); |
dmwahl | 2:67b7c9defdfc | 25 | |
dmwahl | 1:e2ad8ac3cdb7 | 26 | DigitalOut myled(LED1); |
dmwahl | 1:e2ad8ac3cdb7 | 27 | Serial pc(SERIAL_TX, SERIAL_RX); |
dmwahl | 1:e2ad8ac3cdb7 | 28 | |
dmwahl | 1:e2ad8ac3cdb7 | 29 | int main() |
dmwahl | 1:e2ad8ac3cdb7 | 30 | { |
dmwahl | 1:e2ad8ac3cdb7 | 31 | pc.baud(250000); |
dmwahl | 1:e2ad8ac3cdb7 | 32 | pc.printf("Starting up...\n\r"); |
dmwahl | 1:e2ad8ac3cdb7 | 33 | |
dmwahl | 2:67b7c9defdfc | 34 | pc.printf("SN: %u Scale: %d Unit:%s\n\r", sfm.serialNumber.u32, sfm.scaleFactor.u16, sfm.flowUnitStr); |
dmwahl | 1:e2ad8ac3cdb7 | 35 | |
dmwahl | 2:67b7c9defdfc | 36 | //wait(3); |
dmwahl | 1:e2ad8ac3cdb7 | 37 | while (1) { |
dmwahl | 1:e2ad8ac3cdb7 | 38 | myled = !myled; |
dmwahl | 1:e2ad8ac3cdb7 | 39 | wait(1.0); |
dmwahl | 1:e2ad8ac3cdb7 | 40 | |
dmwahl | 1:e2ad8ac3cdb7 | 41 | sfm.Measure(FLOW); |
dmwahl | 1:e2ad8ac3cdb7 | 42 | sfm.Measure(TEMP); |
dmwahl | 1:e2ad8ac3cdb7 | 43 | sfm.Measure(VDD); |
dmwahl | 3:2d43f6ceeca9 | 44 | pc.printf("%.0f %s (raw: %u) Temp: %.1fC Vdd: %.2f\n\r", ((float)sfm.flow.i16 / sfm.scaleFactor.u16), sfm.flowUnitStr, sfm.flow.u16, (float)sfm.temperature.i16/10, (float)sfm.vdd.u16/1000); |
dmwahl | 1:e2ad8ac3cdb7 | 45 | } |
dmwahl | 1:e2ad8ac3cdb7 | 46 | } |
dmwahl | 1:e2ad8ac3cdb7 | 47 | */ |
dmwahl | 1:e2ad8ac3cdb7 | 48 | /// End sample code------------------------------------------------------------- |
dmwahl | 0:9e74b14299fd | 49 | #ifndef SENSIRION_SF04_H |
dmwahl | 0:9e74b14299fd | 50 | #define SENSIRION_SF04_H |
dmwahl | 0:9e74b14299fd | 51 | |
dmwahl | 0:9e74b14299fd | 52 | #include "mbed.h" |
dmwahl | 0:9e74b14299fd | 53 | #include "sensirion_sf04_typedefs.h" |
dmwahl | 0:9e74b14299fd | 54 | |
dmwahl | 0:9e74b14299fd | 55 | #define I2C_READ 1 |
dmwahl | 0:9e74b14299fd | 56 | #define I2C_WRITE 0 |
dmwahl | 0:9e74b14299fd | 57 | |
dmwahl | 0:9e74b14299fd | 58 | //---------- Defines ----------------------------------------------------------- |
dmwahl | 0:9e74b14299fd | 59 | // CRC |
dmwahl | 0:9e74b14299fd | 60 | #define SF04_POLYNOMIAL 0x131 //P(x)=x^8+x^5+x^4+1 = 100110001 |
dmwahl | 0:9e74b14299fd | 61 | |
dmwahl | 0:9e74b14299fd | 62 | // SF04 eeprom map |
dmwahl | 0:9e74b14299fd | 63 | #define SF04_EE_ADR_SN_CHIP 0x02E4 |
dmwahl | 0:9e74b14299fd | 64 | #define SF04_EE_ADR_SN_PRODUCT 0x02F8 |
dmwahl | 0:9e74b14299fd | 65 | #define SF04_EE_ADR_SCALE_FACTOR 0x02B6 |
dmwahl | 0:9e74b14299fd | 66 | #define SF04_EE_ADR_FLOW_UNIT 0x02B7 |
dmwahl | 0:9e74b14299fd | 67 | |
dmwahl | 0:9e74b14299fd | 68 | // sensor command |
dmwahl | 0:9e74b14299fd | 69 | typedef enum { |
dmwahl | 0:9e74b14299fd | 70 | SF04_USER_REG_W = 0xE2, // command writing user register |
dmwahl | 0:9e74b14299fd | 71 | SF04_USER_REG_R = 0xE3, // command reading user register |
dmwahl | 0:9e74b14299fd | 72 | SF04_ADV_USER_REG_W = 0xE4, // command writing advanced user register |
dmwahl | 0:9e74b14299fd | 73 | SF04_ADV_USER_REG_R = 0xE5, // command reading advanced user register |
dmwahl | 0:9e74b14299fd | 74 | SF04_READ_ONLY_REG1_R = 0xE7, // command reading read-only register 1 |
dmwahl | 0:9e74b14299fd | 75 | SF04_READ_ONLY_REG2_R = 0xE9, // command reading read-only register 2 |
dmwahl | 0:9e74b14299fd | 76 | SF04_TRIGGER_FLOW_MEASUREMENT = 0xF1, // command trig. a flow measurement |
dmwahl | 0:9e74b14299fd | 77 | SF04_TRIGGER_TEMP_MEASUREMENT = 0xF3, // command trig. a temperature measurement |
dmwahl | 0:9e74b14299fd | 78 | SF04_TRIGGER_VDD_MEASUREMENT = 0xF5, // command trig. a supply voltage measurement |
dmwahl | 0:9e74b14299fd | 79 | SF04_EEPROM_W = 0xFA, // command writing eeprom |
dmwahl | 0:9e74b14299fd | 80 | SF04_EEPROM_R = 0xFA, // command reading eeprom |
dmwahl | 0:9e74b14299fd | 81 | SF04_SOFT_RESET = 0xFE // command soft reset |
dmwahl | 0:9e74b14299fd | 82 | } etCommand; |
dmwahl | 0:9e74b14299fd | 83 | |
dmwahl | 0:9e74b14299fd | 84 | // sensor register |
dmwahl | 0:9e74b14299fd | 85 | typedef enum { |
dmwahl | 0:9e74b14299fd | 86 | SF04_USER_REG = SF04_USER_REG_R, |
dmwahl | 0:9e74b14299fd | 87 | SF04_ADV_USER_REG = SF04_ADV_USER_REG_R, |
dmwahl | 0:9e74b14299fd | 88 | SF04_READ_ONLY_REG1 = SF04_READ_ONLY_REG1_R, |
dmwahl | 0:9e74b14299fd | 89 | SF04_READ_ONLY_REG2 = SF04_READ_ONLY_REG2_R |
dmwahl | 0:9e74b14299fd | 90 | } etSF04Register; |
dmwahl | 0:9e74b14299fd | 91 | |
dmwahl | 0:9e74b14299fd | 92 | // measurement signal selection |
dmwahl | 0:9e74b14299fd | 93 | typedef enum { |
dmwahl | 0:9e74b14299fd | 94 | FLOW = SF04_TRIGGER_FLOW_MEASUREMENT, |
dmwahl | 0:9e74b14299fd | 95 | TEMP = SF04_TRIGGER_TEMP_MEASUREMENT, |
dmwahl | 0:9e74b14299fd | 96 | VDD = SF04_TRIGGER_VDD_MEASUREMENT, |
dmwahl | 0:9e74b14299fd | 97 | } etSF04MeasureType; |
dmwahl | 0:9e74b14299fd | 98 | |
dmwahl | 0:9e74b14299fd | 99 | // This enum lists all available flow resolution (Advanced User Register [11:9]) |
dmwahl | 0:9e74b14299fd | 100 | typedef enum { |
dmwahl | 0:9e74b14299fd | 101 | eSF04_RES_9BIT = ( 0<<9 ), |
dmwahl | 0:9e74b14299fd | 102 | eSF04_RES_10BIT = ( 1<<9 ), |
dmwahl | 0:9e74b14299fd | 103 | eSF04_RES_11BIT = ( 2<<9 ), |
dmwahl | 0:9e74b14299fd | 104 | eSF04_RES_12BIT = ( 3<<9 ), |
dmwahl | 0:9e74b14299fd | 105 | eSF04_RES_13BIT = ( 4<<9 ), |
dmwahl | 0:9e74b14299fd | 106 | eSF04_RES_14BIT = ( 5<<9 ), |
dmwahl | 0:9e74b14299fd | 107 | eSF04_RES_15BIT = ( 6<<9 ), |
dmwahl | 0:9e74b14299fd | 108 | eSF04_RES_16BIT = ( 7<<9 ), |
dmwahl | 0:9e74b14299fd | 109 | eSF04_RES_MASK = ( 7<<9 ) // (0x0E00) |
dmwahl | 0:9e74b14299fd | 110 | } etSF04Resolution; |
dmwahl | 0:9e74b14299fd | 111 | |
dmwahl | 0:9e74b14299fd | 112 | // Error codes |
dmwahl | 0:9e74b14299fd | 113 | typedef enum { |
dmwahl | 0:9e74b14299fd | 114 | SF04_ACK_ERROR = 0x01, |
dmwahl | 0:9e74b14299fd | 115 | SF04_TIME_OUT_ERROR = 0x02, |
dmwahl | 0:9e74b14299fd | 116 | SF04_CHECKSUM_ERROR = 0x04, |
dmwahl | 0:9e74b14299fd | 117 | SF04_UNIT_ERROR = 0x08 |
dmwahl | 0:9e74b14299fd | 118 | } etError; |
dmwahl | 0:9e74b14299fd | 119 | |
dmwahl | 0:9e74b14299fd | 120 | // Calibration fields for different gases |
dmwahl | 0:9e74b14299fd | 121 | typedef enum { |
dmwahl | 0:9e74b14299fd | 122 | eSF04_CF0_AIR = 0x0A00, |
dmwahl | 0:9e74b14299fd | 123 | eSF04_CF1_O2 = 0x0A10, |
dmwahl | 0:9e74b14299fd | 124 | eSF04_CF2_N2O = 0x0A20, |
dmwahl | 0:9e74b14299fd | 125 | eSF04_CF3_O2 = 0x0A30, // Only for concentration measurement |
dmwahl | 0:9e74b14299fd | 126 | eSF04_CF4_N2O = 0x0A40, // Only for concentration measurement |
dmwahl | 0:9e74b14299fd | 127 | eSF04_CFRAW = 0x0880, // Only for concentration measurement |
dmwahl | 2:67b7c9defdfc | 128 | eSF04_CF_MASK = 0x70 |
dmwahl | 0:9e74b14299fd | 129 | } etSF04Calibration; |
dmwahl | 0:9e74b14299fd | 130 | |
dmwahl | 0:9e74b14299fd | 131 | // Macro that returns number of elements in an array |
dmwahl | 0:9e74b14299fd | 132 | #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) |
dmwahl | 0:9e74b14299fd | 133 | |
dmwahl | 0:9e74b14299fd | 134 | class SF04 |
dmwahl | 0:9e74b14299fd | 135 | { |
dmwahl | 0:9e74b14299fd | 136 | protected: |
dmwahl | 0:9e74b14299fd | 137 | I2C &i2c; |
dmwahl | 0:9e74b14299fd | 138 | u8t mi2cAddress; // 7-bit I2C address shifted left 1 bit |
dmwahl | 0:9e74b14299fd | 139 | |
dmwahl | 0:9e74b14299fd | 140 | u8t checkCRC(u8t data[], u8t numBytes, u8t checksum); // return true if checksum is good, else return false |
dmwahl | 0:9e74b14299fd | 141 | |
dmwahl | 0:9e74b14299fd | 142 | u8t ReadRegister(etSF04Register eSF04Register, nt16 *pRegisterValue); |
dmwahl | 0:9e74b14299fd | 143 | u8t WriteRegister(etSF04Register eSF04Register, nt16 *pRegisterValue); |
dmwahl | 0:9e74b14299fd | 144 | u8t ReadEeprom(u16t eepromStartAdr, u16t size, nt16 eepromData[]); |
dmwahl | 0:9e74b14299fd | 145 | u8t ReadSerialNumber(nt32 *serialNumber); |
dmwahl | 0:9e74b14299fd | 146 | u8t ReadScaleFactor(nt16 *scaleFactor); |
dmwahl | 0:9e74b14299fd | 147 | u8t ReadFlowUnit(char *flowUnitStr); |
dmwahl | 2:67b7c9defdfc | 148 | u8t setTempVddCorrectionBit(u8t value); |
dmwahl | 0:9e74b14299fd | 149 | |
dmwahl | 0:9e74b14299fd | 150 | |
dmwahl | 0:9e74b14299fd | 151 | public: |
dmwahl | 2:67b7c9defdfc | 152 | SF04(I2C &i2c, int addr, int calField, int resolution); |
dmwahl | 2:67b7c9defdfc | 153 | bool softReset(); // Reset sensor. Return true if slave sends ACK, false if not. |
dmwahl | 2:67b7c9defdfc | 154 | |
dmwahl | 2:67b7c9defdfc | 155 | u8t setMeasResolution(u16t resolution); // Set measurement resolution from 9-16 bits |
dmwahl | 2:67b7c9defdfc | 156 | u8t setCalibrationField(u8t calfield); // Set active calibration field |
dmwahl | 2:67b7c9defdfc | 157 | |
dmwahl | 0:9e74b14299fd | 158 | nt32 serialNumber; |
dmwahl | 0:9e74b14299fd | 159 | nt16 scaleFactor; |
dmwahl | 0:9e74b14299fd | 160 | char flowUnitStr[15]; //string for the flow unit |
dmwahl | 2:67b7c9defdfc | 161 | |
dmwahl | 2:67b7c9defdfc | 162 | // Measure FLOW, TEMP, or VDD |
dmwahl | 0:9e74b14299fd | 163 | u8t Measure(etSF04MeasureType eSF04MeasureType); |
dmwahl | 0:9e74b14299fd | 164 | nt16 flow, temperature, vdd, status, checksum; // raw readings |
dmwahl | 4:edf2c4870bbf | 165 | |
dmwahl | 4:edf2c4870bbf | 166 | bool ready; // signal whether or not an operation is in progress |
dmwahl | 0:9e74b14299fd | 167 | }; |
dmwahl | 0:9e74b14299fd | 168 | |
dmwahl | 0:9e74b14299fd | 169 | #endif |