Project: InfinityPi #3 (analog IO)
This time I will show you an even smaller Ardunio board, that is comparable to the Arduino micro, but that costs much less. Furthermore I will write a bit about analog readings.
Pro Micro
It is also a way smaller than the micro, which is very nice for an embedded project. Here is a little comparison to the micro:

You program it just like an Arduino Leonardo/Micro, in fact you will tell your Arduino IDE that it is a Leonardo board (Menu > Tools > Board > Arduino Leonardo).
Analog Input Multiplexer
Analog Multiplexer/Demultiplexer 4051

A (de)multiplexer enables you to expand your in- or output pins of your Arduino. The 4051 is able to do both, you could either use it as a multiplexer or as a demultiplexer. We will only look at the input multiplexer.
You have to connect three digital pins to this chip and one analog pin. The pins s0, s1 and s2 are used to select one of the eight pins, you can then read the corresponding value from your analog input. Each of the three pins is basically a single bit of a 3 bit long number. So in order to select the third analog input, you set s0 and s1 to HIGH and s2 to LOW.
For testing purposes I connected two "normal" joysticks and two PSP joysticks to this chip:

You may have noticed that there are three pins connected to GND. The outer most one ist just the normal GND pin. The next one is the Vee pin, the negative supply pin. You could connect a negative voltage to this pin, which enables this chip to accept analog values in the range of Vee to Vcc. The Arduino cannot handle a negative supply, therefore we just connect it to GND in order to limit the range to 0-Vcc. The next pin is the "enable input" pin. If this pin is grounded, the chip will be used as a multiplexer, otherwise it will be used as a demultiplexer.
private:
const byte sensor;
const byte s0;
const byte s1;
const byte s2;
public:
Mux(byte s, byte a, byte b, byte c) : sensor(s), s0(a), s1(b), s2(c) {
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
}
int read(byte i) {
digitalWrite(s0, bitRead(i, 0));
digitalWrite(s1, bitRead(i, 1));
digitalWrite(s2, bitRead(i, 2));
return analogRead(sensor);
}
};
Mux mux(A0, 8, 9, 10);
void setup() {
Serial.begin(9600);
}
void loop() {
// show all 8 sensor readings
for (byte i = 0; i < 8; i++) {
Serial.print(mux.read(i));
Serial.print(" ");
}
Serial.println();
delay(250);
}
Of course there is no need to put it in an extra class, but I like it more this way, because it looks better and now you could also put it into a separate library.
The code itself is straight forward, before I read the analog input, I just select the correct pin via the s0 to s2 pins.
Looking at the Serial monitor, we can now see the ranges of the two different joystick types:
Joystick Axis | min | center | max |
---|---|---|---|
Joystick X | 0 | 512 | 1023 |
Joystick Y | 0 | 512 | 1023 |
PSP X | 146 | 482 | 859 |
PSP Y | 142 | 487 | 840 |
As you can see, the PSP joystick is a bit crappy. Therefore I hope to have enough space for the bigger one on my InfinityPi.