1
\$\begingroup\$

I use atmega328p. I'm trying to read data from a variable resistor using an ADC. The microcontroller also has LEDs connected. If I ignite them, the data from the ADC increases noticeably.

Initializing the ADC:

/***** ADC *****/
ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); //128
// 16MHz/128 = 125kHz
ADCSRA |= (1<<ADIE); //enable interrupt
ADCSRA |= (1<<ADEN); //enable adc
//ADMUX |= (1<<REFS0) | (1<<REFS1); //1.1В
ADMUX |= (1<<REFS0); //AVcc with capasitor as AREF pin

ADCSRA |= (1<<ADSC); //new start
ADMUX |= (1<<MUX0) | (1<<MUX2); //ADC5

How can I solve this problem?

I apologize for the scheme, but I do not have the right program at hand. enter image description here


Extra info due to answers:

  • In the normal state, the ADC value is 2. If I light the LED, the value is increased to 20. I changed the 220 Ω resistor to 1 kΩ, now value increases from 2 to 7. Voltage comes from USB 3.0.
  • In an attempt to make the PSU stronger I tried to solder the second USB connector and energize in parallel. Nothing changed.
\$\endgroup\$
6
  • \$\begingroup\$ Are you pulsing or pwm these LEDs? That would increase noise in the system. \$\endgroup\$
    – Nedd
    Commented Feb 24, 2018 at 11:40
  • \$\begingroup\$ I don't use PWM. Just set the high or low signal on the LED. \$\endgroup\$ Commented Feb 24, 2018 at 11:48
  • \$\begingroup\$ You did say LEDs, you currently show only one in your example. Another source of noise may come about if you are actively using one of the dual purpose I/O/ADC pins as digital outputs, (for example PC0, PC1, PC2, PC3), while performing a conversion. \$\endgroup\$
    – Nedd
    Commented Feb 24, 2018 at 13:18
  • 2
    \$\begingroup\$ @MaratGareev - (a) Please edit your question to add a clear, in-focus, close-up photo of your hardware, so that the connections to the MCU are visible. (b) Please explain exactly how you have connected power to pins 7, 8, 20, 21 and 22. (You could edit your diagram to give that information.) Have you only connected power to pins 7 and 8, for example? (c) Please add some details about how exactly the ADC readings change, when the LED is lit, or not. Show us examples of the numbers. \$\endgroup\$
    – SamGibson
    Commented Feb 24, 2018 at 13:26
  • \$\begingroup\$ What if you sink current instead of sourcing to the LEDs? "Turn around" the LED, connect to Vcc and see if it improves anything. \$\endgroup\$
    – filo
    Commented Feb 25, 2018 at 11:18

3 Answers 3

0
\$\begingroup\$

Some things to try:

Increase the value of the bypass caps on Aref, Vcc, and AVcc (p20) of the 328P.

Insure that the supply and ground path of the variable resistor are not directly inline with the supply or ground path of the LEDs.

Reduce the load on the 328P by driving the LED's with a transistor or additional gate.

For further critical noise reduction the Atmega328/P data book contains additional improvement methods, see the ADC chapter.
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

\$\endgroup\$
0
\$\begingroup\$

I guess the problem here is either some coupling with the current-carrying line inside the MCU or a drop in Vref voltage that makes the analog signal appear larger in comparison.

Either problem would be solved by driving the LED through a transistor. Alternatively, you could try reversing the LED and letting the MCU sink current to turn it on, by outputting "0". This would still incur the same current through the MCU, but through another path.

Another possible solution is measuring relative to the internal 1.1 voltage reference instead of Vref, as the 1.1 reference is less likely to be affected. But then you need to use a voltage divider to scale down the maximum signal voltage.

\$\endgroup\$
-1
\$\begingroup\$

Have you connected AVCC to 5 volt supply? I assume you have connected.

You have updated ADMUX after starting conversion. First set the proper value of ADMUX. Then set ADSC to 1.

Another important factor is data type. If you need to store the ADC value in a variable or do any mathematics , then do it inside ISR(ADC_vect){ }. All the data types must be - volatile int / volatile float etc (i.e. need to have volatile keyword) . Otherwise you will get junk value. Then you have to set ADSC to 1 again to start new conversion.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.