I successfully read 8 sensors with the 4051, but there is something that is not clear to me. Can I read and write in the same loop without any other instruction than analogRead() and digitalWrite()?
I'm planning to connect 4 LEDs and 4 sensors to the 8 in/out pins of the 4051 and use that sort of code:
void loop () {
for (i=0; i<=7; i++) {
// select the bit
r0 = bitRead(count,0);
r1 = bitRead(count,1);
r2 = bitRead(count,2);
digitalWrite(2, r0);
digitalWrite(3, r1);
digitalWrite(4, r2);
// Read
if (i <= 3) {
sensorVal[i] = analogRead(commonPin);
}
// Nothing to add here before writing?
// Write
if (i >= 4) {
if (sensorVal[i- 4] >= 512) digitalWrite(commonPin, HIGH);
else digitalWrite(zPin, LOW);
}
}
You might need to set pinMode(commonPin, OUTPUT) before writing.
NOTE: The 4051 is a selector, not a latch. You can't use it to turn on more than one LED at a time. When you change the address pins all the unselected pins will be disconnected.
Also note that the analog input needs time to settle. If you change the address going to the 4051 and immediately do analogRead() the value might not have settled in time to get an accurate reading. If you get a problem with changes in one pin appearing on other pins you could try reading the value twice and throwing out the first read.
I tried my code anyway, using switches as inputs and LEDs as outputs. It works fine (except that the LED next to the one that's lit up does light up a little) when I output serial data or when I add a 125ms delay inside the loop, but the LEDs light up in a strange fashion when I comment out the serial lines:
switch 1 lights LEDs 1 & 2 up, switch 2 will light LEDs 1 & 3 up, switch 3 will light LEDs 3 & 4 up and switch 4 will light LEDs 1, 3 and 4 up.
I don't seems to have problems with reading the switches, I didn't even write the code to debounce them and they seem to be working fine. It's just the writing that messes, and I don't plan to use delays in my code as this is supposed to become a MIDI controller... I thought that since MIDI is a serial protocol the LEDs might light up fine in the end but that sounds a little too approximate for my taste.
Any suggestions? I know nothing about multiplexing. Basically I want to connect about 8 analog sensors (or more), a couple of switches and a couple of LEDs. That's just a little too many pins for my Uno.
Any suggestions? I know nothing about multiplexing.
Nether did the person who wrote a tutorial about using a 4051 to light up an LED.
It is the totally wrong chip to use.
Use the 4051 for reading, its made for that and providing the signal you are using is not changing rapidly, ( like 100KHz ) then you will be fine.
except that the LED next to the one that's lit up does light up a little
This is because you are writing the digital select lines one at a time and in the process you put false data briefly on the the chip. You need to write all these bits at the same time using direct port access or bit manipulation. But as I said it is totally the wrong chip anyway, use a shift register and don't put in that capacitor they have in the tutorial.
except that the LED next to the one that's lit up does light up a little
This is because you are writing the digital select lines one at a time and in the process you put false data briefly on the the chip. You need to write all these bits at the same time using direct port access or bit manipulation.
Another choice is to write the data pin to LOW before changing the address pins. That way none of the other pins get connected to a HIGH signal while the address lines are changing.
void loop () {
for (i=0; i<=7; i++) {
// select the bit
r0 = bitRead(count,0);
r1 = bitRead(count,1);
r2 = bitRead(count,2);
pinMode(commonPin, OUTPUT);
digitalWrite(commonPin, LOW);
digitalWrite(2, r0);
digitalWrite(3, r1);
digitalWrite(4, r2);
// Read
if (i <= 3) {
sensorVal[i] = analogRead(commonPin);
}
// Nothing to add here before writing?
// Write
if (i >= 4) {
pinMode(commonPin, OUTPUT); // Not sure if analogRead() switches the pin to INPUT or not.
digitalWrite(commonPin, (sensorVal[i - 4] >= 512));
}
delay(1); // This will improve the brightness of the LED's You can increase this until the flicker becomes annoying.
}