analog input alters voltage... doesn't read properly

So hopefully this schematic will explain what i'm doing well enough.

The problem i am having is that my A0 (and all other input pins) are somehow breaking my reading- w/o the arduino hooked up I read specific ranges for each gear (check the schematic) - but as soon as I connect the A0 pin to the wire it should read voltage from- it locks up on 3.98 volts- and doesn't budge.

Why would this happen?

Schematic:

All of my so-so code:

  const int bottomLeft = 3;
  const int bottom = 6;
  const int bottomRight = 2;
  
  const int topRight = 7;  
  const int top = 1;  
  const int topLeft = 4;

  const int middle = 5;


void setup() {
  
  pinMode(bottomLeft, OUTPUT);
  pinMode(bottom, OUTPUT);
  pinMode(bottomRight, OUTPUT);
  
  pinMode(topRight, OUTPUT);
  pinMode(top, OUTPUT);  
  pinMode(topLeft, OUTPUT);

  pinMode(middle, OUTPUT);

  pinMode(A0, INPUT);
  
  //debug
  //Serial.begin(9600);
}


int incomingByte = 0;
int prevByte = 2;
int currentByte = 0;
int testing = 0;

void loop() {
  if (testing == 1){
    test();
    //digitalWrite(6,HIGH); // test individual segments    
  }else{
  int raw = 0;
  float val = 0;
  float avgVal = 0;
  
  for (int i=0; i <= 99; i++){
      raw = analogRead(A0); //  read 0-5 volts from the GPS
      val = fmap(raw, 0, 1023, 0.0, 5.0); // volts are 10 bit (0-1023) so map it back to a proper volt number
      avgVal = avgVal+val;
  }
 
  //Serial.println(avgVal/100); //voltage
  
  //1st: 1.36V
  //2nd: 1.77V
  //3rd: 2.49V
  //4th: 3.23V
  //5th: 4.1V
  //6th: 4.55V
  //N: 5V
  
if (avgVal <= 4.24){
  reset();
  first();
}

if (avgVal >= 4.25 && avgVal <= 4.31){
  second();
}

if (avgVal >= 4.32 && avgVal <= 4.40){
  third();
}

if (avgVal >= 4.41 && avgVal <= 4.56){
  fourth();
}

if (avgVal >= 4.57 && avgVal <= 4.72){
  fifth();
}

if (avgVal >= 4.73 && avgVal <= 4.89){
  sixth();
}

if (avgVal >= 4.90){
  neutral();
}
    
    

  
  delay(1);
    }
}

void reset(){  
  digitalWrite(bottomRight,HIGH);  
  digitalWrite(bottom,HIGH);
  digitalWrite(bottomLeft,HIGH);
   
  digitalWrite(topRight,HIGH);
  digitalWrite(top,HIGH);  
  digitalWrite(topLeft,HIGH);

  digitalWrite(middle,HIGH);
}


void first(){
  reset();
  digitalWrite(topRight,LOW);
  digitalWrite(bottomRight,LOW);
}

void second(){
  reset();
  digitalWrite(top,LOW);
  digitalWrite(topRight,LOW);
  digitalWrite(middle,LOW);
  digitalWrite(bottomLeft,LOW);
  digitalWrite(bottom,LOW);
}
void third(){
  reset();
  digitalWrite(top,LOW);
  digitalWrite(topRight,LOW);
  digitalWrite(middle,LOW);
  digitalWrite(bottomRight,LOW);
  digitalWrite(bottom,LOW);
}
void fourth(){
  reset();
  digitalWrite(topLeft,LOW);
  digitalWrite(middle,LOW);
  digitalWrite(topRight ,LOW);
  digitalWrite(bottomRight,LOW);
}
void fifth(){
  reset();
  digitalWrite(top,LOW);
  digitalWrite(topLeft,LOW);  
  digitalWrite(middle,LOW);
  digitalWrite(bottomRight,LOW);
  digitalWrite(bottom,LOW);
}
void sixth(){
  reset();
  digitalWrite(top,LOW);
  digitalWrite(topLeft,LOW);
  digitalWrite(bottomLeft,LOW);
  digitalWrite(bottom,LOW);
  digitalWrite(bottomRight,LOW);
  digitalWrite(middle,LOW);
}
//animated neutral "spins"
void neutral(){  
  digitalWrite(bottomLeft,LOW);
  delay(100);
  reset();
  digitalWrite(bottom,LOW);
  delay(100);
  reset();
  digitalWrite(bottomRight,LOW);
  delay(100);
  reset();
  digitalWrite(topRight,LOW);
  delay(100);
  reset();
  digitalWrite(top,LOW);
  delay(100);
  reset();
  digitalWrite(topLeft,LOW); 
  delay(100);
  reset();  
}

