Arduino Due ADC Referrence Voltage

Hi, I am newbie here… I have made a due oscilloscope with sampling rate of 1Mbps (refering to Fast analogRead with Arduino Due ) and display the signal on matlab via Xbee… the Due is working perfectly fine and give me a wonderful sampling rate… but I can’t manage to measure a sine wave signal with 3.3V peak-to-peak (1.5V DC offset)…

I converted the digital value to analog value by formula (Analog_value=Digital_value/4095 *3.3) and this is what i got


Fig.1: input sine wave signal of 3.3V peak-to-peak (1.5V DC offset)


Fig 2: input sine wave signal of 1.5V peak-to-peak (0.75V DC offset)

Fig2 shows a proper sine wave with 3Vpp (but actualy input signal is 1.5Vpp) while Fig1 shows only negative half cycle and the positive cycle was distorted. I conclude that the adc voltage is only limted from 0~1.5V or maybe 1.65V… How can i increase it to 3.3V? i did connect the AREF pin to 3.3V pin but it didnt work…analogreference() function is not valid for arduino due… Thanks.

My codes are as following:

unsigned long start_time;
unsigned long stop_time;
unsigned long values[1000];

void setup() {        
  Serial.begin(9600);  

  REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000;
  ADC->ADC_MR |= 0x80;  //set free running mode on ADC
  ADC->ADC_CHER = 0x80; //enable ADC on pin A0
}

void loop() {
  unsigned int i;
    
  start_time = micros();
  for(i=0;i<1000;i++){
    while((ADC->ADC_ISR & 0x80)==0); // wait for conversion
    values[i]=ADC->ADC_CDR[7]; //get values
  }
  stop_time = micros();

  Serial.print("Total time: ");
  Serial.println(stop_time-start_time); 
  Serial.print("Average time per conversion: ");
  Serial.println((float)(stop_time-start_time)/1000);

  Serial.println("Values: ");
  for(i=0;i<1000;i++) {
    Serial.println(values[i]);
    delay(20);
    
  }
  
  delay(2000);
}

the conversion formula is done in matlab program.

Look at that! [ i ] Italics!
(Please use [ code ] tags.)

The on-chip A/D can only read positive voltages between 0V and +VRef. To read an AC signal centered on 0V, you need to level-shift the input signal, using an op-amp, to shift it up by 0.5 VRef.

Regards,
Ray L.

MorganS:

Look at that! [ i ] Italics!

(Please use [ code ] tags.)

Thank you for the guidance.. :slight_smile:

RayLivingston:
The on-chip A/D can only read positive voltages between 0V and +VRef. To read an AC signal centered on 0V, you need to level-shift the input signal, using an op-amp, to shift it up by 0.5 VRef.

Regards,
Ray L.

Hi Ray L.,

Yes. I did shift the signal..I can configure the signal from the signal generator. The default Vcc of Arduino Due is 3.3V so I expect my the ADC can take a signal range 0~3.3V.

Unfortunately, the positive cycle of a sine wave signal with 3.3Vpp (centered at 1.65V) got distorted (in Fig 1) while a sine wave with 1.5Vpp (centered at 0.75V) had no distortion but the amplitude was wrong (i got 3Vpp instead of 1.5Vpp by using formula (Analog_value=Digital_value/4095 *3.3) ) (Fig2)..when the signal is 1.5V, the ADC gives me a value around 4095 but I would expect 4095 stands for 3.3V voltage.. any idea how to redefine the Vref..

Do away with the AC component, and just set the input to 1.65V, as measured AT the A/D input pin. What does the A/D read? It should be ~2048. 3.3V should give you ~4095, and 0V should give you ~0. If that all works, then there is something wrong with your level shifter. Since you said "when the signal is 1.5V, the ADC gives me a value around 4095, my money us on a problem with your level shifter, as that reading is clearly wrong for that input voltage.

Regards,
Ray L.