increase ADC-speed on 4809

Hi,

I need a higher ADC speed in my project as the analogRead function provides. I need to read 4 Sensors. In the standard configuration the duration of ADC coversion is approx. 600µS.

If I change the prescaler to div2 it the conversion time will be 130µS but the values are incorrect. Does anyone have an idea how to speed up the ADC?

Thanks a lot.
Ben

Here is the sketch:

const int Iin_Pin = A0;
const int Iout_Pin = A1;

const int Uout_Pin = A3; // A7;   //A7 auf PCB, vor Entkoppeldiode, nicht an Batterie. A3 händisch verkabelt
const int Uin_Pin = A6;
const int DebugPin = 7;

float inputVoltage  = 0.0;
float outputVoltage = 0.0;
float inputCurrent = 0.0;
float outputCurrent = 0.0;



void setup() {

  pinMode(DebugPin, OUTPUT);

  pinMode(Iin_Pin, INPUT);
  pinMode(Iout_Pin, INPUT);
  pinMode(Uout_Pin, INPUT);
  pinMode(Uin_Pin, INPUT);


  //ADC

  //ADC0.CTRLC = ADC_PRESC_DIV16_gc;
  //ADC0.CTRLB = ADC_SAMPNUM_ACC4_gc;
  
  VREF_CTRLA = VREF_AC0REFSEL_0V55_gc     /* Voltage reference at 0.55V */
               | VREF_ADC0REFSEL_4V34_gc; /* Voltage reference at 4.34V */

  VREF_CTRLB = 1 << VREF_ADC0REFEN_bp   /* ADC0 reference enable: enabled */
               | 0 << VREF_AC0REFEN_bp; /* AC0 DACREF reference enable: disabled */



  ADC0.CTRLA = 1 << ADC_ENABLE_bp     /* ADC Enable: enabled */
               | 0 << ADC_FREERUN_bp  /* ADC Freerun mode: enabled */
               | ADC_RESSEL_10BIT_gc  /* 10-bit mode */
               | 0 << ADC_RUNSTBY_bp; /* Run standby mode: disabled */

  //Ende ADC


  Serial.begin(115200);

}

void loop() {
  digitalWrite(DebugPin, HIGH);

  //********************************INPUT VOLTAGE********************************
  //******************************************************************************

  ADC0.MUXPOS  = ADC_MUXPOS_AIN4_gc;
  ADC0_COMMAND |= ADC_STCONV_bm;

  // Wait for it to finish. Alternatively, use the interrupt flag RESRDY in ADC0_INTFLAGS.
  while (ADC0_COMMAND & ADC_STCONV_bm) {
  }

  int Sensorwert = 0;
  Sensorwert = ADC0_RES;
  inputVoltage  = (Sensorwert / 1024.0) * 4.3;
  inputVoltage  = inputVoltage  * 5.525;//da Spannungsteiler  100K--22k1 (122,1K%22,1k = 5,525)

  //********************************OUTPUT VOLTAGE********************************
  //******************************************************************************
  ADC0.MUXPOS  = ADC_MUXPOS_AIN0_gc;
  ADC0_COMMAND |= ADC_STCONV_bm;

  // Wait for it to finish. Alternatively, use the interrupt flag RESRDY in ADC0_INTFLAGS.
  while (ADC0_COMMAND & ADC_STCONV_bm) {
  }

  Sensorwert = 0;
  Sensorwert = ADC0_RES;
  outputVoltage  = (Sensorwert / 1024.0) * 4.3;
  outputVoltage  = outputVoltage  * 5.525;//da Spannungsteiler  100K--22k1 (122,1K%22,1k = 5,525)


  //********************************INPUT CURRENT********************************
  //******************************************************************************
  ADC0.MUXPOS  = ADC_MUXPOS_AIN3_gc;
  ADC0_COMMAND |= ADC_STCONV_bm;

  // Wait for it to finish. Alternatively, use the interrupt flag RESRDY in ADC0_INTFLAGS.
  while (ADC0_COMMAND & ADC_STCONV_bm) {
  }

  Sensorwert = 0;
  Sensorwert = ADC0_RES;
  inputCurrent  = (Sensorwert / 1024.0) * 4.3;
  inputCurrent  = inputCurrent  * 5.525;//da Spannungsteiler  100K--22k1 (122,1K%22,1k = 5,525)

  //********************************OUTPUT Current********************************
  //******************************************************************************

  ADC0.MUXPOS  = ADC_MUXPOS_AIN2_gc;
  ADC0_COMMAND |= ADC_STCONV_bm;

  // Wait for it to finish. Alternatively, use the interrupt flag RESRDY in ADC0_INTFLAGS.
  while (ADC0_COMMAND & ADC_STCONV_bm) {
  }

  Sensorwert = 0;
  Sensorwert = ADC0_RES;
  outputCurrent  = (Sensorwert / 1024.0) * 4.3;
  outputCurrent  = outputCurrent  * 5.525;//da Spannungsteiler  100K--22k1 (122,1K%22,1k = 5,525)





  digitalWrite(DebugPin, LOW);

  Serial.print("inputVoltage: ");
  Serial.println(inputVoltage);

  Serial.print("inputCurrent: ");
  Serial.println(inputCurrent);

  Serial.print("outputVoltage: ");
  Serial.println(outputVoltage);

  Serial.print("outputCurrent: ");
  Serial.println(outputCurrent);

  Serial.println("");
  delay(100);

}

The datasheet for the chip shows it has two modes, 10 bit and 8 bit. Only 8 bit supports fast conversions I think...

Hi Marc,

thanks for the reply. I think the 8Bit conversion is faster, but I really need the 10Bit accuracy. The description in the Datasheet tells me a sample rate of 150ks/s.

Datasheet information: One 10-bit 150 ksps Analog-to-Digital Converter (ADC)

A ADC conversion with 150ks/s should take less than 10µs or am I wrong?

I would be totally happy if I could achieve a conversion time for 4 channels of less than 150µs.

The datasheet says 115kSPS for 10 bit and the 1.1V reference, for the 0.55V reference and 10 bit the limit is 20kSPS, table 5-21 in the short-form datasheet.

You'll have to look in the Arduino code to see how it talks to the ADC for that chip, and probably consult the long datasheet, section 28. Note the ADC has two modes, free-running and single conversion, and the timings for them will be different.