Library for working with the HYCON HY3116/8 24-bit weigh-scales ADC series.
HY3116.cpp@8:530aad60c490, 2016-07-26 (annotated)
- Committer:
- seajayshore
- Date:
- Tue Jul 26 16:26:35 2016 +0000
- Revision:
- 8:530aad60c490
- Parent:
- 7:c9a0ce000a18
Refactoring & re-organisation with true C++ constructors.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
seajayshore | 0:80768ca5d5ff | 1 | #include "HY3116.h" |
seajayshore | 0:80768ca5d5ff | 2 | |
seajayshore | 8:530aad60c490 | 3 | /** |
seajayshore | 8:530aad60c490 | 4 | * Default Constructor. |
seajayshore | 8:530aad60c490 | 5 | * Sets default I2C pins with default frequency |
seajayshore | 8:530aad60c490 | 6 | */ |
seajayshore | 8:530aad60c490 | 7 | HY3116::HY3116() : |
seajayshore | 8:530aad60c490 | 8 | i2c(p22, p21) |
seajayshore | 8:530aad60c490 | 9 | { |
seajayshore | 8:530aad60c490 | 10 | |
seajayshore | 8:530aad60c490 | 11 | // Set the I2C clock frequency |
seajayshore | 8:530aad60c490 | 12 | i2c.frequency(250000); |
seajayshore | 8:530aad60c490 | 13 | } // End constructor |
seajayshore | 3:535ed9a0ce59 | 14 | |
seajayshore | 8:530aad60c490 | 15 | /** |
seajayshore | 8:530aad60c490 | 16 | * Constructor #2 |
seajayshore | 8:530aad60c490 | 17 | * Sets I2C pins with default frequency |
seajayshore | 8:530aad60c490 | 18 | */ |
seajayshore | 8:530aad60c490 | 19 | HY3116::HY3116(PinName sda, |
seajayshore | 8:530aad60c490 | 20 | PinName scl) : |
seajayshore | 8:530aad60c490 | 21 | i2c(sda, scl) |
seajayshore | 8:530aad60c490 | 22 | { |
seajayshore | 8:530aad60c490 | 23 | |
seajayshore | 8:530aad60c490 | 24 | // Set the I2C clock frequency |
seajayshore | 8:530aad60c490 | 25 | i2c.frequency(250000); |
seajayshore | 8:530aad60c490 | 26 | } // End constructor |
seajayshore | 8:530aad60c490 | 27 | |
seajayshore | 8:530aad60c490 | 28 | /** |
seajayshore | 8:530aad60c490 | 29 | * Constructor #3 |
seajayshore | 8:530aad60c490 | 30 | * Sets I2C pins and non-default frequency |
seajayshore | 8:530aad60c490 | 31 | */ |
seajayshore | 8:530aad60c490 | 32 | HY3116::HY3116(PinName sda, |
seajayshore | 8:530aad60c490 | 33 | PinName scl, |
seajayshore | 8:530aad60c490 | 34 | int freq ) : |
seajayshore | 8:530aad60c490 | 35 | i2c(sda, scl) |
seajayshore | 8:530aad60c490 | 36 | { |
seajayshore | 8:530aad60c490 | 37 | |
seajayshore | 8:530aad60c490 | 38 | // Set the I2C clock frequency |
seajayshore | 8:530aad60c490 | 39 | i2c.frequency(freq); |
seajayshore | 8:530aad60c490 | 40 | } // End constructor |
seajayshore | 3:535ed9a0ce59 | 41 | |
seajayshore | 8:530aad60c490 | 42 | /** |
seajayshore | 8:530aad60c490 | 43 | * Destructor. |
seajayshore | 8:530aad60c490 | 44 | */ |
seajayshore | 8:530aad60c490 | 45 | HY3116::~HY3116() |
seajayshore | 8:530aad60c490 | 46 | { |
seajayshore | 8:530aad60c490 | 47 | |
seajayshore | 8:530aad60c490 | 48 | } |
seajayshore | 8:530aad60c490 | 49 | |
seajayshore | 8:530aad60c490 | 50 | /** |
seajayshore | 8:530aad60c490 | 51 | * Helper function to write correct data to HY3116 registers |
seajayshore | 8:530aad60c490 | 52 | */ |
seajayshore | 8:530aad60c490 | 53 | int HY3116::writeRegister(uint8_t regAddress, uint8_t writeData) |
seajayshore | 8:530aad60c490 | 54 | { |
seajayshore | 8:530aad60c490 | 55 | int retval = 1; |
seajayshore | 8:530aad60c490 | 56 | char writeBuffer[2]; |
seajayshore | 8:530aad60c490 | 57 | writeBuffer[0]=regAddress; |
seajayshore | 8:530aad60c490 | 58 | writeBuffer[1]=writeData; |
seajayshore | 8:530aad60c490 | 59 | retval = i2c.write(HY3116_ADDRESS,writeBuffer,sizeof(writeBuffer),0); |
seajayshore | 8:530aad60c490 | 60 | if (retval != 0) { |
seajayshore | 8:530aad60c490 | 61 | return retval; |
seajayshore | 8:530aad60c490 | 62 | } |
seajayshore | 8:530aad60c490 | 63 | return 0; |
seajayshore | 8:530aad60c490 | 64 | } |
seajayshore | 0:80768ca5d5ff | 65 | |
seajayshore | 8:530aad60c490 | 66 | /** |
seajayshore | 8:530aad60c490 | 67 | * Helper function to write correct data to HY3116 registers |
seajayshore | 8:530aad60c490 | 68 | */ |
seajayshore | 8:530aad60c490 | 69 | int HY3116::readRegister(uint8_t regAddress, uint8_t byteNum, uint8_t* dest) |
seajayshore | 0:80768ca5d5ff | 70 | { |
seajayshore | 8:530aad60c490 | 71 | int retval = 1; |
seajayshore | 8:530aad60c490 | 72 | if (byteNum > sizeof(dest)) { |
seajayshore | 8:530aad60c490 | 73 | return retval; |
seajayshore | 7:c9a0ce000a18 | 74 | } |
seajayshore | 8:530aad60c490 | 75 | char writeBuffer[1]; |
seajayshore | 8:530aad60c490 | 76 | writeBuffer[0] = regAddress; |
seajayshore | 8:530aad60c490 | 77 | char readBuffer[byteNum]; |
seajayshore | 8:530aad60c490 | 78 | retval = i2c.write(HY3116_ADDRESS,writeBuffer,sizeof(writeBuffer),1); |
seajayshore | 8:530aad60c490 | 79 | if (retval != 0) { |
seajayshore | 8:530aad60c490 | 80 | return retval; |
seajayshore | 8:530aad60c490 | 81 | } |
seajayshore | 8:530aad60c490 | 82 | retval = i2c.read(HY3116_ADDRESS,readBuffer,sizeof(readBuffer),0); |
seajayshore | 8:530aad60c490 | 83 | if (retval != 0) { |
seajayshore | 8:530aad60c490 | 84 | return retval; |
seajayshore | 8:530aad60c490 | 85 | } |
seajayshore | 8:530aad60c490 | 86 | for(int i=0; i<byteNum; i++) { |
seajayshore | 8:530aad60c490 | 87 | dest[i]=readBuffer[i]; |
seajayshore | 8:530aad60c490 | 88 | } |
seajayshore | 8:530aad60c490 | 89 | return 0; |
seajayshore | 0:80768ca5d5ff | 90 | } |
seajayshore | 0:80768ca5d5ff | 91 | |
seajayshore | 0:80768ca5d5ff | 92 | // Function to send the reset command |
seajayshore | 7:c9a0ce000a18 | 93 | int HY3116::resetChip() |
seajayshore | 0:80768ca5d5ff | 94 | { |
seajayshore | 8:530aad60c490 | 95 | int retval = 0; |
seajayshore | 8:530aad60c490 | 96 | char writeBuffer[1]; |
seajayshore | 8:530aad60c490 | 97 | writeBuffer[0] = RESET; |
seajayshore | 8:530aad60c490 | 98 | retval = i2c.write(RESET_ADDRESS,writeBuffer,sizeof(writeBuffer),0); |
seajayshore | 8:530aad60c490 | 99 | if (retval != 0) { |
seajayshore | 7:c9a0ce000a18 | 100 | return 1; |
seajayshore | 7:c9a0ce000a18 | 101 | } |
seajayshore | 7:c9a0ce000a18 | 102 | return 0; |
seajayshore | 0:80768ca5d5ff | 103 | } |
seajayshore | 0:80768ca5d5ff | 104 | |
seajayshore | 0:80768ca5d5ff | 105 | // Dedicated ADC-output read, check & format function |
seajayshore | 7:c9a0ce000a18 | 106 | uint8_t HY3116::readAdc(int32_t *_adcReading) |
seajayshore | 0:80768ca5d5ff | 107 | { |
seajayshore | 1:1967c3f48465 | 108 | // Initialise function variables |
seajayshore | 0:80768ca5d5ff | 109 | uint8_t rawData[3]; |
seajayshore | 0:80768ca5d5ff | 110 | bool newReading = 0; |
seajayshore | 0:80768ca5d5ff | 111 | int32_t adcReading = 0; |
seajayshore | 7:c9a0ce000a18 | 112 | uint8_t adc_error = 0; |
seajayshore | 7:c9a0ce000a18 | 113 | uint8_t returnError = 0; |
seajayshore | 0:80768ca5d5ff | 114 | |
seajayshore | 1:1967c3f48465 | 115 | // Read in the raw ADO bytes |
seajayshore | 8:530aad60c490 | 116 | adc_error = readRegister(ADO, 3, &rawData[0]); |
seajayshore | 7:c9a0ce000a18 | 117 | if (adc_error != 0) { |
seajayshore | 7:c9a0ce000a18 | 118 | returnError = 2; |
seajayshore | 7:c9a0ce000a18 | 119 | return returnError; |
seajayshore | 7:c9a0ce000a18 | 120 | } |
seajayshore | 0:80768ca5d5ff | 121 | |
seajayshore | 1:1967c3f48465 | 122 | // Test if there is new data (polling mode) |
seajayshore | 0:80768ca5d5ff | 123 | if (rawData[2] & 0b00000001) { |
seajayshore | 1:1967c3f48465 | 124 | |
seajayshore | 1:1967c3f48465 | 125 | // Set the newReading flag |
seajayshore | 7:c9a0ce000a18 | 126 | returnError = 0; |
seajayshore | 1:1967c3f48465 | 127 | |
seajayshore | 1:1967c3f48465 | 128 | // Shift the raw bytes into the 32-bit variable |
seajayshore | 1:1967c3f48465 | 129 | adcReading += rawData[0] << 15; |
seajayshore | 1:1967c3f48465 | 130 | adcReading += rawData[1] << 7; |
seajayshore | 1:1967c3f48465 | 131 | adcReading += rawData[2] >> 1; |
seajayshore | 1:1967c3f48465 | 132 | |
seajayshore | 1:1967c3f48465 | 133 | // Account for twos complement polarity |
seajayshore | 1:1967c3f48465 | 134 | if (rawData[0] & 0b10000000) { |
seajayshore | 1:1967c3f48465 | 135 | adcReading ^= 0xFF800000; |
seajayshore | 1:1967c3f48465 | 136 | } |
seajayshore | 0:80768ca5d5ff | 137 | } |
seajayshore | 0:80768ca5d5ff | 138 | else { |
seajayshore | 1:1967c3f48465 | 139 | |
seajayshore | 1:1967c3f48465 | 140 | // Set the newReading flag |
seajayshore | 7:c9a0ce000a18 | 141 | returnError = 1; |
seajayshore | 0:80768ca5d5ff | 142 | } |
seajayshore | 0:80768ca5d5ff | 143 | |
seajayshore | 1:1967c3f48465 | 144 | *_adcReading = adcReading; |
seajayshore | 0:80768ca5d5ff | 145 | |
seajayshore | 7:c9a0ce000a18 | 146 | return returnError; |
seajayshore | 0:80768ca5d5ff | 147 | } |
seajayshore | 0:80768ca5d5ff | 148 | |
seajayshore | 0:80768ca5d5ff | 149 | // Initialise the HY3116 with the following config.: |
seajayshore | 0:80768ca5d5ff | 150 | // |
seajayshore | 7:c9a0ce000a18 | 151 | bool HY3116::init() |
seajayshore | 0:80768ca5d5ff | 152 | { |
seajayshore | 7:c9a0ce000a18 | 153 | int adc_error = 0; |
seajayshore | 7:c9a0ce000a18 | 154 | |
seajayshore | 8:530aad60c490 | 155 | // Reset the chip |
seajayshore | 8:530aad60c490 | 156 | adc_error = resetChip(); |
seajayshore | 8:530aad60c490 | 157 | if (adc_error != 0) { |
seajayshore | 8:530aad60c490 | 158 | return 0; |
seajayshore | 8:530aad60c490 | 159 | } |
seajayshore | 8:530aad60c490 | 160 | wait_ms(1); |
seajayshore | 0:80768ca5d5ff | 161 | |
seajayshore | 0:80768ca5d5ff | 162 | // Set-up the SYS register |
seajayshore | 8:530aad60c490 | 163 | adc_error = writeRegister(SYS, 0b00011100); // Enable the ADC & LDO |
seajayshore | 7:c9a0ce000a18 | 164 | if (adc_error != 0) { |
seajayshore | 7:c9a0ce000a18 | 165 | return 0; |
seajayshore | 7:c9a0ce000a18 | 166 | } |
seajayshore | 2:2da9fbab02b7 | 167 | wait_ms(1); // wait 100 ms to stabilize |
seajayshore | 0:80768ca5d5ff | 168 | |
seajayshore | 0:80768ca5d5ff | 169 | // Set-up the ADC1 register |
seajayshore | 8:530aad60c490 | 170 | adc_error = writeRegister(ADC1, 0b00001000); // Set inputs to AIN1 & AIN2 |
seajayshore | 7:c9a0ce000a18 | 171 | if (adc_error != 0) { |
seajayshore | 7:c9a0ce000a18 | 172 | return 0; |
seajayshore | 7:c9a0ce000a18 | 173 | } |
seajayshore | 2:2da9fbab02b7 | 174 | wait_ms(1); // wait 100 ms to stabilize |
seajayshore | 0:80768ca5d5ff | 175 | |
seajayshore | 0:80768ca5d5ff | 176 | // Set-up the ADC2 register |
seajayshore | 8:530aad60c490 | 177 | adc_error = writeRegister(ADC2, 0b01010000); // Set pos. ref. voltage to VDDA, neg. ref. to VSSA, DC offset to 0VRef |
seajayshore | 7:c9a0ce000a18 | 178 | if (adc_error != 0) { |
seajayshore | 7:c9a0ce000a18 | 179 | return 0; |
seajayshore | 7:c9a0ce000a18 | 180 | } |
seajayshore | 2:2da9fbab02b7 | 181 | wait_ms(1); // wait 100 ms to stabilize |
seajayshore | 0:80768ca5d5ff | 182 | |
seajayshore | 0:80768ca5d5ff | 183 | // Set-up the ADC3 register |
seajayshore | 8:530aad60c490 | 184 | adc_error = writeRegister(ADC3, 0b00111111); // Set to int. osc. 327kHz, full ref. range, PGA to 32x, pre-amp to 2x |
seajayshore | 7:c9a0ce000a18 | 185 | if (adc_error != 0) { |
seajayshore | 7:c9a0ce000a18 | 186 | return 0; |
seajayshore | 7:c9a0ce000a18 | 187 | } |
seajayshore | 2:2da9fbab02b7 | 188 | wait_ms(1); // wait 100 ms to stabilize |
seajayshore | 0:80768ca5d5ff | 189 | |
seajayshore | 0:80768ca5d5ff | 190 | // Set-up the ADC4 register |
seajayshore | 5:3fdbe36e5057 | 191 | // [0:1] = LDO voltage select, 01 = 3.0V |
seajayshore | 5:3fdbe36e5057 | 192 | // [2] = REFO voltage, 0 = 1.2V |
seajayshore | 5:3fdbe36e5057 | 193 | // [3] = HS conversion rate, 0 = slow (327kHz) |
seajayshore | 5:3fdbe36e5057 | 194 | // [4:6] = OSR ADC output rate, 110 = 40SPS (when HS = 0) |
seajayshore | 5:3fdbe36e5057 | 195 | // [7] = N/A |
seajayshore | 8:530aad60c490 | 196 | adc_error = writeRegister(ADC4, 0b01001100); |
seajayshore | 7:c9a0ce000a18 | 197 | if (adc_error != 0) { |
seajayshore | 7:c9a0ce000a18 | 198 | return 0; |
seajayshore | 7:c9a0ce000a18 | 199 | } |
seajayshore | 5:3fdbe36e5057 | 200 | wait_ms(1); // Wait to stabilise |
seajayshore | 0:80768ca5d5ff | 201 | |
seajayshore | 7:c9a0ce000a18 | 202 | return 1; |
seajayshore | 0:80768ca5d5ff | 203 | } |