Project: InfinityPi #3 (analog IO)

Category: 


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

The Arduino Micro ist super useful and small, but it's maybe not the best choice if you want to embedded it in a project, because 20€ is not that cheap. I searched a bit around and found a nice little alternative. The "Pro Micro Module Board" is similar to an "Pro Mini", but with the nice ATmega32u4 on board, therefore you can use it as an input device for your computer. It is compatible to an Arduino Leonardo/Micro, but with less IO pins. It only has 12 digital pins and four analog pins, but in most cases this will be enough and if not, you could extend it with some ICs. I bought a 3 pieces bundle from Amazon for just 15€, so one piece costs only a quarter of a micro, much better :)

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

Let's go back to the gamepad. The ultimate goal is to implement a full featured gamepad. That means that we need six analog inputs, two for each thumbstick and one for each trigger. So if we would use a normal micro, then everything is fine, because it has enough pins. In the case of the cheaper version, we only have four pins. So we either drop two analog inputs (obviously the triggers) or we use an input multiplexer. Let's take a look at the 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.

class Mux {
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.

To be continued

Next we will check out the actual Joystick behavior and we will make a first test gamepad that can be used by any computer.