Write your own drivers for Arduino

Making It Work

Interestingly enough, the Ax pins (from A0 to A5) on your Arduino Uno are not used to produce an analog output. They are only good for reading. When they are used for output, they produce a regular digital, 1 or 0, HIGH or LOW. To produce an analog output, you use the pins marked as PWM. On the Uno, these are pins 3, 5, 6, 9, 10, and 11. These pins accept, apart from the a digital output, any number between 0 and 255. This allows you to regulate, for example, the brightness of an LED or the speed of a motor.

As you can't use the same pin for input and output, you need two MC14051Bs if you want to read in and push out data during the execution of the same sketch. This isn't that bad: eight analog inputs and eight analog outputs…yay! Right? However, I did try to use only one chip by gating the input and output using transistors, but that didn't work. There must be something I'm not getting. So, for the time being, two MC14051Bs it is.

To demonstrate a basic use of simultaneous input and output through the MC14051B, I'll use a potentiometer to regulate the speed of a motor. Using a multiplexer makes more sense if you have many more sensors to read from and many more devices to output to, and I will be covering a more advanced project in the next issue of Raspberry Pi Geek. For the sake of simplicity here, however, I'll keep it, well, simple.

Your setup could look like what's shown in Figure 4. The MC14051B on the left is the one that serves as an output analog port expander, and the one on the right is the input port expander. They are connected to the Arduino via pin 3 and analog pin A0, respectively (green wires). The pink wires are used to tickle the inhibitor, and the set of white, yellow, and orange wires connect pins on the Arduino to the MC14051Bs' A, B, and C ports.

Figure 4: Reading from and writing to two MC14051Bs simultaneously.

The blue wires connect the MC14051Bs to the potentiometer in the case of the input port expander, and to a transistor that regulates the flow of electricity to a motor in the case of the output port expander. It wouldn't make sense to connect the output directly to the motor because normally it wouldn't be strong enough to make it run. Figure 5 shows what this setup looks like in real life.

Figure 5: It looks a mess, but it does actually work (see reference [3]).

As for the code, thanks to the new library, this is as tight as it gets. Look at Listing 7: You first set up two MC14051B objects, one for output (lines 3 and 4) and one for input (lines 6 and 7). On line 13, you use the mcAnalogWrite() function from your library to write the value read from the potentiometer (using the mcAnalogRead() function, also from your library) to your motor. Because values read in via analog pins range from 0 to 1023 and PWM values only go up to 255, you use the Arduino map() function to scale down the value from the potentiometer accordingly.

Conclusion

Writing Arduino libraries for otherwise unsupported hardware doesn't have to be a big deal. The library you've seen here takes up a grand total of 55 lines, including blank lines, and in no way uses obscure pointers, structures, or cryptic C++ libraries. In fact, it uses the standard Arduino functions you should already be used to. And, does it ever make life easier!

Additionally, if you share your work online, you can help make the world of Arduino a much richer place and contribute to the community. If you're interested, you can download the MC14051B library shown in this article from GitHub [4].

House plants are fairly self-sufficient, but they do need certain care from people to survive. With a few Arduino sensors and a little programming, you can take the guesswork out of watering your plants.