Problems with teensy 4.1 ADC signal – connecting to the wrong ground?

powerfly

Active member
Hi everyone,

I’m trying to get a teensy 4.1 to be used as a datalogger in place of different, physically larger micro-controller. I’m testing it out, and it seems that the code side of things is ok (it’s recording samples at the correct rate and storing them to a card), but when I try to get a signal from a signal generator, I’m getting a lot of noise. I’m suspicious of there being some issue with whether I’m using the right ground pin, and if it’s treating some ADC channels as floating.

I’m currently using channels 14-25 to be used to collect 12 bit data with a sampling rate of 10 kHz. Data is being stored to a micro-SD card and it’s using a buffer to achieve the high sampling rate.

If you look on the picture below, the pins with X’s on them are the pins that are connected.

teensy_pins_I_am_using.jpg

I’m powering the Teensy with a 5V power supply on a Vin and GND pin that is closes to the micro-USB connection. The connection between 3.3 V and pin 2 is just a button to get the datalogger to start recording. A signal generator is connected to pin 17 (and is connected to the GND pin I mentioned previously to get a common ground) and I’m doing a 100 Hz, 1V p2p, offset by 1V signal. When the signal generator is turned on, the signal read for pin 17 is correct, but several other channels have incorrect readings – showing a lot of noise. I don’t think this is due to the environment as I have run the same test on an oscilloscope and another microcontroller datalogger, and they show the data being absolutely fine. I think something is wrong with the GND, and it being as if the other pins are floating (or something like that). When no signal is coming from the signal generator, the signal is incorrect, it's not coming in at zero.

pin 17 (the one connected to the signal generator):
signal_generator_teensy_data.png
(the y axis is the number of bits - 4096 being equivalent to 3.3 V I believe)

neighbouring pin 18:
signal_generator_teensy_data_ch18.png

pins 14 and 21 respectively (other pins being recorded that just give the wrong voltage reading back):
signal_generator_teensy_data_ch_14.png
signal_generator_teensy_data_ch_21.png

Any help or direction for this would be greatly appreciated. I have collected data on the Teensy, the other micro controller and the oscilloscope multiple different times and got the same result, so I really don't think it is ambient noise.
 
When the signal generator is off you have a floating input I think - don't do that, just turn the signal generator amplitude down to zero.

Be careful with this setup, the Teensy pins will absolutely not tolerate negative voltage and you'll destroy the chip immediately if you accidentally use the wrong offset.

I'd always use a protection circuit for something like this, the classic 2 schottky's and a series resistor.
 
When the signal generator is off you have a floating input I think - don't do that, just turn the signal generator amplitude down to zero.

Be careful with this setup, the Teensy pins will absolutely not tolerate negative voltage and you'll destroy the chip immediately if you accidentally use the wrong offset.

I'd always use a protection circuit for something like this, the classic 2 schottky's and a series resistor.

Thanks for the replies!

A floating input should usually give back 0 V though right? there is still a stable GND from the power supply I think. At least when I do this with another micro-controller data logger, it just gives back a signal of 0 V with little noise. You are right about it being dangerous with the current negative voltage setup, I should probably change that. I'll look into protection circuits as I haven't used them before.
 
A floating input is undefined/hi-Z, so expect a lot of noise from pickup and any DC offset is possible.
 
A floating input is undefined/hi-Z, so expect a lot of noise from pickup and any DC offset is possible.

Thanks for replying Mark. I'm trying to understand what you're saying, but must confess that I'm not very knowledgeable about electronics so don't fully understand you. if you are saying the floating input is high z, why would that mean there is more noise from 'pickup'?

Also does 'more noise from pickup' just mean it will pick up the surrounding noise and make a bigger deal of it?

