Odd analogRead results with USB power

This concerns my Arduino’s analogRead while using USB power. I have created an EMF detector using 10 LEDs controlled by a 74HC595 Shift Register. When I use a 9V battery to power the Arduino Uno, and touch the probe wire with my finger, 1 LED lights up (about 10 ADC). ADC is the value returned by analogRead. When I put it near a TV, 8-10 LEDS light up (80-100 ADC). These are reasonable results. When I power the Arduino with a USB to a desktop, and touch the wire with my finger, all the LEDs light up! The serial monitor says that the ADC is about 300! I disconnected it from the computer, hooked up the battery, and the results are back to normal. I don’t suspect that any connections are incorrect. I am using the internal 1.1V analog reference. Could it be that the computer doesn’t supply enough power to make the reference a full 1.1V? Please help!

Circuit: 74HC595 data to pin 2, clock to pin 3, latch to pin 4. 8 LEDs connected to Q0 - Q7 on the 74HC595, 1 LED to pin 5, 1 LED to pin 6. A bare copper wire to A0, two 1.8M resistors (total of 3.6M) in series from A0 to GND.

This is my code (it’s a bit confusing for other people to read). It takes the ADC from A0, and turns on a number of LEDs depending on the range of the ADC (e.g. 1 - 10 ADC lightd up 1 LED, 11 - 20 ADC lights up 2 LEDs).

const int numReadings = 10;
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int inputPin = A0;
int data = 2; 
int clock = 3;
int latch = 4;
void setup(){
  Serial.begin(9600);
  analogReference(INTERNAL);
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;  
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
  DDRD = 0x7c;
}
byte reader[] = {
  0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff};
boolean state1[]= {
  0,0,0,0,0,0,0,0,0,1,1};
boolean state2[] = {
  0,0,0,0,0,0,0,0,0,0,1};
void loop(){
  total= total - readings[index];         
  readings[index] = analogRead(inputPin); 
  total= total + readings[index];       
  index = index + 1;                    
  if (index >= numReadings)              
    index = 0;                           
  average = total / numReadings;
  float reading = average*1.1/1024.0/**100.0*/;
  int emf = map(average,0,100,0,10);
  updateLEDs(reader[emf]);
  digitalWrite(5, state1[emf]);
  digitalWrite(6, state2[emf]);
  Serial.print(reading);
  Serial.print("\t");
  Serial.println(average);
}
void updateLEDs(int value){
  digitalWrite(latch, LOW);     //Pulls the chips latch low
  shiftOut(data, clock, LSBFIRST, value); //Shifts out the 8 bits to the shift register
  digitalWrite(latch, HIGH);   //Pulls the latch high displaying the data
}
  if(withinRange(emf,1,10))doAll(1);
  else if(withinRange(emf,11,20))doAll(2);
  else if(withinRange(emf,21,30))doAll(3);
  else if(withinRange(emf,31,40))doAll(4);
  else if(withinRange(emf,41,50))doAll(5);
  else if(withinRange(emf,51,60))doAll(6);
  else if(withinRange(emf,61,70))doAll(7);
  else if(withinRange(emf,71,80))doAll(8);
  else if(withinRange(emf,81,90))doAll(9);

A loop might be better here.


The big problem as I see it is that an analog input is basically undefined if just a bare wire. So different environments (eg. USB) may just have more noise.

So once you are doing something that has undefined results, I stop really worrying about in what way they are undefined.

The big problem as I see it is that an analog input is basically undefined if just a bare wire. So different environments (eg. USB) may just have more noise.

So once you are doing something that has undefined results, I stop really worrying about in what way they are undefined.

What do you mean by "undefined"? Do you mean that the EMFs range is unknown? The bare wire is supposed to pick up electric fields in the air. They are unknown, but what I was wondering about was why the results are so different when I use a USB.

OK, well we often get people complaining that an input reads non-zero even though "nothing is plugged into it". The general response is that an input has undefined results unless it has a well-defined input, eg. tied high or low via some sort of reasonable resistance.

Now if you do analog reads, you can indeed get all sorts of wonderful figures if you wave your hand over the pin, and I suppose this could be classified as a sort of range reader. But I'm not sure you are detecting EMF, it's more likely capacitance between the pins and a nearby ground source.

By plugging into USB you are changing the environment, maybe providing a ground path, maybe introducing more noise.

