Kenji Arai / MCP3425

Dependents:   check_ADC_MCP3425

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCP3425.cpp Source File

MCP3425.cpp

00001 /*
00002  * mbed library program
00003  *  16-Bit Analog-to-Digital Converter with I2C Interface
00004  *  MCP3425 by Microchip Technology Inc.
00005  *
00006  * Copyright (c) 2018 Kenji Arai / JH1PJL
00007  *  http://www.page.sannet.ne.jp/kenjia/index.html
00008  *  http://mbed.org/users/kenjiArai/
00009  *      Modify:     March     17th, 2018
00010  *      Revised:    March     18th, 2018
00011  */
00012 
00013 #include "MCP3425.h"
00014 
00015 extern Serial pc;
00016 
00017 // BIT DEFINITION
00018 #define RDY_BIT                     (1UL << 7)
00019 #define CONVERSION_MODE_BIT         (1UL << 4)
00020 #define SAMPLE_RATE_BIT             (3UL << 2)
00021 #define PGA_GAIN_BIT                (3UL << 0)
00022 
00023 #if (MBED_MAJOR_VERSION == 2)
00024 #define WAIT_MS(x)              wait_ms(x)
00025 #elif (MBED_MAJOR_VERSION == 5)
00026 #define WAIT_MS(x)              Thread::wait(x)
00027 #else
00028 #warning "I cannot control wait_ms()!!"
00029 #endif
00030 
00031 MCP3425::MCP3425 (PinName p_sda, PinName p_scl)
00032     : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00033 {
00034     mcp3425_addr = MCP3425A0T_ADDR; // Chip MCP3425A0T-E/CH
00035     init();
00036 }
00037 
00038 MCP3425::MCP3425 (PinName p_sda, PinName p_scl, uint8_t addr)
00039     : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00040 {
00041     mcp3425_addr = addr;    // you need get diffrent part nuber of chip
00042     init();
00043 }
00044 
00045 MCP3425::MCP3425 (I2C& p_i2c)
00046     : _i2c(p_i2c)
00047 {
00048     mcp3425_addr = MCP3425A0T_ADDR; // Chip MCP3425A0T-E/CH
00049     init();
00050 }
00051 
00052 MCP3425::MCP3425 (I2C& p_i2c, uint8_t addr)
00053     : _i2c(p_i2c)
00054 {
00055     mcp3425_addr = addr;    // you need get diffrent part nuber of chip
00056     init();
00057 }
00058 
00059 void MCP3425::init()
00060 {
00061     offset_volt = 0.0f;             // none offset
00062     compensation_ref = 1.0f;        // no compensation
00063     config.pga_gain = PGA_GAIN_1;   // Gain x1
00064     config.sample_rate = SAMPLE_RATE_15SPS_16BIT;   // 16bit resolution
00065     config.conversion_mode = CONV_MODE_CONTINUOUS;  // Continuous conversion
00066     config_byte = convert_config2byte(&config); // make one byte
00067     buf[0] = config_byte;
00068     _i2c.write((int)mcp3425_addr, (char *)buf, 1);  // write into config reg.
00069 }
00070 
00071 int16_t MCP3425::read_16bit()
00072 {
00073     uint32_t timeout = 1000U;   // timeout
00074     if (config.conversion_mode == CONV_MODE_ONE_SHOT) {
00075         // trigger for starting conversion
00076         buf[0] = config_byte + RDY_BIT;
00077         _i2c.write((int)mcp3425_addr, (char *)buf, 1);
00078     }
00079     do {
00080         _i2c.read( (int)mcp3425_addr, (char *)buf, 3);
00081         if ((buf[2] & RDY_BIT) == 0) {  // check Config. reg. Ready bit
00082             break;      // end of conversion (RDY = 0)
00083         }
00084         if (--timeout == 0) {
00085             return -1;  // timeout then error
00086         }
00087         uint8_t spd = (buf[2] >> 2) & 0x03; // get current sampling rate
00088         if (spd == SAMPLE_RATE_60SPS_14BIT) {   // wait next conversion period
00089             WAIT_MS(6);     // conversion time = 16.7ms
00090         } else if (spd == SAMPLE_RATE_15SPS_16BIT) {
00091             WAIT_MS(24);    // conversion time = 66.7ms
00092         } else {  // == SAMPLE_RATE_240SPS_12BIT
00093             WAIT_MS(2);     // conversion time = 4.2ms
00094         }
00095     } while(true);
00096     dt_adc16 = (uint16_t)buf[0] << 8;   // High byte
00097     dt_adc16 += (uint16_t)buf[1];       // Low byte
00098     return dt_adc16;
00099 }
00100 
00101 float MCP3425::read_voltage()
00102 {
00103     float dt16 = (float)read_16bit();
00104     switch(config.sample_rate) {
00105         case SAMPLE_RATE_240SPS_12BIT:
00106             dt16 /=  2048.0f; // 11bit (0x7ff +1)
00107             break;
00108         case SAMPLE_RATE_60SPS_14BIT:
00109             dt16 /= 16384.0f; // 14bit (0x3fff +1)
00110             break;
00111         case SAMPLE_RATE_15SPS_16BIT:
00112             dt16 /= 32768.0f; // 15bit (0x7fff +1)
00113             break;
00114         default:
00115             return -1;      // error
00116     }
00117     switch(config.pga_gain) {
00118         case PGA_GAIN_1:
00119             dt16 /= 1.0f;
00120             break;
00121         case PGA_GAIN_2:
00122             dt16 /= 2.0f;
00123             break;
00124         case PGA_GAIN_4:
00125             dt16 /= 4.0f;
00126             break;
00127         case PGA_GAIN_8:
00128             dt16 /= 8.0f;
00129             break;
00130         default:
00131             return -1;      // error
00132     }
00133     dt_adc_f = dt16 * 2.048f;       // Vref = 2.048V +/- 0.05%
00134     dt_adc_f -= offset_volt;        // adjust offset voltage
00135     dt_adc_f *= compensation_ref;   // compensate Vref deviation
00136     return dt_adc_f;
00137 }
00138 
00139 void MCP3425::set_offset_volt(float offset)
00140 {
00141     offset_volt = offset;
00142 }
00143 
00144 void MCP3425::set_vref_compensation(float compensation)
00145 {
00146     compensation_ref = compensation;
00147 }
00148 
00149 void MCP3425::set_config(mcp3425_config_t *parameter)
00150 {
00151     config.pga_gain = parameter->pga_gain & 0x03;
00152     config.sample_rate = parameter->sample_rate & 0x03;
00153     config.conversion_mode = parameter->conversion_mode & 0x01;
00154     config_byte = convert_config2byte(&config);
00155     buf[0] = config_byte;
00156     _i2c.write((int)mcp3425_addr, (char *)buf, 1);
00157 }
00158 
00159 void MCP3425::read_config(mcp3425_config_t *parameter)
00160 {
00161     _i2c.read( (int)mcp3425_addr, (char *)buf, 3);
00162     config_byte = buf[2] & 0x1f;
00163     parameter->pga_gain = config_byte & PGA_GAIN_BIT;
00164     parameter->sample_rate  = (config_byte & SAMPLE_RATE_BIT) >> 2;
00165     parameter->conversion_mode  = (config_byte & CONVERSION_MODE_BIT) >> 4;
00166     config = *parameter;
00167 }
00168 
00169 void MCP3425::frequency(uint32_t hz)
00170 {
00171     _i2c.frequency(hz);
00172 }
00173 
00174 uint8_t MCP3425::convert_config2byte(mcp3425_config_t *config)
00175 {
00176     uint8_t byte = config->pga_gain;
00177     byte |= config->sample_rate << 2;
00178     byte |= config->conversion_mode << 4;
00179     config_byte = byte;
00180     return config_byte;
00181 }