Go Down

Topic: 4051 not working right (Read 3076 times) previous topic - next topic

J-Ri350

I was playing around with my new 4051 (I bought 5 and have tried this same code on each one with the same results), and can't get it to work right.  A0-A2 will work correctly, but only if using delay().  I have tried this with and without pull-down resistors (10k and 1k) attached to the inputs on the 4051 and on the input pin on my Arduino.   When I run this code...
Code: [Select]
void loop() {
  for(int count = 0; count <=7; count++){
    r0 = count & 0x01;
    r1 = (count>>1) & 0x01;
    r2 = (count>>2) & 0x01;
    digitalWrite(2, r0);
    digitalWrite(3, r1);
    digitalWrite(4, r2);
    val = digitalRead(readPin);
    a,b,c,d,e,f,g,h =0;
    if(count == 0) a=val;
    if(count == 1) b=val;
    if(count == 2) c=val;
    if(count == 3) d=val;
    if(count == 4) e=val;
    if(count == 5) f=val;
    if(count == 6) g=val;
    if(count == 7) h=val;
  }
  Serial.print (a);
  Serial.print ("  ");
  Serial.print (b);
  Serial.print ("  ");
  Serial.print (c);
  Serial.print ("  ");
  Serial.print (d);
  Serial.print ("  ");
  Serial.print (e);
  Serial.print ("  ");
  Serial.print (f);
  Serial.print ("  ");
  Serial.print (g);
  Serial.print ("  ");
  Serial.println (h);


...I get the number on the right (in serial monitor) when a 5v wire is touched to the pin represented by the binary number on the left:
000 - 11000000
001 - 00001100
010 - 00110000
011 - 00000011
100 - 01010101
101 - 01010101
110 - 01010101
111 - 01010101

I then wrote a new sketch (which I accidentally closed without saving and I'm not going to re-write) that had a 5 second delay after S0,S1,S2 writes, then read the input and sent the serial out.  I went through and did each one manually so I could check the inputs/outputs with my voltmeter as the sketch progressed.  For example, using input 2:
    digitalWrite(2, 0);
    digitalWrite(3, 1);
    digitalWrite(4, 0); (of course I changed these values to select the correct pin)
    delay(5000);
    c=digitalRead(9);
    Serial.print("c");
With 5v only to the pin it was supposed to read, this sketch gave the output:
000- 10000000
001- 01000000
010- 00100000
011- 00011111
100- 00001111
101- 00001111
110- 00001111
111- 00001111

I wired it up as shown in the playground (http://www.arduino.cc/playground/Learning/4051), and verified on the manufacturer datasheet the the pins were the same.

Thanks in advance for any help!
-Jason

Korman

Your message and your code is very confusing. What are you're trying to do and how does that relate to the 4051?

To recap: The 4051 is a 8 to 1 analogue multiplexer where you control with 3 pins which input is switched onto the output pin. This output you can then read with analogRead() function to get values between 0 and 1024 for the range 0-5V.

If you're doing many analogRead in rapid succession of varying values, you might have to read the data twice to allow the internal capacitors to discharge an to get correct readings. Read the documentation about the analogue inputs of the ATmega328 for more details.

Your code doesn't really match the capabilities of the connected  hardware, thus it's no big surprise that you get garbage values.

Korman

Grumpy_Mike

You can't let an input pin float, that is be unconnected to anything. If you do then you will not read a consistent value from the input.

You need either a pull up or pull down resistor on the analogue input pin. Then it can be driven by some input on the multiplexer.
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

J-Ri350

I was very tired last night when I asked for help, let me re-type this in a slightly clearer state of mind.  I think I used up the last of my mental energy trying to figure out the problem myself :)

While running the sketch below, Arduino's digital pins 2,3,4 are connected to the 4051 pins s0,s1 and s2, respectively.  I have power to pin 3 on the 4051, and ground on pins 6,7,8.  The 4051's multiplexed pins (A0-A7) are all connected to a 1k ohm pull-down resistor.  I have checked multiple sources and this appears to be the correct way to hook everything up.

I wrote a simplified sketch that doesn't use bitshifting or for(), and with the variables removed.  It's a bit easier to see the intended function.  All it does is write to the select pins, and send the value of the input pin to the serial monitor.  I tried it with and without using the commented-out "delay(200)" since before it behaved differently with and without delay().  It now makes no difference whether I use delay() or not.
Code: [Select]
int readPin = 9;
void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(readPin, INPUT);
  Serial.begin(9600);
}
void loop() {
  digitalWrite(2, 0);
  digitalWrite(3, 0);
  digitalWrite(4, 0);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 0);
  digitalWrite(3, 0);
  digitalWrite(4, 1);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 0);
  digitalWrite(3, 1);
  digitalWrite(4, 0);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 0);
  digitalWrite(3, 1);
  digitalWrite(4, 1);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 1);
  digitalWrite(3, 0);
  digitalWrite(4, 0);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 1);
  digitalWrite(3, 0);
  digitalWrite(4, 1);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 1);
  digitalWrite(3, 1);
  digitalWrite(4, 0);
  //delay(200);
  Serial.print (digitalRead(readPin));
  digitalWrite(2, 1);
  digitalWrite(3, 1);
  digitalWrite(4, 1);
  //delay(200);
  Serial.println (digitalRead(readPin));
}