also, would this mean that if I have a proper voltage input on the other channels (e.g. with other signal generators), there wouldn't actually be very much noise? If so, maybe I don't need to worry so much. The reason I ask is that I'm going to make a signal conditioning circuit, but wanted to suss out any issues before making a custom board, waiting for it to arrive etc. and to isolate any problems that aren't due to my design of the signal conditioning board.

again thanks, I appreciate the reply and the help.
 
Z is impedance (generalization of resistance). High-Z means high impedance, so very tiny currents have a massive effect on voltage - for CMOS this is a very big effect as impedances can be upto 10^14 ohms in the extreme cases (yes, 100 million million ohms, so even picoamps of current noise have large effect). In practice this means a floating input just senses the electric field around it from neighbouring pins and traces rather like an antenna or electroscope.

Try adding 10k resistor to ground on the input so it isn't high-Z any more - the signal generator won't have any trouble handling 10k, but environmental voltage noise will be effectively shorted out to ground by it.

Incidentally you may see logic chips sometimes described as "tristate", meaning the output(s) have 3 states, high, low and high-Z (floating). Inputs for CMOS are always floating if not connected to something that actively drives them(*). Many circuits when powered down have their outputs as high-Z (though only upto +/- one diode drop, ie +/- 0.5V or so).

(*) actually not quite true, some chips have build-in pull-up or pull-down resistors on some inputs as floating inputs are often a headache to deal with. Its always best to connect every input high or low in a CMOS logic chip rather than let any float.
 
When the signal generator is off you have a floating input I think - don't do that, just turn the signal generator amplitude down to zero.

