Library to read/write Sensirion SF04 based gas/liquid flow sensors.
Dependents: TestBenchSerenity-proto_F429ZI TestBenchFlow HSPFLOW1 TestBenchFlow1 ... more
sensirion_sf04.cpp@7:0c1bbd80bec3, 2021-09-16 (annotated)
- Committer:
- dmwahl
- Date:
- Thu Sep 16 20:46:51 2021 +0000
- Revision:
- 7:0c1bbd80bec3
- Parent:
- 5:1243b362ece8
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 | 0:9e74b14299fd | 1 | #include "sensirion_sf04.h" |
dmwahl | 0:9e74b14299fd | 2 | |
dmwahl | 0:9e74b14299fd | 3 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 4 | // Default constructor |
dmwahl | 2:67b7c9defdfc | 5 | SF04::SF04(I2C &i2c, int i2cAddress, int calField, int resolution) : i2c(i2c), mi2cAddress(i2cAddress << 1) |
dmwahl | 0:9e74b14299fd | 6 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 7 | { |
dmwahl | 4:edf2c4870bbf | 8 | u8t error = false; |
dmwahl | 4:edf2c4870bbf | 9 | ready = false; |
dmwahl | 2:67b7c9defdfc | 10 | int16_t wait = 200; // Unsure why, but without a wait between commands the values read out don't make sense. |
dmwahl | 2:67b7c9defdfc | 11 | wait_us(wait); |
dmwahl | 5:1243b362ece8 | 12 | error |= softReset(); |
dmwahl | 4:edf2c4870bbf | 13 | wait_us(wait); |
dmwahl | 4:edf2c4870bbf | 14 | error |= ReadSerialNumber(&serialNumber); |
dmwahl | 2:67b7c9defdfc | 15 | wait_us(wait); |
dmwahl | 4:edf2c4870bbf | 16 | error |= ReadScaleFactor(&scaleFactor); |
dmwahl | 2:67b7c9defdfc | 17 | wait_us(wait); |
dmwahl | 4:edf2c4870bbf | 18 | error |= ReadFlowUnit(flowUnitStr); |
dmwahl | 2:67b7c9defdfc | 19 | wait_us(wait); |
dmwahl | 4:edf2c4870bbf | 20 | error |= setMeasResolution(resolution); // 9-16 bit |
dmwahl | 4:edf2c4870bbf | 21 | wait_us(wait); |
dmwahl | 4:edf2c4870bbf | 22 | error |= setCalibrationField(calField); |
dmwahl | 2:67b7c9defdfc | 23 | wait_us(wait); |
dmwahl | 4:edf2c4870bbf | 24 | |
dmwahl | 4:edf2c4870bbf | 25 | if (error == false) { |
dmwahl | 4:edf2c4870bbf | 26 | ready = true; |
dmwahl | 4:edf2c4870bbf | 27 | } |
dmwahl | 0:9e74b14299fd | 28 | } |
dmwahl | 0:9e74b14299fd | 29 | |
dmwahl | 0:9e74b14299fd | 30 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 31 | // Set measurement resolution (9-16 bit), format is eSF04_RES_12BIT |
dmwahl | 2:67b7c9defdfc | 32 | u8t SF04::setMeasResolution(u16t resolution) |
dmwahl | 0:9e74b14299fd | 33 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 34 | { |
dmwahl | 4:edf2c4870bbf | 35 | ready = false; |
dmwahl | 0:9e74b14299fd | 36 | u8t error = false; //variable for error code |
dmwahl | 0:9e74b14299fd | 37 | nt16 registerValue; // variable for register value |
dmwahl | 2:67b7c9defdfc | 38 | |
dmwahl | 2:67b7c9defdfc | 39 | switch(resolution) { |
dmwahl | 2:67b7c9defdfc | 40 | case 9 : |
dmwahl | 2:67b7c9defdfc | 41 | resolution = eSF04_RES_9BIT; |
dmwahl | 2:67b7c9defdfc | 42 | break; |
dmwahl | 2:67b7c9defdfc | 43 | case 10 : |
dmwahl | 2:67b7c9defdfc | 44 | resolution = eSF04_RES_10BIT; |
dmwahl | 2:67b7c9defdfc | 45 | break; |
dmwahl | 2:67b7c9defdfc | 46 | case 11 : |
dmwahl | 2:67b7c9defdfc | 47 | resolution = eSF04_RES_11BIT; |
dmwahl | 2:67b7c9defdfc | 48 | break; |
dmwahl | 2:67b7c9defdfc | 49 | case 12 : |
dmwahl | 2:67b7c9defdfc | 50 | resolution = eSF04_RES_12BIT; |
dmwahl | 2:67b7c9defdfc | 51 | break; |
dmwahl | 2:67b7c9defdfc | 52 | case 13 : |
dmwahl | 2:67b7c9defdfc | 53 | resolution = eSF04_RES_13BIT; |
dmwahl | 2:67b7c9defdfc | 54 | break; |
dmwahl | 2:67b7c9defdfc | 55 | case 14 : |
dmwahl | 2:67b7c9defdfc | 56 | resolution = eSF04_RES_14BIT; |
dmwahl | 2:67b7c9defdfc | 57 | break; |
dmwahl | 2:67b7c9defdfc | 58 | case 15 : |
dmwahl | 2:67b7c9defdfc | 59 | resolution = eSF04_RES_15BIT; |
dmwahl | 2:67b7c9defdfc | 60 | break; |
dmwahl | 2:67b7c9defdfc | 61 | case 16 : |
dmwahl | 2:67b7c9defdfc | 62 | resolution = eSF04_RES_16BIT; |
dmwahl | 2:67b7c9defdfc | 63 | break; |
dmwahl | 2:67b7c9defdfc | 64 | default: |
dmwahl | 2:67b7c9defdfc | 65 | resolution = eSF04_RES_16BIT; |
dmwahl | 2:67b7c9defdfc | 66 | break; |
dmwahl | 2:67b7c9defdfc | 67 | } |
dmwahl | 0:9e74b14299fd | 68 | ReadRegister(SF04_ADV_USER_REG,®isterValue); // Read out current register value |
dmwahl | 0:9e74b14299fd | 69 | registerValue.u16 = (registerValue.u16 & ~eSF04_RES_MASK) | resolution; // Set resolution in Advanced User Register [11:9] |
dmwahl | 0:9e74b14299fd | 70 | WriteRegister(SF04_ADV_USER_REG,®isterValue); // Write out new register value |
dmwahl | 4:edf2c4870bbf | 71 | ready = true; |
dmwahl | 0:9e74b14299fd | 72 | return error; |
dmwahl | 0:9e74b14299fd | 73 | } |
dmwahl | 0:9e74b14299fd | 74 | |
dmwahl | 0:9e74b14299fd | 75 | //=========================================================================== |
dmwahl | 2:67b7c9defdfc | 76 | // Set calibration field (0-4) |
dmwahl | 2:67b7c9defdfc | 77 | u8t SF04::setCalibrationField(u8t calfield) |
dmwahl | 0:9e74b14299fd | 78 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 79 | { |
dmwahl | 4:edf2c4870bbf | 80 | ready = false; |
dmwahl | 0:9e74b14299fd | 81 | u8t error = false; //variable for error code |
dmwahl | 0:9e74b14299fd | 82 | nt16 registerValue; // variable for register value |
dmwahl | 2:67b7c9defdfc | 83 | if (calfield > 8) { |
dmwahl | 2:67b7c9defdfc | 84 | calfield = 0; |
dmwahl | 2:67b7c9defdfc | 85 | } |
dmwahl | 2:67b7c9defdfc | 86 | |
dmwahl | 0:9e74b14299fd | 87 | ReadRegister(SF04_USER_REG,®isterValue); // Read out current register value |
dmwahl | 2:67b7c9defdfc | 88 | registerValue.u16 = (registerValue.u16 & ~eSF04_CF_MASK) | (calfield << 4); // Set calibration field in User Register [6:4] |
dmwahl | 0:9e74b14299fd | 89 | WriteRegister(SF04_USER_REG,®isterValue); // Write out new register value |
dmwahl | 4:edf2c4870bbf | 90 | ready = true; |
dmwahl | 0:9e74b14299fd | 91 | return error; |
dmwahl | 0:9e74b14299fd | 92 | } |
dmwahl | 0:9e74b14299fd | 93 | |
dmwahl | 2:67b7c9defdfc | 94 | //=========================================================================== |
dmwahl | 2:67b7c9defdfc | 95 | // Enable Temperature/Vdd correction |
dmwahl | 2:67b7c9defdfc | 96 | u8t SF04::setTempVddCorrectionBit(u8t value) |
dmwahl | 2:67b7c9defdfc | 97 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 98 | { |
dmwahl | 4:edf2c4870bbf | 99 | ready = false; |
dmwahl | 4:edf2c4870bbf | 100 | |
dmwahl | 2:67b7c9defdfc | 101 | u8t error = false; //variable for error code |
dmwahl | 2:67b7c9defdfc | 102 | nt16 registerValue; // variable for register value |
dmwahl | 2:67b7c9defdfc | 103 | |
dmwahl | 2:67b7c9defdfc | 104 | if (value != 1) { |
dmwahl | 2:67b7c9defdfc | 105 | value = 0; // Ensure value is 1 or 0 |
dmwahl | 0:9e74b14299fd | 106 | } |
dmwahl | 2:67b7c9defdfc | 107 | ReadRegister(SF04_USER_REG,®isterValue); // Read out current register value |
dmwahl | 2:67b7c9defdfc | 108 | registerValue.u16 = ((registerValue.u16 & ~0x400) | (value << 10)); // Set calibration field in User Register [bit 10] |
dmwahl | 2:67b7c9defdfc | 109 | WriteRegister(SF04_USER_REG,®isterValue); // Write out new register value |
dmwahl | 2:67b7c9defdfc | 110 | |
dmwahl | 4:edf2c4870bbf | 111 | ready = true; |
dmwahl | 2:67b7c9defdfc | 112 | return error; |
dmwahl | 0:9e74b14299fd | 113 | } |
dmwahl | 0:9e74b14299fd | 114 | |
dmwahl | 0:9e74b14299fd | 115 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 116 | // Force sensor reset |
dmwahl | 0:9e74b14299fd | 117 | bool SF04::softReset() |
dmwahl | 0:9e74b14299fd | 118 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 119 | { |
dmwahl | 4:edf2c4870bbf | 120 | ready = false; |
dmwahl | 0:9e74b14299fd | 121 | char data_write = SF04_SOFT_RESET; |
dmwahl | 0:9e74b14299fd | 122 | if (i2c.write(mi2cAddress, &data_write, 1, false) == 0) { |
dmwahl | 4:edf2c4870bbf | 123 | ready = true; |
dmwahl | 0:9e74b14299fd | 124 | return true; |
dmwahl | 4:edf2c4870bbf | 125 | } else { |
dmwahl | 4:edf2c4870bbf | 126 | ready = true; |
dmwahl | 4:edf2c4870bbf | 127 | return false; |
dmwahl | 4:edf2c4870bbf | 128 | } |
dmwahl | 0:9e74b14299fd | 129 | } |
dmwahl | 0:9e74b14299fd | 130 | |
dmwahl | 0:9e74b14299fd | 131 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 132 | // Compute CRC and return true if correct and false if not |
dmwahl | 0:9e74b14299fd | 133 | u8t SF04::checkCRC(u8t data[], u8t numBytes, u8t checksum) |
dmwahl | 0:9e74b14299fd | 134 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 135 | { |
dmwahl | 0:9e74b14299fd | 136 | u8t crc = 0; |
dmwahl | 0:9e74b14299fd | 137 | u8t byteCtr; |
dmwahl | 0:9e74b14299fd | 138 | for (byteCtr = 0; byteCtr < numBytes; byteCtr++) { |
dmwahl | 0:9e74b14299fd | 139 | crc ^= (data[byteCtr]); |
dmwahl | 0:9e74b14299fd | 140 | for (u8t bit = 8; bit > 0; bit--) { |
dmwahl | 0:9e74b14299fd | 141 | if (crc & 0x80) crc = (crc << 1) ^ SF04_POLYNOMIAL; |
dmwahl | 0:9e74b14299fd | 142 | else crc = (crc << 1); |
dmwahl | 0:9e74b14299fd | 143 | } |
dmwahl | 0:9e74b14299fd | 144 | } |
dmwahl | 0:9e74b14299fd | 145 | if (crc != checksum) return SF04_CHECKSUM_ERROR; |
dmwahl | 0:9e74b14299fd | 146 | else return 0; |
dmwahl | 0:9e74b14299fd | 147 | } |
dmwahl | 0:9e74b14299fd | 148 | |
dmwahl | 0:9e74b14299fd | 149 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 150 | u8t SF04::ReadRegister(etSF04Register eSF04Register, nt16 *pRegisterValue) |
dmwahl | 0:9e74b14299fd | 151 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 152 | { |
dmwahl | 4:edf2c4870bbf | 153 | ready = false; |
dmwahl | 0:9e74b14299fd | 154 | u8t checksum; //variable for checksum byte |
dmwahl | 0:9e74b14299fd | 155 | u8t error = false; //variable for error code |
dmwahl | 2:67b7c9defdfc | 156 | |
dmwahl | 0:9e74b14299fd | 157 | char dataWrite[1] = {eSF04Register}; |
dmwahl | 0:9e74b14299fd | 158 | char dataRead[3]; |
dmwahl | 0:9e74b14299fd | 159 | u8t data[2]; //data array for checksum verification |
dmwahl | 0:9e74b14299fd | 160 | |
dmwahl | 0:9e74b14299fd | 161 | int writeAddr = (mi2cAddress | I2C_WRITE); |
dmwahl | 0:9e74b14299fd | 162 | int readAddr = (mi2cAddress | I2C_READ); |
dmwahl | 0:9e74b14299fd | 163 | |
dmwahl | 0:9e74b14299fd | 164 | i2c.write(writeAddr, dataWrite, 1, true); |
dmwahl | 0:9e74b14299fd | 165 | i2c.read(readAddr, dataRead, 3, false); |
dmwahl | 0:9e74b14299fd | 166 | checksum = dataRead[2]; |
dmwahl | 0:9e74b14299fd | 167 | data[0] = dataRead[0]; |
dmwahl | 0:9e74b14299fd | 168 | data[1] = dataRead[1]; |
dmwahl | 0:9e74b14299fd | 169 | |
dmwahl | 0:9e74b14299fd | 170 | error |= checkCRC(data,2,checksum); |
dmwahl | 0:9e74b14299fd | 171 | pRegisterValue->s16.u8H = dataRead[0]; |
dmwahl | 0:9e74b14299fd | 172 | pRegisterValue->s16.u8L = dataRead[1]; |
dmwahl | 4:edf2c4870bbf | 173 | ready = true; |
dmwahl | 0:9e74b14299fd | 174 | return error; |
dmwahl | 0:9e74b14299fd | 175 | } |
dmwahl | 0:9e74b14299fd | 176 | |
dmwahl | 0:9e74b14299fd | 177 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 178 | u8t SF04::WriteRegister(etSF04Register eSF04Register, nt16 *pRegisterValue) |
dmwahl | 0:9e74b14299fd | 179 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 180 | { |
dmwahl | 4:edf2c4870bbf | 181 | ready = false; |
dmwahl | 0:9e74b14299fd | 182 | u8t error = 1; //variable for error code |
dmwahl | 0:9e74b14299fd | 183 | //-- check if selected register is writable -- |
dmwahl | 0:9e74b14299fd | 184 | if(!(eSF04Register == SF04_READ_ONLY_REG1 || eSF04Register == SF04_READ_ONLY_REG2)) { |
dmwahl | 0:9e74b14299fd | 185 | error=0; |
dmwahl | 0:9e74b14299fd | 186 | //-- write register to sensor -- |
dmwahl | 0:9e74b14299fd | 187 | int writeAddr = (mi2cAddress | I2C_WRITE); |
dmwahl | 7:0c1bbd80bec3 | 188 | char dataWrite[3] = {static_cast<char>((eSF04Register & ~0x01 | I2C_WRITE)), pRegisterValue->s16.u8H, pRegisterValue->s16.u8L}; |
dmwahl | 0:9e74b14299fd | 189 | i2c.write(writeAddr, dataWrite, 3); |
dmwahl | 0:9e74b14299fd | 190 | } |
dmwahl | 4:edf2c4870bbf | 191 | ready = true; |
dmwahl | 0:9e74b14299fd | 192 | return error; |
dmwahl | 0:9e74b14299fd | 193 | } |
dmwahl | 0:9e74b14299fd | 194 | |
dmwahl | 0:9e74b14299fd | 195 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 196 | u8t SF04::ReadEeprom(u16t eepromStartAdr, u16t size, nt16 eepromData[]) |
dmwahl | 0:9e74b14299fd | 197 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 198 | { |
dmwahl | 4:edf2c4870bbf | 199 | ready = false; |
dmwahl | 0:9e74b14299fd | 200 | u8t checksum; //checksum |
dmwahl | 0:9e74b14299fd | 201 | u8t data[2]; //data array for checksum verification |
dmwahl | 0:9e74b14299fd | 202 | u8t error = 0; //error variable |
dmwahl | 0:9e74b14299fd | 203 | u16t i; //counting variable |
dmwahl | 0:9e74b14299fd | 204 | nt16 eepromStartAdrTmp; //variable for eeprom adr. as nt16 |
dmwahl | 0:9e74b14299fd | 205 | eepromStartAdrTmp.u16=eepromStartAdr; |
dmwahl | 0:9e74b14299fd | 206 | |
dmwahl | 0:9e74b14299fd | 207 | //-- write I2C sensor address and command -- |
dmwahl | 0:9e74b14299fd | 208 | i2c.start(); |
dmwahl | 0:9e74b14299fd | 209 | error |= i2c.write(mi2cAddress | I2C_WRITE); |
dmwahl | 0:9e74b14299fd | 210 | error |= i2c.write(SF04_EEPROM_R); |
dmwahl | 0:9e74b14299fd | 211 | |
dmwahl | 0:9e74b14299fd | 212 | eepromStartAdrTmp.u16=(eepromStartAdrTmp.u16<<4); // align eeprom adr left |
dmwahl | 0:9e74b14299fd | 213 | error |= i2c.write(eepromStartAdrTmp.s16.u8H); |
dmwahl | 0:9e74b14299fd | 214 | error |= i2c.write(eepromStartAdrTmp.s16.u8L); |
dmwahl | 0:9e74b14299fd | 215 | |
dmwahl | 0:9e74b14299fd | 216 | //-- write I2C sensor address for read -- |
dmwahl | 0:9e74b14299fd | 217 | i2c.start(); |
dmwahl | 0:9e74b14299fd | 218 | error |= i2c.write(mi2cAddress | I2C_READ); |
dmwahl | 0:9e74b14299fd | 219 | |
dmwahl | 0:9e74b14299fd | 220 | //-- read eeprom data and verify checksum -- |
dmwahl | 0:9e74b14299fd | 221 | for(i=0; i<size; i++) { |
dmwahl | 0:9e74b14299fd | 222 | eepromData[i].s16.u8H = data[0] = i2c.read(1); |
dmwahl | 0:9e74b14299fd | 223 | eepromData[i].s16.u8L = data[1] = i2c.read(1); |
dmwahl | 0:9e74b14299fd | 224 | checksum=i2c.read( (i < size-1) ? 1 : 0 ); //NACK for last byte |
dmwahl | 0:9e74b14299fd | 225 | error |= checkCRC(data,2,checksum); |
dmwahl | 0:9e74b14299fd | 226 | } |
dmwahl | 0:9e74b14299fd | 227 | i2c.stop(); |
dmwahl | 4:edf2c4870bbf | 228 | ready = true; |
dmwahl | 0:9e74b14299fd | 229 | return error; |
dmwahl | 0:9e74b14299fd | 230 | } |
dmwahl | 0:9e74b14299fd | 231 | |
dmwahl | 0:9e74b14299fd | 232 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 233 | u8t SF04::Measure(etSF04MeasureType eSF04MeasureType)//, nt16 *pMeasurement) |
dmwahl | 0:9e74b14299fd | 234 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 235 | { |
dmwahl | 4:edf2c4870bbf | 236 | ready = false; |
dmwahl | 0:9e74b14299fd | 237 | u8t checksum; //checksum |
dmwahl | 0:9e74b14299fd | 238 | u8t error=0; //error variable |
dmwahl | 0:9e74b14299fd | 239 | |
dmwahl | 0:9e74b14299fd | 240 | char dataWrite[1]; |
dmwahl | 0:9e74b14299fd | 241 | char dataRead[3]; |
dmwahl | 0:9e74b14299fd | 242 | u8t data[2]; //data array for checksum verification |
dmwahl | 2:67b7c9defdfc | 243 | |
dmwahl | 0:9e74b14299fd | 244 | nt16 *pMeasurement; |
dmwahl | 2:67b7c9defdfc | 245 | |
dmwahl | 0:9e74b14299fd | 246 | //-- write measurement command -- |
dmwahl | 0:9e74b14299fd | 247 | switch(eSF04MeasureType) { |
dmwahl | 0:9e74b14299fd | 248 | case FLOW : |
dmwahl | 0:9e74b14299fd | 249 | dataWrite[0] = SF04_TRIGGER_FLOW_MEASUREMENT; |
dmwahl | 0:9e74b14299fd | 250 | pMeasurement = &flow; |
dmwahl | 2:67b7c9defdfc | 251 | setTempVddCorrectionBit(0); |
dmwahl | 0:9e74b14299fd | 252 | break; |
dmwahl | 0:9e74b14299fd | 253 | case TEMP : |
dmwahl | 0:9e74b14299fd | 254 | dataWrite[0] = SF04_TRIGGER_TEMP_MEASUREMENT; |
dmwahl | 0:9e74b14299fd | 255 | pMeasurement = &temperature; |
dmwahl | 2:67b7c9defdfc | 256 | setTempVddCorrectionBit(1); |
dmwahl | 0:9e74b14299fd | 257 | break; |
dmwahl | 0:9e74b14299fd | 258 | case VDD : |
dmwahl | 0:9e74b14299fd | 259 | dataWrite[0] = SF04_TRIGGER_VDD_MEASUREMENT; |
dmwahl | 0:9e74b14299fd | 260 | pMeasurement = &vdd; |
dmwahl | 2:67b7c9defdfc | 261 | setTempVddCorrectionBit(1); |
dmwahl | 0:9e74b14299fd | 262 | break; |
dmwahl | 0:9e74b14299fd | 263 | default: |
dmwahl | 0:9e74b14299fd | 264 | break; |
dmwahl | 0:9e74b14299fd | 265 | } |
dmwahl | 0:9e74b14299fd | 266 | |
dmwahl | 0:9e74b14299fd | 267 | int writeAddr = (mi2cAddress | I2C_WRITE); |
dmwahl | 0:9e74b14299fd | 268 | int readAddr = (mi2cAddress | I2C_READ); |
dmwahl | 0:9e74b14299fd | 269 | |
dmwahl | 0:9e74b14299fd | 270 | i2c.write(writeAddr, dataWrite, 1, true); |
dmwahl | 0:9e74b14299fd | 271 | i2c.read(readAddr, dataRead, 3, false); |
dmwahl | 0:9e74b14299fd | 272 | checksum = dataRead[2]; |
dmwahl | 2:67b7c9defdfc | 273 | |
dmwahl | 0:9e74b14299fd | 274 | data[0] = dataRead[0]; |
dmwahl | 0:9e74b14299fd | 275 | data[1] = dataRead[1]; |
dmwahl | 2:67b7c9defdfc | 276 | |
dmwahl | 2:67b7c9defdfc | 277 | if (checkCRC(data,2,checksum) == 0) { |
dmwahl | 0:9e74b14299fd | 278 | pMeasurement->s16.u8H = dataRead[0]; |
dmwahl | 0:9e74b14299fd | 279 | pMeasurement->s16.u8L = dataRead[1]; |
dmwahl | 2:67b7c9defdfc | 280 | } else { |
dmwahl | 2:67b7c9defdfc | 281 | error |= SF04_CHECKSUM_ERROR; |
dmwahl | 0:9e74b14299fd | 282 | } |
dmwahl | 4:edf2c4870bbf | 283 | ready = true; |
dmwahl | 0:9e74b14299fd | 284 | return error; |
dmwahl | 0:9e74b14299fd | 285 | } |
dmwahl | 0:9e74b14299fd | 286 | |
dmwahl | 0:9e74b14299fd | 287 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 288 | u8t SF04::ReadSerialNumber( nt32 *serialNumber ) |
dmwahl | 0:9e74b14299fd | 289 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 290 | { |
dmwahl | 4:edf2c4870bbf | 291 | ready = false; |
dmwahl | 0:9e74b14299fd | 292 | nt16 registerValue; //register value for register |
dmwahl | 0:9e74b14299fd | 293 | u16t eepromBaseAdr; //eeprom base address of active calibration field |
dmwahl | 0:9e74b14299fd | 294 | u16t eepromAdr; //eeprom address of SF04's scale factor |
dmwahl | 0:9e74b14299fd | 295 | nt16 eepromData[2]; //serial number |
dmwahl | 0:9e74b14299fd | 296 | u8t error=0; //error variable |
dmwahl | 2:67b7c9defdfc | 297 | |
dmwahl | 0:9e74b14299fd | 298 | //-- read "Read-Only Register 2" to find out the active configuration field -- |
dmwahl | 0:9e74b14299fd | 299 | error |= ReadRegister(SF04_READ_ONLY_REG2,®isterValue); |
dmwahl | 2:67b7c9defdfc | 300 | |
dmwahl | 0:9e74b14299fd | 301 | //-- calculate eeprom address of product serial number -- |
dmwahl | 0:9e74b14299fd | 302 | eepromBaseAdr=(registerValue.u16 & 0x0007)*0x0300; //RO_REG2 bit<2:0>*0x0300 |
dmwahl | 0:9e74b14299fd | 303 | eepromAdr= eepromBaseAdr + SF04_EE_ADR_SN_PRODUCT; |
dmwahl | 2:67b7c9defdfc | 304 | |
dmwahl | 0:9e74b14299fd | 305 | //-- read product serial number from SF04's eeprom-- |
dmwahl | 0:9e74b14299fd | 306 | error |= ReadEeprom( eepromAdr, 2, eepromData); |
dmwahl | 0:9e74b14299fd | 307 | serialNumber->s32.u16H=eepromData[0].u16; |
dmwahl | 0:9e74b14299fd | 308 | serialNumber->s32.u16L=eepromData[1].u16; |
dmwahl | 4:edf2c4870bbf | 309 | ready = true; |
dmwahl | 0:9e74b14299fd | 310 | return error; |
dmwahl | 0:9e74b14299fd | 311 | } |
dmwahl | 0:9e74b14299fd | 312 | |
dmwahl | 0:9e74b14299fd | 313 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 314 | u8t SF04::ReadScaleFactor(nt16 *scaleFactor) |
dmwahl | 0:9e74b14299fd | 315 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 316 | { |
dmwahl | 4:edf2c4870bbf | 317 | ready = false; |
dmwahl | 0:9e74b14299fd | 318 | u8t error = 0; //variable for error code |
dmwahl | 0:9e74b14299fd | 319 | nt16 registerValue; //register value for user register |
dmwahl | 0:9e74b14299fd | 320 | u16t eepromBaseAdr; //eeprom base address of active calibration field |
dmwahl | 0:9e74b14299fd | 321 | u16t eepromAdr; //eeprom address of SF04's scale factor |
dmwahl | 0:9e74b14299fd | 322 | |
dmwahl | 0:9e74b14299fd | 323 | //-- read "User Register " to find out the active calibration field -- |
dmwahl | 0:9e74b14299fd | 324 | error |= ReadRegister(SF04_USER_REG ,®isterValue); |
dmwahl | 0:9e74b14299fd | 325 | |
dmwahl | 0:9e74b14299fd | 326 | //-- calculate eeprom address of scale factor -- |
dmwahl | 0:9e74b14299fd | 327 | eepromBaseAdr = ((registerValue.u16 & 0x0070) >> 4) * 0x0300; //UserReg bit<6:4>*0x0300 |
dmwahl | 0:9e74b14299fd | 328 | eepromAdr = eepromBaseAdr + SF04_EE_ADR_SCALE_FACTOR; |
dmwahl | 0:9e74b14299fd | 329 | |
dmwahl | 0:9e74b14299fd | 330 | //-- read scale factor from SF04's eeprom-- |
dmwahl | 0:9e74b14299fd | 331 | error |= ReadEeprom( eepromAdr, 1, scaleFactor); |
dmwahl | 0:9e74b14299fd | 332 | |
dmwahl | 4:edf2c4870bbf | 333 | ready = true; |
dmwahl | 0:9e74b14299fd | 334 | return error; |
dmwahl | 0:9e74b14299fd | 335 | } |
dmwahl | 0:9e74b14299fd | 336 | |
dmwahl | 0:9e74b14299fd | 337 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 338 | u8t SF04::ReadFlowUnit(char *flowUnitStr) |
dmwahl | 0:9e74b14299fd | 339 | //=========================================================================== |
dmwahl | 0:9e74b14299fd | 340 | { |
dmwahl | 4:edf2c4870bbf | 341 | ready = false; |
dmwahl | 0:9e74b14299fd | 342 | //-- table for unit dimension, unit time, unit volume (x=not defined) -- |
dmwahl | 0:9e74b14299fd | 343 | const char *unitDimension[]= {"x","x","x","n","u","m","c","d","","-","h","k", |
dmwahl | 2:67b7c9defdfc | 344 | "M","G","x","x" |
dmwahl | 2:67b7c9defdfc | 345 | }; |
dmwahl | 0:9e74b14299fd | 346 | const char *unitTimeBase[] = {"","us","ms","s","min","h","day","x","x","x","x", |
dmwahl | 2:67b7c9defdfc | 347 | "x","x","x","x","x" |
dmwahl | 2:67b7c9defdfc | 348 | }; |
dmwahl | 0:9e74b14299fd | 349 | const char *unitVolume[] = {"ln","sl","x","x","x","x","x","x","l","g","x", |
dmwahl | 0:9e74b14299fd | 350 | "x","x","x","x","x","Pa","bar","mH2O","inH2O", |
dmwahl | 2:67b7c9defdfc | 351 | "x","x","x","x","x","x","x","x","x","x","x","x" |
dmwahl | 2:67b7c9defdfc | 352 | }; |
dmwahl | 0:9e74b14299fd | 353 | //-- local variables -- |
dmwahl | 0:9e74b14299fd | 354 | nt16 registerValue; //register value for user register |
dmwahl | 0:9e74b14299fd | 355 | u16t eepromBaseAdr; //eeprom base address of active calibration field |
dmwahl | 0:9e74b14299fd | 356 | u16t eepromAdr; //eeprom address of SF04's flow unit word |
dmwahl | 0:9e74b14299fd | 357 | nt16 flowUnit; //content of SF04's flow unit word |
dmwahl | 0:9e74b14299fd | 358 | u8t tableIndex; //index of one of the unit arrays |
dmwahl | 0:9e74b14299fd | 359 | u8t error=0; |
dmwahl | 0:9e74b14299fd | 360 | //-- read "User Register" to find out the active calibration field -- |
dmwahl | 0:9e74b14299fd | 361 | error |= ReadRegister(SF04_USER_REG ,®isterValue); |
dmwahl | 0:9e74b14299fd | 362 | //-- calculate eeprom address of flow unit-- |
dmwahl | 0:9e74b14299fd | 363 | eepromBaseAdr=((registerValue.u16 & 0x0070)>>4)*0x0300; //UserReg bit<6:4>*0x0300 |
dmwahl | 0:9e74b14299fd | 364 | eepromAdr= eepromBaseAdr + SF04_EE_ADR_FLOW_UNIT; |
dmwahl | 0:9e74b14299fd | 365 | //-- read flow unit from SF04's eeprom-- |
dmwahl | 0:9e74b14299fd | 366 | error |= ReadEeprom( eepromAdr, 1, &flowUnit); |
dmwahl | 0:9e74b14299fd | 367 | //-- get index of corresponding table and copy it to unit string -- |
dmwahl | 0:9e74b14299fd | 368 | tableIndex=(flowUnit.u16 & 0x000F)>>0; //flowUnit bit <3:0> |
dmwahl | 0:9e74b14299fd | 369 | strcpy(flowUnitStr, unitDimension[tableIndex]); |
dmwahl | 0:9e74b14299fd | 370 | tableIndex=(flowUnit.u16 & 0x1F00)>>8; //flowUnit bit <8:12> |
dmwahl | 0:9e74b14299fd | 371 | strcat(flowUnitStr, unitVolume[tableIndex]); |
dmwahl | 0:9e74b14299fd | 372 | tableIndex=(flowUnit.u16 & 0x00F0)>>4; //flowUnit bit <4:7> |
dmwahl | 0:9e74b14299fd | 373 | if(unitTimeBase[tableIndex] != "") { //check if time base is defined |
dmwahl | 0:9e74b14299fd | 374 | strcat(flowUnitStr, "/"); |
dmwahl | 0:9e74b14299fd | 375 | strcat(flowUnitStr, unitTimeBase[tableIndex]); |
dmwahl | 0:9e74b14299fd | 376 | } |
dmwahl | 0:9e74b14299fd | 377 | //-- check if unit string is feasible -- |
dmwahl | 0:9e74b14299fd | 378 | if(strchr(flowUnitStr,'x') != NULL ) error |= SF04_UNIT_ERROR; |
dmwahl | 4:edf2c4870bbf | 379 | ready = true; |
dmwahl | 0:9e74b14299fd | 380 | return error; |
dmwahl | 0:9e74b14299fd | 381 | } |