Teensy 3.6 Jumps in Voltage Acquisition ADC

Status
Not open for further replies.

Meo

Member
Hi

A Teensy 3.6 is used to digitize an analog voltage (in the code attached, it reads in PIN A20).
I have a very simple set-up where

1) the board is powered by the USB
2) I have connected a 1.6 Volt Battery to the A20 PIN.
3) I use two batteries in series (2x1.6 V) for the reference voltage.

I carry out repeated measurements in a loop.

The attached figures show that the signal jumps randomly at new acquisitions. Sometimes the jumps are at 2 mV. Under other conditions, I get jumps of 20 mV
I attached the source code as reference. It reads in the voltage at ADC1_RA which corresponds to the PIN A20
50 kSample / sec at 16 bit.
-- When I reduce either the bit depth or the ACQ rate, I still get these anomalies but at a lower level.
-- I tried a lower conversion speed and sampling speed and still get the same.

Really strange is that I get different levels by only compiling and uploading the code!

Can someone help on why this occurs? Has anyone seen such an anomaly?

Thank you in advance
 

Attachments

  • CalibrationSensor.ino
    3.7 KB · Views: 46
  • Folie1.PNG
    Folie1.PNG
    79.3 KB · Views: 76
  • Folie2.PNG
    Folie2.PNG
    124.6 KB · Views: 47
In additional to noise reducing hardware design, I use a median filter to reduce ADC noise. It also helps to disable the USB connection while sampling.

What is the purpose of "pinMode(adc_pin0, INPUT_PULLDOWN)" vs the usual "pinMode(adc_pin0, INPUT)"?
 
Thanks for the reply,

In a different setup, we actually disconnected the power portion of the USB and use an auxiliary power supply at 5V to power the micro controller.
The noise goes away, but the anomalies (Voltage jumps) are still present.

How can I disable the USB connection during sampling?

The code was written by my colleague who is not present. But I think because this is connected to a detector which is activated and deactivated. In any case, I changed it to pinMode(adc_pin0, INPUT) and still get the same anomaly.
 
I found that closing the serial monitor and storing data to ram helped with ADC noise. As did "VERY_LOW_SPEED". Be sure that you have low source impedance and avoid designs likely to pick up noise (like wire loops). Differential inputs fed by paired lines helps. What do you get if you tie the input to ground?

I used a teensy 3.2 (might be quite difference), but when doing all the right things and lots of oversampling, I was able to get > 13 bits.
 
Last edited:
How can we close the serial monitor?

I tried reducing the Sampling rate to VERY_LOW_SPEED and get the same

I just tried attaching the PIN to GND and get the following traces (attached).

Folie3.PNG

BTW, I simply convert the data to U.*3.3/(2^16 - 1); The reference voltage is not exactly 3.3, but I get these anomalies.
 
Warning: I am mostly a digital guy... But wondering how you have all of it hooked up?

That is is your setup to look at the analog value setup to use the Analog Ground? Or is your sample device (battery) setup to go through the normal ground?
 
Hi KurtE

Thanks for the reply

I tried jonr suggestion to connect the digitizing PIN to ground.

But my setup is as I described it in the first post where I have a breadboard and I simply connect a USB, a battery for the reference voltage and a battery on the PIN for digitization. I do connect the ground of the board to the common ground as well.

So to answer your question: yes all grounds (battery ground and Teensy ground GND) are connected to the common ground of our outlet.
 
I should have been more clear and said to tie the input to the analog ground. Which should be kept separate from other grounds.
 
Last edited:
Hi jonr

Thanks for the suggestion.
I just connected the Teensy Digital GND (first pin) to the common ground, then connected the (-) of the batteries to the Analog GND pin (second PIN).
I unfortunately still got the same anomaly. :-(

I am really perplexed! I have used other micro controllers before but I never had such a bad experience.
 
Again take this with a grain of salt...

But you might show a picture of your setup, to make sure there is nothing obvious going on.

Examples: like the T3.6 plugged into breadboard but the pins were not soldered to the T3.6... Or bad solder joints or ...

Again, sometimes it is hard to give other suggestions.

There are things in the code I would have a tendency to try changing.


Things like: your usage of uint16_t i...

It is changed in interrupt and looked at elsewhere... Probably needs to be volatile, not sure about some of the others.
 
Hello,

Thanks KurtE and jonr for your suggestions.
KurtE very important point. But I verified the connections already. But I did looked at the code in more detail and experimented.

I found the remedy to get rid of these jumps....

As the code shows, the adc->startSynchronizedContinuous(adc_pin0, adc_pin1); is in the loop() but is only activated when a start command is initiated sinput = Serial.parseInt();
Once a command is read, the data is stored in the buffer. Once the buffer is full, it deactivates the ADC adc->stopSynchronizedContinuous(); until the next command.

If I move the adc->startSynchronizedContinuous(adc_pin0, adc_pin1); outside the loop() and instead place it in the setup() which means the ADC will be always activated, the problem goes away! Of course I comment out the deactivation of the controller.

I am very relieved, but if anyone can explain to me why this occurs we would all learn something.

I would like to thank all who took time to post suggestions in this Thread

Best regards

Meo
 
You should use "volatile" on global variables that you modify in an interrupt service routine.
 
As I have written that the problem goes away when I place adc->startSynchronizedContinuous(adc_pin0, adc_pin1); in the setup()
Which means that the ADC is turned on only once and thus every time I make an acquisition it is stable.

However there is still a caveat. When I turn off the power of the microcontroller, and restart it again, it jumps again to another reference voltage.
I also get this when i recompile and upload the code which makes sense since the microcontroller temporarily stops and reactivates the ADC.

This means that every time I activate the ADC, there is a different voltage offset and it seems to be random.

I even place delay(10000) and get the same.

Can anyone shed light on this on what is going on?
 
@meo - Maybe on buffer1 but for sure in your original program, the global variable i. That is your code has(d):

Code:
void setFlagandReadBuf() {

 [COLOR="#FF0000"] i = 0;  [/COLOR]                      //to be repeated that we measured for time t
  unsigned long started = micros();
  while (micros() - started < t_rotation) { //while the intervall(micros()-started)
    flag = true;                          //is smaller than t_rotation flag = true
  }

  flag = false;

  [COLOR="#FF0000"]for (int q = 0; q < i; q++)  [/COLOR]         //send all values that were measured during t_rotation
  {
    Serial.println(buffer1[q]);         //first print out all values from ADC0
    delayMicroseconds(5);              //short break for serial port to "recover"
  }

  Serial.println("e");                  //nur bei t>=1s
}

So in that function, it sees, you set the value of i to 0 and then
the for loop it might decide that i is always 0 the optimizer might simply remove everything in that for loop...
 
You could put volatile on every variable used in the ISR. Whoops - I missed that Kurt already pointed out this issue in #10.
 
Thanks for the suggestions.
I defined volatile to my variables.

I still get these offsets every time I reactivate the ADC.
 
Status
Not open for further replies.
Back
Top