Testprogramm für die ADC Einstellungen des MCP3424. Code ist für Arduino nach der Vorlage des AVR C Compiler von Mikroelektronika.
#include <Wire.h> // I2C address for MCP3422 - base address for MCP3424 #define MCP3422_ADDRESS 0X68 // fields in configuration register #define MCP342X_GAIN_FIELD 0X03 // PGA field #define MCP342X_GAIN_X1 0X00 // PGA gain X1 #define MCP342X_GAIN_X2 0X01 // PGA gain X2 #define MCP342X_GAIN_X4 0X02 // PGA gain X4 #define MCP342X_GAIN_X8 0X03 // PGA gain X8 #define MCP342X_RES_FIELD 0X0C // resolution/rate field #define MCP342X_RES_SHIFT 2 // shift to low bits #define MCP342X_12_BIT 0X00 // 12-bit 240 SPS #define MCP342X_14_BIT 0X04 // 14-bit 60 SPS #define MCP342X_16_BIT 0X08 // 16-bit 15 SPS #define MCP342X_18_BIT 0X0C // 18-bit 3.75 SPS #define MCP342X_CONTINUOUS 0X10 // 1 = continuous, 0 = one-shot #define MCP342X_CHAN_FIELD 0X60 // channel field #define MCP342X_CHANNEL_1 0X00 // select MUX channel 1 #define MCP342X_CHANNEL_2 0X20 // select MUX channel 2 #define MCP342X_CHANNEL_3 0X40 // select MUX channel 3 #define MCP342X_CHANNEL_4 0X60 // select MUX channel 4 #define MCP342X_START 0X80 // write: start a conversion #define MCP342X_BUSY 0X80 // read: output not ready
//------------------------------------------------------------------------ // default adc configuration register - resolution and gain added in setup() #include "WProgram.h" void halt(void); uint8_t mcp342xWrite(uint8_t config); void setup(); void loop(); uint8_t adcConfig = MCP342X_START | MCP342X_CHANNEL_1 | MCP342X_CONTINUOUS; // divisor to convert ADC reading to milivolts uint16_t mvDivisor; //------------------------------------------------------------------------------
void halt(void) { Serial.println("Halted"); while(1); } //------------------------------------------------------------------------------
// read mcp342x data uint8_t mcp342xRead(int32_t &data) { // pointer used to form int32 data uint8_t *p = (uint8_t *)&data; // timeout - not really needed? uint32_t start = millis(); //do { // assume 18-bit mode Wire.requestFrom(MCP3422_ADDRESS, 4); if (Wire.available() != 4) { Serial.println("read failed"); return false; } for (int8_t i = 2; i >= 0; i--) { p[i] = Wire.receive(); } // extend sign bits p[3] = p[2] & 0X80 ? 0XFF : 0; // read config/status byte uint8_t s = Wire.receive(); if ((s & MCP342X_RES_FIELD) != MCP342X_18_BIT) { // not 18 bits - shift bytes for 12, 14, or 16 bits p[0] = p[1]; p[1] = p[2]; p[2] = p[3]; } // if ((s & MCP342X_BUSY) == 0) return true; // } while (millis() - start < 100); //allows rollover of millis() // Serial.println("read timeout"); // return false; return true; } //------------------------------------------------------------------------------
// write mcp342x configuration byte uint8_t mcp342xWrite(uint8_t config) { Wire.beginTransmission(MCP3422_ADDRESS); Wire.send(config); Wire.endTransmission(); }
//------------------------------------------------------------------------------ void setup() { Serial.begin(9600); Wire.begin(); uint8_t chan = 0XFF, gain = 0XFF, res = 0XFF; do { Serial.flush(); Serial.print("\nEnter channel (1, 2, 3, 4): "); while (Serial.available() == 0); chan = Serial.read() - '1'; } while(chan > 3); Serial.println(chan + 1, DEC); do { Serial.println(); Serial.flush(); Serial.print("Enter gain (1, 2, 4, or 8): "); while(Serial.available() < 1); switch (Serial.read()) { case '1': gain = 0; break; case '2': gain = 1; break; case '4': gain = 2; break; case '8': gain = 3; break; } } while (gain > 3); Serial.println(1 << gain, DEC); do { Serial.flush(); Serial.println(); Serial.print("Enter resolution (12, 14, 16, or 18): "); while (Serial.available() < 2); if (Serial.read() != '1') continue; switch (Serial.read()) { case '2': res = 0; break; case '4': res = 1; break; case '6': res = 2; break; case '8': res = 3; break; } } while (res > 3); Serial.println(12 + 2*res, DEC); adcConfig |= chan << 5 | res << 2 | gain; // divisor to convert ADC reading to millivolts mvDivisor = 1 << (gain + 2*res); } //------------------------------------------------------------------------------
void loop() { // Really only needed write once in continuous mode. Could be moved to setup. mcp342xWrite(adcConfig); int32_t data; if (!mcp342xRead(data)) halt(); // voltage in millivolts double mv = (double)data/mvDivisor; // convert reading to microvolts int32_t uv = (data*1000L)/mvDivisor; Serial.print(mv);Serial.print(" mv, "); Serial.print(uv);Serial.println(" uv"); delay(1000); }
int main(void) { init(); setup(); for (;;) loop(); return 0; }