void test(){
  
  
  first();
  delay(1000);
  
  second();
  delay(1000);
  
  third();
  delay(1000);
  
  fourth();
  delay(1000);
  
  fifth();
  delay(1000);
  
  sixth();
  delay(1000);
}

//Mapping function, used to convert 0-1023 to 0-5 volts
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Your diagram is much too big to read easily.

It looks like you have no ground connection between the Arduino and the gear indicators.

...R

Ha- fits well on a 27" 1440p monitor... sorry my bad. -- updated OP image.

So perhaps I need to use the ground line from the GPS... I thought it would be the same thing as the ground on the rest of the bike, I mean it IS running to the common ground on the rest of the bike AFAIK.

Altered it a bit this morning- grounding directly to the GPS sensor now- its like .1 volt difference vs grounding to the frame or the neg. battery terminal.

Regardless- all my readings w/o the Arduino A0 pin attached- look right-... as soon as i plug the arduino in though the numbers go all over the place... doesn't make ssense.

You haven't said how you are generating the gear change voltages.

How are you measuring the voltages without the Arduino? Perhaps you are using a digital multimeter which has a very high impedance - several megaOhms. The Arduino's ADC input pins have an impedance of about 10k ohms. This may affect things.

...R

Robin2:
The Arduino's ADC input pins have an impedance of about 10k ohms.

Are you sure about that?

Robin2:
You haven't said how you are generating the gear change voltages.

How are you measuring the voltages without the Arduino? Perhaps you are using a digital multimeter which has a very high impedance - several megaOhms. The Arduino's ADC input pins have an impedance of about 10k ohms. This may affect things.

...R

You sir deserve a gold star :slight_smile:

I think this is what is going wrong... i was just triple checking my voltage readings- with my multimeter when it occurred to me- maybe the readings on the meter are different from what the arudino sees.

This said- what should i do about it? Perhaps I need to add a resistor or 3 ? Or am I misunderstanding this again...

I might try and set this up on my laptop- all next to the bike, then I could get the readings FROM the arduino- via serial... and know for sure what it is getting.

"The ADC is optimized for analog signals with an output impedance of approximately 10 k? or less"

Extract from Section 23.6.1 of Atmel doc8161.pdf

...R

PeterH:

Robin2:
The Arduino's ADC input pins have an impedance of about 10k ohms.

Are you sure about that?

So what is the verdict? What is the solution for this?

So what is the verdict? What is the solution for this?

I can't think of any reason this is happening. That's why I didn't answer before... Maybe figure-out a different way of detecting gear selection?

I don't know why the gear indicator output would be high impedance, yet this is the "obvious" cause of what you are seeing. (Unless it's not really an "output".)

Because of it's very-high impedance, the Arduino's input shouldn't affect anything it's connected to, unless the voltage is greater than 5V, or negative. (Internal protection dioes start conducting when the input goes nevative, or above the power supply voltage.)

Are you sure you have 5V powering the Arduino? Are you sure the gear-output voltages are not negative?

An [u]op-amp buffer circuit[/u] is the usual solution (to increase the input-impedance, or decrease the output impedance). But, the Arduino already has very-high input impedance.

"The ADC is optimized for analog signals with an output impedance of approximately 10 k? or less"

Extract from Section 23.6.1 of Atmel doc8161.pdf

...R

That means that the output (source) impedance of whatever is driving the ADC input should be less than 10K. The Arduino's input impedance is much greater... The spec sheet (page 377) says 100 Megohms minimum.

http://forums.hackaday.com/viewtopic.php?f=4&t=564

Great info on a few of those-

"Attach a 1k-100k resistor to ground on the floating pin and repeat the test. "

This is what I was guessing i'd need to do- but just so I understand this correctly- This implys that I cross my signal and ground wires, with a resistor?

Please excuse my noob understanding of electronics- I thought I'd just be hooking a couple wires up to get X voltage- the impedance stuff has me baffled.

DVDdoug:

So what is the verdict? What is the solution for this?

I can't think of any reason this is happening. That's why I didn't answer before... Maybe figure-out a different way of detecting gear selection?

I don't know why the gear indicator output would be high impedance, yet this is the "obvious" cause of what you are seeing. (Unless it's not really an "output".)

Because of it's very-high impedance, the Arduino's input shouldn't affect anything it's connected to, unless the voltage is greater than 5V, or negative. (Internal protection dioes start conducting when the input goes nevative, or above the power supply voltage.)

Are you sure you have 5V powering the Arduino? Are you sure the gear-output voltages are not negative?

An [u]op-amp buffer circuit[/u] is the usual solution (to increase the input-impedance, or decrease the output impedance). But, the Arduino already has very-high input impedance.