When I start serial monitor with all the 4051 input pins to ground through a 1k resistor, I see 00000000, as I should.  When I touch a 5v wire to the input pins on the 4051, I see the following:
5v to pin 0 shows 10000000 in serial monitor
5v to pin 1 shows 01000000 in serial monitor
5v to pin 2 shows 00100000 in serial monitor
5v to pin 3 shows 00011111 in serial monitor
5v to pin 4 shows 00001111 in serial monitor
5v to pin 5 shows 00001111 in serial monitor
5v to pin 6 shows 00001111 in serial monitor
5v to pin 7 shows 00001111 in serial monitor

5v to multiple pins shows up as you would expect based on the readings above, eg. power at 0,2,6 shows 10101111

I'm very curious why pins 0,1,2 on the 4051 are read correctly and the rest are not.

My goal, for now, is for the readout on serial monitor to be the current state of the pin, either high or low.  I just want to be sure that I know how to hook this up before etching the PCB the chips will be attached to.

Since you asked what I'm trying to do, I am building a methanol injection controller for my car.  Ultimately I will be using a 4051 (in conjunction with NAND and AND gates) to ensure that when the transistors are switched on, the controlled devices (pump and injectors) have power and, if commanded, ground.  I just ran out of pins, and the 4051 seemed like a good option

graynomad

#4
Apr 06, 2011, 12:05 pm Last Edit: Apr 06, 2011, 12:28 pm by Graynomad Reason: 1
You are doing a digitalRead of a pin, the only valid values are 1 and 0, how are you getting these other values?

EDIT:
Doh, I get it, you quite cunningly have a loop :)

What Korman says is the most likely option.
______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Korman

#5
Apr 06, 2011, 12:18 pm Last Edit: Apr 06, 2011, 12:21 pm by Korman Reason: 1
Your program looks ok. From the results, I would check first if you have properly connected pin2 to the 4051. If you had connected that pin to the Input enable on the 4051, you would get exactly this behaviour: As long as Pin2 is low, pin 3 and 4 switch inputs as desired, but if it's high, the output is disabled and the value read is independent of the input. Perhaps you just have a short circuit with the input enable pin. This can be easily checked with a multimeter.

That would be at least be a simple explanation. Also check the correct data sheet for your chip if the pin-out is correct, don't trust secondary descriptions on web sites.

Perhaps it helps.

Korman

J-Ri350

Thank you very much for your help and patience Korman.

This is a bit embarrassing, but hopefully admitting this will help someone else if they screw up too.  The jumper wire I had connecting the two ground rails on my breadboard had developed an open spot.  It's quite obvious just by feeling the wire, there's a very soft spot right where it bends.  Apparently I overlooked this in my sleep deprived state.  Pins 4,5,6,7 (1,2,4,5 on the DIP) were effectively connected to each other through a 2k resistor.

I'm not sure why reading pin 3 (on the side that was actually connected to ground) showed 00011111 in serial monitor, it may have something to do with the fact that the input pin on my Arduino was also using this "floating" rail as ground for the pull-down resistor, but that should make all pins read 1.  If I have time in the future, I may try to figure this out, but for now I've got it working as it should and that's all I care about right now.

Go Up