MCP3427 16-Bit Analog-to-Digital Converter with I2C Interface

Fork of MCP3425 by Kenji Arai

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?

UserRevisionLine numberNew 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 }