I tried plugging in an adjacent channel to the signal generator with a flat, constant voltage signal and still got a lot more noise than expected (and a lot more noise than with the other oscilloscopes/data loggers I tried), but it was an improvment from before (although that's not saying much). It's the bit with the least noise on the right hand graph here:

Skärmbild 2023-10-12 002310.jpg

the left hand signal is the signal generator channel that is giving a 100 Hz wave, which looks ok when it is on, but is noisy when off as before.

why do you think the noise is still so large (given that it's probably not external EM interference)?

I'll try some other stuff soon
 

Attachments

  • Skärmbild 2023-10-12 002310.jpg
    Skärmbild 2023-10-12 002310.jpg
    42.3 KB · Views: 24
Floating inputs don't just pick up noise (a microcontroller is _extremely_ noisy, full of high frequency square waves everywhere). Floating inputs can also oscillate by themselves sometimes (though if they have a decent amount of hysteresis this is less likely).

If you are expecting a CMOS floating input to behave nicely, you will likely be disappointed. The input FETs are likely 10^12 ohms and a few 1pF and a few microns from an internal clock signal...
 
Floating inputs don't just pick up noise (a microcontroller is _extremely_ noisy, full of high frequency square waves everywhere). Floating inputs can also oscillate by themselves sometimes (though if they have a decent amount of hysteresis this is less likely).

If you are expecting a CMOS floating input to behave nicely, you will likely be disappointed. The input FETs are likely 10^12 ohms and a few 1pF and a few microns from an internal clock signal...

Is there a way to mitigate this? according to the PJRC website, the analog inputs are usable up to 10 bit resolution (basically 0.1% accuracy) if I'm understanding the description propelry. from https://www.pjrc.com/store/teensy41.html I will quote:

"Analog Inputs
18 pins can be used an analog inputs, for reading sensors or other analog signals. Basic analog input is done with the analogRead function. The default resolution is 10 bits (input range 0 to 1023), but can be adjusted with analogReadResolution. The hardware allows up to 12 bits of resolution, but in practice only up to 10 bits are normally usable due to noise. More advanced use is possible with the ADC library."

what I'm currently getting is way more than than 10 bits of noise, and I wasn't getting any near as much noise when I did tests with a datalogging microcontroller in the same envrionment. if the noise level is stuck at the bit circled in red, the data is about 5 bit resolution, not 10 bit. Sorry if I'm misunderstanding anything, as I'm quite new to this side of things.
 
Last edited:
Nothing to mitigate, if the input is floating, its floating - that's how the physics works... Until you connect a signal to it or provide a suitable impedance to ground it will sniff the air for its voltage very efficiently.

Your datalogger would have have had a load impedance perhaps. Did you add the 10k resistor I suggested?
 
Nothing to mitigate, if the input is floating, its floating - that's how the physics works... Until you connect a signal to it or provide a suitable impedance to ground it will sniff the air for its voltage very efficiently.

Your datalogger would have have had a load impedance perhaps. Did you add the 10k resistor I suggested?

Sorry if I'm just misunderstanding you, but I thought my input wasn't floating (in the bit that is circled in red). There it is connected to a signal generator that is turned on at a fixed offset voltage, and the signal generator shares a common ground with the GND pin of the teensy. As far as I can tell (I might be missing something), I'm following your advice here:

When the signal generator is off you have a floating input I think - don't do that, just turn the signal generator amplitude down to zero.

but I'm still getting lots of noise. see the red bit on this graph - then the signal generator is on so I don't think it's floating:



I haven't yet done the resistor thing, but I can try that in my school's labs on Monday.

Thank you for your continued help and patience, it is appreciated :)
 
Nothing to mitigate, if the input is floating, its floating - that's how the physics works... Until you connect a signal to it or provide a suitable impedance to ground it will sniff the air for its voltage very efficiently.

Your datalogger would have have had a load impedance perhaps. Did you add the 10k resistor I suggested?

Hi Mark, thanks for your continued support. I tried linking up the 10k resistor, and the noise did not subside. in the diagram below, the circled red bit should have essentially a flat signal - the p2p of the noise is about 100 divisions of the 12 bit logged data. It says the data is supposed to be a functional 10 bits on the description.

Skärmbild 2023-10-19 162504.png


I tried logging data with the teensy in an aluminium box (to act as a faraday cage), and that also didn't help. Is there a problem with how it's collecting data, is there some way to help with the coding?
 
Clearly that pin is not floating as adding the 10k resistor didn't bring it down to 0V - so its connected to some signal source?
 
Clearly that pin is not floating as adding the 10k resistor didn't bring it down to 0V - so its connected to some signal source?

Hi, sorry if I was being unclear there. I have been trying to see if I can minimise noise when it is connected to a clean signal, as that seems like it should be easier than when the signal is floating. I replied to your comment to say that I have tried connectin the 10k resistor but it did not make a difference. I have used a signal generator with an offset voltage, and then turned the amplitude down such that the signal should basically be flat for the bit circled in red. despite that, there is a lot of noise - making the data functionally about 7-bit. To my mind, I cannot currently see why the data should have so much noise given the conditions (have tried putting it in an alu box to act as a Faraday cage, there doesn't appear to be external signals from outisde providing much noise etc.).
 
First things first: are you using pinMode() to set all your ADC pins to INPUT_DISABLE (to disable the digital input schmitt trigger) ?

You never answered this question. If you could please show your configuration code from setup(), and how you are reading the analog inputs (could be analogRead or the ADC library), that might be helpful.
 
One suggestion that I haven't seen so far is to use two (or more) ground pins.
Currently your signal generator is using the same ground pin as your power supply. In theory this shouldn't matter but depending on the exact layout splitting them could help reduce power supply noise coupling into the ADC ground.
 
You never answered this question. If you could please show your configuration code from setup(), and how you are reading the analog inputs (could be analogRead or the ADC library), that might be helpful.

sorry for the delayed reply.

the setup code is:

pinMode(2, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(2), myfunction, RISING);
for (int i = 0; i < PINS; i++) {
pinMode(adc_pins, INPUT_DISABLE);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
Serial.begin(2000000);
///// ADC0 ////
adc->adc0->setAveraging(1); // set number of averages
adc->adc0->setResolution(12); // set bits of resolution
adc->adc0->setConversionSpeed(
ADC_CONVERSION_SPEED::HIGH_SPEED ); // change the conversion speed
adc->adc0->setSamplingSpeed(
ADC_SAMPLING_SPEED::VERY_HIGH_SPEED ); // change the sampling speed

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
adc->adc1->setAveraging(1); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
adc->adc1->setConversionSpeed(
ADC_CONVERSION_SPEED::HIGH_SPEED ); // change the conversion speed
adc->adc1->setSamplingSpeed(
ADC_SAMPLING_SPEED::HIGH_SPEED ); // change the sampling speed
#endif
delay(500);


This is how we read the ADC pins:

for (int i = 0; i < PINS; i++)
{
temp_data= adc->analogRead( adc_pins);
current_buffer_size++;
data_[buffer_selection][current_buffer_size] = (uint8_t) temp_data;
current_buffer_size++;
data_[buffer_selection][current_buffer_size] = (uint8_t) (temp_data>>8);
}

any ideas on whether this would cause the signal read to be noisy?
 
sorry for the delayed reply.

the setup code is:

pinMode(2, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(2), myfunction, RISING);
for (int i = 0; i < PINS; i++) {
pinMode(adc_pins, INPUT_DISABLE);
}
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
Serial.begin(2000000);
///// ADC0 ////
adc->adc0->setAveraging(1); // set number of averages
adc->adc0->setResolution(12); // set bits of resolution
adc->adc0->setConversionSpeed(
ADC_CONVERSION_SPEED::HIGH_SPEED ); // change the conversion speed
adc->adc0->setSamplingSpeed(
ADC_SAMPLING_SPEED::VERY_HIGH_SPEED ); // change the sampling speed

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
adc->adc1->setAveraging(1); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
adc->adc1->setConversionSpeed(
ADC_CONVERSION_SPEED::HIGH_SPEED ); // change the conversion speed
adc->adc1->setSamplingSpeed(
ADC_SAMPLING_SPEED::HIGH_SPEED ); // change the sampling speed
#endif
delay(500);


This is how we read the ADC pins:

for (int i = 0; i < PINS; i++)
{
temp_data= adc->analogRead( adc_pins);
current_buffer_size++;
data_[buffer_selection][current_buffer_size] = (uint8_t) temp_data;
current_buffer_size++;
data_[buffer_selection][current_buffer_size] = (uint8_t) (temp_data>>8);
}

any ideas on whether this would cause the signal read to be noisy?


Using HIGH_SPEED conversion and VERY_HIGH_SPEED sampling will cause the readings to be noisier than if you use slower settings. Unless you need a very high sampling rate, you should use slower settings.
 
One suggestion that I haven't seen so far is to use two (or more) ground pins.
Currently your signal generator is using the same ground pin as your power supply. In theory this shouldn't matter but depending on the exact layout splitting them could help reduce power supply noise coupling into the ADC ground.

I tried using different ground pins. Thanks for the suggestion, it looks like it might have improved things slightly:

same ground pin:

1_gnd_pin.png

using 2 different GND pins:

2_gnd_pins.png


As you can see, there is still, however a lot of noise :/



Which signal generator are you using? Perhaps a photo of the setup?

here is a picture of the setup:

setup.jpg

Here is the waveform generator I'm using (a keysight 33500B - a pretty expensive one):

wave_Form_generator.jpg

Here is the voltage source:

voltage_source.jpg

Here is the Teensy (when using 1 GND pin):

Teensy.jpg

I've tried using the waveform generator on an oscilloscope and another microcontroller that does data logging, and have not received anywhere near the same amount of noise.
 
How much noise do you see if you add a capacitor between the analog pin and ground (say 100nF or so) ?
 
How much noise do you see if you add a capacitor between the analog pin and ground (say 100nF or so) ?
I tried this, and it didn't really seem to make a difference (I also had a resistor connected).
 

Attachments

  • Skärmbild 2023-12-08 173740.png
    Skärmbild 2023-12-08 173740.png
    30.7 KB · Views: 15
You may have a ground loop. You probably have an SD card that draws quite some current when writing. And you maybe use a power supply that is dipping when the Teensy draws more significant current.

I think the reference voltage for the ADC is the 3V3 rail. Is that a steady 3.30 V or does it have ripple order of magnitude of what you see as ADC values noise?

On ground loop: draw a schematic and add say 1 ohm series resistor in your brown GND wire. You will then see that when the power supply current rises by say 50 mA that your Teensy pin 1 GND level rises 50 mV above what you assumed was 0. And then your ADC reports 50 mV ’error’.

Tests to do:
* wire a 1.5V battery to your Teensy ADC input pin (+) and to Teensy GND (-) directly, but don’t let the same wires carry power supply current. Do you then still see these weird excursions?
* better/other 5v power supply.
* no SD card, but write to Teensy RAM or flash disk instead.

Better would be to use ADC in differential input mode.

Unclear from what’s posted is what triggers ADC sampling and conversion (a timer interrupt so that it’s deterministic?), what upstream analog anti-alias filter you use, as in order and cutoff frequencies, what (if any at all) oversampling you have in the Teensy, and what the source output impedance of the analog voltage signal is.
 
You may have a ground loop. You probably have an SD card that draws quite some current when writing. And you maybe use a power supply that is dipping when the Teensy draws more significant current.

I think the reference voltage for the ADC is the 3V3 rail. Is that a steady 3.30 V or does it have ripple order of magnitude of what you see as ADC values noise?

On ground loop: draw a schematic and add say 1 ohm series resistor in your brown GND wire. You will then see that when the power supply current rises by say 50 mA that your Teensy pin 1 GND level rises 50 mV above what you assumed was 0. And then your ADC reports 50 mV ’error’.
Thanks for the suggestions. The voltage source I was using can give up to 5 A, so I would be surprised if the powersupply was struggling with a Teensy alone. I think you are right that the reference voltage is GND and the 3.3 V on the Teensy. I know the range you should use on the Teensy should not go above 3.3 V.

for your thought experiment, I think that would only be the case if the signal generator was on the other side of the 1 ohm resistor right? otherwise the power across the Teensy would just be 4.95 V if it was dropping 50 mV across the the resistor at the end.

Tests to do:
* wire a 1.5V battery to your Teensy ADC input pin (+) and to Teensy GND (-) directly, but don’t let the same wires carry power supply current. Do you then still see these weird excursions?
* better/other 5v power supply.
* no SD card, but write to Teensy RAM or flash disk instead.

Better would be to use ADC in differential input mode.

Unclear from what’s posted is what triggers ADC sampling and conversion (a timer interrupt so that it’s deterministic?), what upstream analog anti-alias filter you use, as in order and cutoff frequencies, what (if any at all) oversampling you have in the Teensy, and what the source output impedance of the analog voltage signal is.
Just to make sure, are you in agreement that the issue that we are looking at is the noise level, not the change in voltage when I plug/unplug a voltage source/signal generator. i.e. the bit circled in red:

Skärmbild 2023-12-15 163238.png


I did experiments 1 and 2. In both cases the noise level remained:

experiment 1 (I used a different GND terminal to connect the GND of the 1.5 V battery):
Skärmbild 2023-12-15 163302.png


Experiment 2 (I used a power bank, as opposed to the cleaner and more expensive voltage supply, noise levels looked about the same):
Datalog49_using_portable_voltage_pack.png


the data shown is pre-filtering. I can filter away some noise, but it looks pretty uniformly distributed across the FFTs, so getting rid of more of it here would be helpful.

Can you please explain why it's better to use the ADC in differential input mode? Is there an intuitive reason to why this is the case?

Thanks again for all of your suggestions, I appreciate you putting in the time for this.
 
Back
Top