"The ADC is optimized for analog signals with an output impedance of approximately 10 k? or less"

Extract from Section 23.6.1 of Atmel doc8161.pdf

...R

That means that the output (source) impedance of whatever is driving the ADC input should be less than 10K. The Arduino's input impedance is much greater... The spec sheet (page 377) says 100 Megohms minimum.

And yes- i am sure i've got a 5v power for the Arduino- tested that a few times, its a V regulator from radioshack... solid as a rock at 5 volts.

Thanks also for the op-amp suggestion, i had read that elsewhere... something new i don't know about haha :slight_smile:

Someone asked before, but, what's the shakedown on this "gear position sensor"?
Any links, PDFs, etc?

Do you have any transistors, resistors?

I have to take issue with you on this one. Page 377 of doc8161.pdf doesn't deal with impedance. Have you a link to the document you refer to?

In any case unless your document specifically refers to the inputs to the ADC I will believe the "facts" in doc8161. Indeed I have just proved it to my own satisfaction because a 4k7 potentiometer works properly whereas a 47k pot produces jittery values from the ADC.

Oh, and there is a difference between DC impedance and AC impedance.

...R

DVDdoug:

"The ADC is optimized for analog signals with an output impedance of approximately 10 k? or less"

Extract from Section 23.6.1 of Atmel doc8161.pdf

...R

That means that the output (source) impedance of whatever is driving the ADC input should be less than 10K. The Arduino's input impedance is much greater... The spec sheet (page 377) says 100 Megohms minimum.

RAIN (Analogue Input Resistance) is, indeed, typically 100Mohm (section 28.8 ADC Characteristics)

And yes- i am sure i've got a 5v power for the Arduino- tested that a few times, its a V regulator from radioshack... solid as a rock at 5 volts.

5V into the barrel jack is not enough! There is a voltage drop across the on-board regulator and diode. You may only have 4V powering the Arduino chip. (You can measure that on the 5V pin.) The specs say 6V minimum, with a recommended minimum of 7V. (Or with an external 5V regulator, you can power the Arduino at the 5V pin.)

Less than 5V powering the Arduino chip would cause the protection diodes to kick-in below 5V, clamping/limiting the analog input voltage (at slightly more than the chip-supply voltage).

Also, if you are using an LED 7-Segment display, I don't see any current limiting resistors on your schematic. Without current limiting resistors, you could be pulling excess current, which could also pull-down the 5V supply on the Arduino-side of the regulator. And, you can potentially damage your Arduino and/or the LED display. 14.5V into the barrel jack should not have fried you other Arduino, but the lack of current limiting could explain that too.

Thanks. I've found that now.

This has nothing at all to do with the input impedance of the ADC when it is working.

...R

AWOL:
RAIN (Analogue Input Resistance) is, indeed, typically 100Mohm (section 28.8 ADC Characteristics)

Well there is this whole thread:

You'l see "TeeRiver" did a different version of this (far prettier haha).

Pulled from SV Gear Indicator. | Page 2 | Suzuki SV650 Riders Forum

Inside the ECM is a 1k resistor pulled up to 5v. If the 1k internal ECM resistor is proper, then a 1k ohm external load will voltage divide 5v down to 2.5v. If you don't see 2.5v then start looking for a series resistor inserted somewhere on the Pink wire to the ECM.

You can also test the gear position sensor resistors individually by disconnecting the sensor, then measure resistance between sensor Pink, and ground Black/White. Should see:
1st: 374 ohms
2nd: 547
3rd: 1k
4th: 1.82k
5th: 4.6k
6th: 10k
N: open circuit.

FYI- there aren't any extra resistors inline here I've checked, just the 1k in the ECM and then the list above.

Perhaps there is a way to calculate this?

I'll give some readings:

With Arduino Connected Without Arduino Connected
1 1.34 1.36
2 1.81 1.76
3 2.48 2.57
4 3.22 3.23
5 3.75 4.11
6 3.84 4.52
Neutral 3.89 4.97

All of this said- I reprogrammed the arudino to look at the "On and Plugged in" numbers- that is the closest I got - but it displays 3 for First gear, 4 for 2nd gear, and N (Neutral) for all the rest... as if it is STILL not seeing the same voltage my multimeter is reading.

My old laptop isn't working with a batter- im half inclined to setup the duino with a LCD and have it print voltage readings and then just program for those numbers....

As for transistors and resistors... I have a bunch of resistors- this whole kit http://www.amazon.com/Arduino-Sidekick-Basic-Kit-Version/dp/B007B14HM8/ref=sr_1_1?ie=UTF8&qid=1367321842&sr=8-1&keywords=arduino+sidekick

And a few other things laying around. Again- really wasn't anticipating a complicated project.