MCP3427 16-Bit Analog-to-Digital Converter with I2C Interface
Fork of MCP3425 by
MCP3427.cpp@2:bb3efa8c5b23, 2018-09-21 (annotated)
- Committer:
- kenjiArai
- Date:
- Fri Sep 21 22:39:23 2018 +0000
- Revision:
- 2:bb3efa8c5b23
- Parent:
- MCP3425.cpp@1:223248a79e87
Library for MCP3427
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:29be5dda6cf2 | 1 | /* |
kenjiArai | 0:29be5dda6cf2 | 2 | * mbed library program |
kenjiArai | 2:bb3efa8c5b23 | 3 | * 2 channels 16-Bit(available 14/12bit mode) Analog-to-Digital Converter |
kenjiArai | 2:bb3efa8c5b23 | 4 | * with I2C Interface ---- MCP3427 by Microchip Technology Inc. |
kenjiArai | 0:29be5dda6cf2 | 5 | * |
kenjiArai | 0:29be5dda6cf2 | 6 | * Copyright (c) 2018 Kenji Arai / JH1PJL |
kenjiArai | 0:29be5dda6cf2 | 7 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:29be5dda6cf2 | 8 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 2:bb3efa8c5b23 | 9 | * Created: June 7th, 2018 |
kenjiArai | 2:bb3efa8c5b23 | 10 | * Revised: July 13th, 2018 |
kenjiArai | 0:29be5dda6cf2 | 11 | */ |
kenjiArai | 0:29be5dda6cf2 | 12 | |
kenjiArai | 2:bb3efa8c5b23 | 13 | #include "MCP3427.h" |
kenjiArai | 0:29be5dda6cf2 | 14 | |
kenjiArai | 0:29be5dda6cf2 | 15 | extern Serial pc; |
kenjiArai | 0:29be5dda6cf2 | 16 | |
kenjiArai | 0:29be5dda6cf2 | 17 | // BIT DEFINITION |
kenjiArai | 0:29be5dda6cf2 | 18 | #define RDY_BIT (1UL << 7) |
kenjiArai | 0:29be5dda6cf2 | 19 | #define CONVERSION_MODE_BIT (1UL << 4) |
kenjiArai | 0:29be5dda6cf2 | 20 | #define SAMPLE_RATE_BIT (3UL << 2) |
kenjiArai | 0:29be5dda6cf2 | 21 | #define PGA_GAIN_BIT (3UL << 0) |
kenjiArai | 0:29be5dda6cf2 | 22 | |
kenjiArai | 0:29be5dda6cf2 | 23 | #if (MBED_MAJOR_VERSION == 2) |
kenjiArai | 0:29be5dda6cf2 | 24 | #define WAIT_MS(x) wait_ms(x) |
kenjiArai | 0:29be5dda6cf2 | 25 | #elif (MBED_MAJOR_VERSION == 5) |
kenjiArai | 0:29be5dda6cf2 | 26 | #define WAIT_MS(x) Thread::wait(x) |
kenjiArai | 0:29be5dda6cf2 | 27 | #else |
kenjiArai | 2:bb3efa8c5b23 | 28 | #warning "Cannot control wait_ms()!!" |
kenjiArai | 0:29be5dda6cf2 | 29 | #endif |
kenjiArai | 0:29be5dda6cf2 | 30 | |
kenjiArai | 2:bb3efa8c5b23 | 31 | MCP3427::MCP3427 (PinName p_sda, PinName p_scl, uint8_t addr) |
kenjiArai | 0:29be5dda6cf2 | 32 | : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) |
kenjiArai | 0:29be5dda6cf2 | 33 | { |
kenjiArai | 2:bb3efa8c5b23 | 34 | mcp3427_addr = addr; |
kenjiArai | 0:29be5dda6cf2 | 35 | init(); |
kenjiArai | 0:29be5dda6cf2 | 36 | } |
kenjiArai | 0:29be5dda6cf2 | 37 | |
kenjiArai | 2:bb3efa8c5b23 | 38 | MCP3427::MCP3427 (I2C& p_i2c, uint8_t addr) |
kenjiArai | 0:29be5dda6cf2 | 39 | : _i2c(p_i2c) |
kenjiArai | 0:29be5dda6cf2 | 40 | { |
kenjiArai | 2:bb3efa8c5b23 | 41 | mcp3427_addr = addr; |
kenjiArai | 0:29be5dda6cf2 | 42 | init(); |
kenjiArai | 0:29be5dda6cf2 | 43 | } |
kenjiArai | 0:29be5dda6cf2 | 44 | |
kenjiArai | 2:bb3efa8c5b23 | 45 | void MCP3427::init() |
kenjiArai | 0:29be5dda6cf2 | 46 | { |
kenjiArai | 2:bb3efa8c5b23 | 47 | offset_volt[0] = 0.0f; // none offset |
kenjiArai | 2:bb3efa8c5b23 | 48 | offset_volt[1] = 0.0f; // none offset |
kenjiArai | 2:bb3efa8c5b23 | 49 | compensation_ref = 1.0f; // no compensation |
kenjiArai | 2:bb3efa8c5b23 | 50 | pga_gain[0] = PGA_GAIN_1; // Gain x1 |
kenjiArai | 2:bb3efa8c5b23 | 51 | pga_gain[1] = PGA_GAIN_1; // Gain x1 |
kenjiArai | 2:bb3efa8c5b23 | 52 | sample_rate[0] = SAMPLE_RATE_15SPS_16BIT; // 16bit resolution |
kenjiArai | 2:bb3efa8c5b23 | 53 | sample_rate[1] = SAMPLE_RATE_15SPS_16BIT; // 16bit resolution |
kenjiArai | 2:bb3efa8c5b23 | 54 | conversion_mode[0] = CONV_MODE_CONTINUOUS; // Continuous conversion |
kenjiArai | 2:bb3efa8c5b23 | 55 | conversion_mode[1] = CONV_MODE_CONTINUOUS; // Continuous conversion |
kenjiArai | 2:bb3efa8c5b23 | 56 | convert_config2byte(); // make one byte |
kenjiArai | 2:bb3efa8c5b23 | 57 | buf[0] = config_byte[0]; |
kenjiArai | 2:bb3efa8c5b23 | 58 | _i2c.write((int)mcp3427_addr, (char *)buf, 1); // write into config reg. |
kenjiArai | 2:bb3efa8c5b23 | 59 | current_ch = 0; |
kenjiArai | 0:29be5dda6cf2 | 60 | } |
kenjiArai | 0:29be5dda6cf2 | 61 | |
kenjiArai | 2:bb3efa8c5b23 | 62 | int16_t MCP3427::read_16bit(uint8_t ch) |
kenjiArai | 0:29be5dda6cf2 | 63 | { |
kenjiArai | 2:bb3efa8c5b23 | 64 | _ch = ch - 1; |
kenjiArai | 2:bb3efa8c5b23 | 65 | if (_ch != current_ch) { |
kenjiArai | 2:bb3efa8c5b23 | 66 | current_ch = _ch; |
kenjiArai | 2:bb3efa8c5b23 | 67 | _set_ch_and_config(current_ch); |
kenjiArai | 2:bb3efa8c5b23 | 68 | buf[0] = config_byte[current_ch] + RDY_BIT; |
kenjiArai | 2:bb3efa8c5b23 | 69 | _i2c.write((int)mcp3427_addr, (char *)buf, 1); |
kenjiArai | 2:bb3efa8c5b23 | 70 | } |
kenjiArai | 2:bb3efa8c5b23 | 71 | if (conversion_mode[current_ch] == CONV_MODE_ONE_SHOT) { |
kenjiArai | 2:bb3efa8c5b23 | 72 | // trigger for starting conversion |
kenjiArai | 2:bb3efa8c5b23 | 73 | buf[0] = config_byte[current_ch] + RDY_BIT; |
kenjiArai | 2:bb3efa8c5b23 | 74 | _i2c.write((int)mcp3427_addr, (char *)buf, 1); |
kenjiArai | 2:bb3efa8c5b23 | 75 | } |
kenjiArai | 2:bb3efa8c5b23 | 76 | return _read_16bit(); // internal channel 0 & 1 |
kenjiArai | 2:bb3efa8c5b23 | 77 | |
kenjiArai | 0:29be5dda6cf2 | 78 | } |
kenjiArai | 0:29be5dda6cf2 | 79 | |
kenjiArai | 2:bb3efa8c5b23 | 80 | int16_t MCP3427::_read_16bit(void) |
kenjiArai | 0:29be5dda6cf2 | 81 | { |
kenjiArai | 0:29be5dda6cf2 | 82 | uint32_t timeout = 1000U; // timeout |
kenjiArai | 0:29be5dda6cf2 | 83 | do { |
kenjiArai | 2:bb3efa8c5b23 | 84 | _i2c.read( (int)mcp3427_addr, (char *)buf, 3); |
kenjiArai | 1:223248a79e87 | 85 | if ((buf[2] & RDY_BIT) == 0) { // check Config. reg. Ready bit |
kenjiArai | 1:223248a79e87 | 86 | break; // end of conversion (RDY = 0) |
kenjiArai | 0:29be5dda6cf2 | 87 | } |
kenjiArai | 0:29be5dda6cf2 | 88 | if (--timeout == 0) { |
kenjiArai | 1:223248a79e87 | 89 | return -1; // timeout then error |
kenjiArai | 0:29be5dda6cf2 | 90 | } |
kenjiArai | 1:223248a79e87 | 91 | uint8_t spd = (buf[2] >> 2) & 0x03; // get current sampling rate |
kenjiArai | 1:223248a79e87 | 92 | if (spd == SAMPLE_RATE_60SPS_14BIT) { // wait next conversion period |
kenjiArai | 0:29be5dda6cf2 | 93 | WAIT_MS(6); // conversion time = 16.7ms |
kenjiArai | 0:29be5dda6cf2 | 94 | } else if (spd == SAMPLE_RATE_15SPS_16BIT) { |
kenjiArai | 0:29be5dda6cf2 | 95 | WAIT_MS(24); // conversion time = 66.7ms |
kenjiArai | 0:29be5dda6cf2 | 96 | } else { // == SAMPLE_RATE_240SPS_12BIT |
kenjiArai | 1:223248a79e87 | 97 | WAIT_MS(2); // conversion time = 4.2ms |
kenjiArai | 0:29be5dda6cf2 | 98 | } |
kenjiArai | 0:29be5dda6cf2 | 99 | } while(true); |
kenjiArai | 2:bb3efa8c5b23 | 100 | //printf("[%d,0x%02x,0x%02x,0x%02x]", _ch, buf[0], buf[1], buf[2]); |
kenjiArai | 1:223248a79e87 | 101 | dt_adc16 = (uint16_t)buf[0] << 8; // High byte |
kenjiArai | 1:223248a79e87 | 102 | dt_adc16 += (uint16_t)buf[1]; // Low byte |
kenjiArai | 0:29be5dda6cf2 | 103 | return dt_adc16; |
kenjiArai | 0:29be5dda6cf2 | 104 | } |
kenjiArai | 0:29be5dda6cf2 | 105 | |
kenjiArai | 2:bb3efa8c5b23 | 106 | void MCP3427::start_conversion(uint8_t ch) |
kenjiArai | 0:29be5dda6cf2 | 107 | { |
kenjiArai | 2:bb3efa8c5b23 | 108 | _ch = ch - 1; |
kenjiArai | 2:bb3efa8c5b23 | 109 | if (_ch != current_ch) { |
kenjiArai | 2:bb3efa8c5b23 | 110 | current_ch = _ch; |
kenjiArai | 2:bb3efa8c5b23 | 111 | _set_ch_and_config(current_ch); |
kenjiArai | 2:bb3efa8c5b23 | 112 | buf[0] = config_byte[current_ch] + RDY_BIT; |
kenjiArai | 2:bb3efa8c5b23 | 113 | _i2c.write((int)mcp3427_addr, (char *)buf, 1); |
kenjiArai | 2:bb3efa8c5b23 | 114 | } |
kenjiArai | 2:bb3efa8c5b23 | 115 | if (conversion_mode[current_ch] == CONV_MODE_ONE_SHOT) { |
kenjiArai | 2:bb3efa8c5b23 | 116 | // trigger for starting conversion |
kenjiArai | 2:bb3efa8c5b23 | 117 | buf[0] = config_byte[current_ch] + RDY_BIT; |
kenjiArai | 2:bb3efa8c5b23 | 118 | _i2c.write((int)mcp3427_addr, (char *)buf, 1); |
kenjiArai | 2:bb3efa8c5b23 | 119 | } |
kenjiArai | 2:bb3efa8c5b23 | 120 | } |
kenjiArai | 2:bb3efa8c5b23 | 121 | |
kenjiArai | 2:bb3efa8c5b23 | 122 | float MCP3427::read_voltage_from_current_ch(void) |
kenjiArai | 2:bb3efa8c5b23 | 123 | { |
kenjiArai | 2:bb3efa8c5b23 | 124 | float dt16 = (float)_read_16bit(); |
kenjiArai | 2:bb3efa8c5b23 | 125 | return _read_voltage(dt16); |
kenjiArai | 2:bb3efa8c5b23 | 126 | } |
kenjiArai | 2:bb3efa8c5b23 | 127 | |
kenjiArai | 2:bb3efa8c5b23 | 128 | float MCP3427::read_voltage(uint8_t ch) |
kenjiArai | 2:bb3efa8c5b23 | 129 | { |
kenjiArai | 2:bb3efa8c5b23 | 130 | float dt16 = (float)read_16bit(ch); |
kenjiArai | 2:bb3efa8c5b23 | 131 | return _read_voltage(dt16); |
kenjiArai | 2:bb3efa8c5b23 | 132 | } |
kenjiArai | 2:bb3efa8c5b23 | 133 | |
kenjiArai | 2:bb3efa8c5b23 | 134 | float MCP3427::_read_voltage(float dt16) |
kenjiArai | 2:bb3efa8c5b23 | 135 | { |
kenjiArai | 2:bb3efa8c5b23 | 136 | switch(sample_rate[current_ch]) { |
kenjiArai | 0:29be5dda6cf2 | 137 | case SAMPLE_RATE_240SPS_12BIT: |
kenjiArai | 0:29be5dda6cf2 | 138 | dt16 /= 2048.0f; // 11bit (0x7ff +1) |
kenjiArai | 0:29be5dda6cf2 | 139 | break; |
kenjiArai | 0:29be5dda6cf2 | 140 | case SAMPLE_RATE_60SPS_14BIT: |
kenjiArai | 0:29be5dda6cf2 | 141 | dt16 /= 16384.0f; // 14bit (0x3fff +1) |
kenjiArai | 0:29be5dda6cf2 | 142 | break; |
kenjiArai | 0:29be5dda6cf2 | 143 | case SAMPLE_RATE_15SPS_16BIT: |
kenjiArai | 0:29be5dda6cf2 | 144 | dt16 /= 32768.0f; // 15bit (0x7fff +1) |
kenjiArai | 0:29be5dda6cf2 | 145 | break; |
kenjiArai | 0:29be5dda6cf2 | 146 | default: |
kenjiArai | 1:223248a79e87 | 147 | return -1; // error |
kenjiArai | 0:29be5dda6cf2 | 148 | } |
kenjiArai | 2:bb3efa8c5b23 | 149 | switch(pga_gain[current_ch]) { |
kenjiArai | 0:29be5dda6cf2 | 150 | case PGA_GAIN_1: |
kenjiArai | 0:29be5dda6cf2 | 151 | dt16 /= 1.0f; |
kenjiArai | 0:29be5dda6cf2 | 152 | break; |
kenjiArai | 0:29be5dda6cf2 | 153 | case PGA_GAIN_2: |
kenjiArai | 0:29be5dda6cf2 | 154 | dt16 /= 2.0f; |
kenjiArai | 0:29be5dda6cf2 | 155 | break; |
kenjiArai | 0:29be5dda6cf2 | 156 | case PGA_GAIN_4: |
kenjiArai | 0:29be5dda6cf2 | 157 | dt16 /= 4.0f; |
kenjiArai | 0:29be5dda6cf2 | 158 | break; |
kenjiArai | 0:29be5dda6cf2 | 159 | case PGA_GAIN_8: |
kenjiArai | 0:29be5dda6cf2 | 160 | dt16 /= 8.0f; |
kenjiArai | 0:29be5dda6cf2 | 161 | break; |
kenjiArai | 0:29be5dda6cf2 | 162 | default: |
kenjiArai | 1:223248a79e87 | 163 | return -1; // error |
kenjiArai | 0:29be5dda6cf2 | 164 | } |
kenjiArai | 2:bb3efa8c5b23 | 165 | dt_adc_f = dt16 * 2.048f; // Vref = 2.048V +/- 0.05% |
kenjiArai | 2:bb3efa8c5b23 | 166 | dt_adc_f -= offset_volt[current_ch];// adjust offset voltage |
kenjiArai | 2:bb3efa8c5b23 | 167 | dt_adc_f *= compensation_ref; // compensate Vref deviation |
kenjiArai | 0:29be5dda6cf2 | 168 | return dt_adc_f; |
kenjiArai | 0:29be5dda6cf2 | 169 | } |
kenjiArai | 0:29be5dda6cf2 | 170 | |
kenjiArai | 2:bb3efa8c5b23 | 171 | void MCP3427::set_offset_volt(uint8_t ch, float offset) |
kenjiArai | 0:29be5dda6cf2 | 172 | { |
kenjiArai | 2:bb3efa8c5b23 | 173 | offset_volt[ch - 1] = offset; // internal channel 0 & 1 |
kenjiArai | 0:29be5dda6cf2 | 174 | } |
kenjiArai | 0:29be5dda6cf2 | 175 | |
kenjiArai | 2:bb3efa8c5b23 | 176 | void MCP3427::set_vref_compensation(float compensation) |
kenjiArai | 0:29be5dda6cf2 | 177 | { |
kenjiArai | 0:29be5dda6cf2 | 178 | compensation_ref = compensation; |
kenjiArai | 0:29be5dda6cf2 | 179 | } |
kenjiArai | 0:29be5dda6cf2 | 180 | |
kenjiArai | 2:bb3efa8c5b23 | 181 | void MCP3427::set_config(mcp3427_config_t *parameter) |
kenjiArai | 0:29be5dda6cf2 | 182 | { |
kenjiArai | 2:bb3efa8c5b23 | 183 | pga_gain[0] = parameter->pga_gain1 & 0x03; |
kenjiArai | 2:bb3efa8c5b23 | 184 | pga_gain[1] = parameter->pga_gain2 & 0x03; |
kenjiArai | 2:bb3efa8c5b23 | 185 | sample_rate[0] = parameter->sample_rate1 & 0x03; |
kenjiArai | 2:bb3efa8c5b23 | 186 | sample_rate[1] = parameter->sample_rate2 & 0x03; |
kenjiArai | 2:bb3efa8c5b23 | 187 | conversion_mode[0] = parameter->conversion_mode1 & 0x01; |
kenjiArai | 2:bb3efa8c5b23 | 188 | conversion_mode[1] = parameter->conversion_mode2 & 0x01; |
kenjiArai | 2:bb3efa8c5b23 | 189 | convert_config2byte(); |
kenjiArai | 2:bb3efa8c5b23 | 190 | _set_ch_and_config(0); // channel inf is dummy at this moment |
kenjiArai | 0:29be5dda6cf2 | 191 | } |
kenjiArai | 0:29be5dda6cf2 | 192 | |
kenjiArai | 2:bb3efa8c5b23 | 193 | void MCP3427::_set_ch_and_config(uint8_t n) |
kenjiArai | 0:29be5dda6cf2 | 194 | { |
kenjiArai | 2:bb3efa8c5b23 | 195 | buf[0] = config_byte[n] + n << 5; |
kenjiArai | 2:bb3efa8c5b23 | 196 | _i2c.write((int)mcp3427_addr, (char *)buf, 1); |
kenjiArai | 0:29be5dda6cf2 | 197 | } |
kenjiArai | 0:29be5dda6cf2 | 198 | |
kenjiArai | 2:bb3efa8c5b23 | 199 | void MCP3427::frequency(uint32_t hz) |
kenjiArai | 0:29be5dda6cf2 | 200 | { |
kenjiArai | 0:29be5dda6cf2 | 201 | _i2c.frequency(hz); |
kenjiArai | 0:29be5dda6cf2 | 202 | } |
kenjiArai | 0:29be5dda6cf2 | 203 | |
kenjiArai | 2:bb3efa8c5b23 | 204 | void MCP3427::convert_config2byte() |
kenjiArai | 0:29be5dda6cf2 | 205 | { |
kenjiArai | 2:bb3efa8c5b23 | 206 | uint8_t byte = pga_gain[0]; |
kenjiArai | 2:bb3efa8c5b23 | 207 | byte |= sample_rate[0] << 2; |
kenjiArai | 2:bb3efa8c5b23 | 208 | byte |= conversion_mode[0] << 4; |
kenjiArai | 2:bb3efa8c5b23 | 209 | config_byte[0] = byte; |
kenjiArai | 2:bb3efa8c5b23 | 210 | byte = pga_gain[1]; |
kenjiArai | 2:bb3efa8c5b23 | 211 | byte |= sample_rate[1] << 2; |
kenjiArai | 2:bb3efa8c5b23 | 212 | byte |= conversion_mode[1] << 4; |
kenjiArai | 2:bb3efa8c5b23 | 213 | byte |= 0x20; // Ch 2 |
kenjiArai | 2:bb3efa8c5b23 | 214 | config_byte[1] = byte; |
kenjiArai | 0:29be5dda6cf2 | 215 | } |