OK, well we often get people complaining that an input reads non-zero even though "nothing is plugged into it". The general response is that an input has undefined results unless it has a well-defined input, eg. tied high or low via some sort of reasonable resistance.

My A0 pin is tied to Arduino Uno's ground via 2 1.8M ohm resistors in series, 'cause I don't have a 3.3M ohm resistor. If you mean "undefined" as the pin connected to nothing at all, then the pin having "floating voltage" isn't the problem. When it is working properly (i.e. powered by a battery), and I touch the wire, 1 LED might occasionally blink (or nothing happens), as opposed to the USB making all the LEDs turn on! There is a weak connection to ground, because I want the bare wire to pick up as much EMFs in the air as possible, without the pin being "undefined", if you know what I mean. The Arduino DOES pick up positive voltage near inductance chargers (toothbrush chargers), back of TV, power sockets, transformers, etc. I found out how to make the EMF detecting part on the internet (e.g. YouTube). Otherwise, it stays at zero (except when powered by a USB)! I think the problem is that the internal 1.1V reference voltage I'm using may be unstable when using USB power from a desktop, because it supplys less power. There are 10 LEDs attached to the Arduino! Maybe I should change it to a more stable 3.3V and see what happens.

OK, I accept most of what you are saying there, however I don't agree about the 1.1V reference not working "when using USB power from a desktop, because it supplys less power". I think that is pure speculation.

You can see for yourself though. Load up this sketch:

// Find internal 1.1 reference voltage on AREF pin
void setup ()
{
  ADMUX = _BV (REFS0) | _BV (REFS1);
}
void loop () { }

Then measure the AREF pin with a meter. That will confirm the voltage on it, with or without the USB connected.

Trying that on my Uno I got:

  • 1.0853V using USB
  • 1.0850V using a 9V battery plugged into the power-in jack

So, no difference unless you are going to quibble over 0.3 mV.

Please take a look at my code in the first post again. I have changed it to the code I was using when the problem occured. I posted this topic a few days later. The code with withinRange() commands was a new version of the code I have yet to try. I posted the other code by accident. I made both codes myself, but the one shown now in the first post is the one I used when the problem occurred. Maybe you can spot a bug in the code. On the day I posted this reply, I still didn't change the sketch on my Arduino (I still had the code in the first post on my Uno). I used a relatively new multimeter to measure the voltage from AREF to GND. It was 1.095V with battery. I used an old multimeter, and it read 1.082V. The voltage with USB is still 1.095V, but when I touch the wire, the voltage drops to 0.974V! My Serial Monitor spits out these numbers (left column is mV, right is ADC reading):

0.00 0
0.00 0
0.00 0
0.32 1
0.32 1
0.32 1
0.32 1
0.32 1
0.64 2
0.64 2
1.29 4
3.87 12
19.66 61
19.34 60
49.31 153
49.31 153
49.31 153
68.64 213
81.53 253
81.53 253
89.91 279
120.21 373
104.41 324
104.41 324
74.44 231
74.77 232
74.77 232
55.11 171
42.54 132
42.54 132
33.52 104
0.97 3

You can see the substantial difference when I touch the wire. I accept Nick Gammon's explaination of grounding and noise from USB. I think that the USB power's ground is Earth, and the Arduino's ground when powered by a battery, is the battery's negative terminal. But, I have another prediction. Once, I was experimenting with reading voltage of a low-pass filter. I used pin 9, change the timer 1 to the fastest PWM, and A0 to measure it. When I touched the 5V wire to A0, it read 994! I was worried that I had done something that affected the ADC, such as speeding up the timer. I realized that I had the 74HC595 attached to the 5V. My multimeter said that it was at 4.5V. I removed the 74HC595, and the voltage returned to 5V. Could this have anything to do with the strange results? Also, I would like to know how the grounding of the Arduino board might have to do with this. I will soon make another post about different readings with USB power.

I tried out your code and it spat out a whole lot of numbers like:

0.61	572
0.59	548
0.59	548
0.59	550
0.60	555
0.60	561
0.61	568
0.62	574
0.62	579
62	578
0.61	570
0.61	564
0.60	557
0.59	552
0.59	548
0.59	548
0.59	550
0.60	555

Of course I can't see the numbers if connect to a battery because I lose the serial interface.