Arduino

MCP3424 Demo/Test Code

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;
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.