Multi-function shield for Arduino

Hackatronics – Arduino Multi-function Shield

Introduction to the Coding Series

Simple I/O that is usually taken for granted on PCs, like reading key presses, outputting to a display, and sounding an alarm, often get in the way of the focus of the main task when developing for microcontrollers. It is for this reason we have developed a library, for the multi-function shield we have chosen, that simplifies basic I/O operations. We also provide a set of real world applications that make use of this library, so those new to coding on the Arduino can experiment with and enhance them.

Some familiarity with the Arduino platform is assumed, as is the installation of the Arduino development environment. We got our shield from Hobby Components, but there are a number of other suppliers too.

Installing the multi-function shield library

If you haven’t already done so, you will need to first install the TimerOne and Software I2C libraries using instructions for installing Arduino libraries. You can download the multi-function shield library from the link below and install using the instructions from the link above:

If for any reason you haven’t been successful installing any of the libraries, then download this library bundle instead, unzip and copy to your Documents\Arduino\libraries folder (if using Windows) or OS equivalent. Although we do everything to ensure our downloads are free from viruses and malware, please check that your virus and malware scanning software is up to date before hand.

We must point out that by following the Hackatronics series, you agree to do so at your own risk, and agree to take full responsibility for any loss or damages you may incur upon yourself or others. If you’re a kid starting out, be sure to have supervision of a responsible adult.

More about this series

This series is divided in to three main parts (and is also available as an eBook with extra information):

  1. Basic Input / Output
  2. Reading Sensors
  3. Real World Applications

Part 1 demonstrates the ease with which the multi-function shield buttons, beeper and display can utilized by using the shield library, thereby making it easier to concentrate on the logic of the application. Part 2 demonstrates how the shield library can be used to read values from external sensors, such as temperature, sonar and motion sensors, and how to process electronic pulses from an external source. Part 3 explores working applications using the library and the multi-function shield:

  • 24 hour alarm clock
  • Heart monitor   – (requires heart pulse sensor)
  • Count down timer
  • Surface incline level indicator– (requires MPU6050 motion sensor)
  • Sonar ranger   – (requires HC SR04 sonar module)
  • Speedometer   – (requires magnet and reed switch)

Each of these has scope to be built upon and expanded, but we leave that to you. Get coding and have fun!

New! Want to control your Arduino with an internet browser? Check out our new Arduino Web Server

Share on LinkedInShare on Google+Tweet about this on TwitterShare on Facebook

21 thoughts on “Hackatronics – Arduino Multi-function Shield

  1. bill

    hi.. if i want all the times a value px 1.00 min or 1.30 how can store the time ??i mean the board and arduino its off ..power on and start with last timer settings .and if easy if start the timer to countdown to open a relay and closed if finish the timer ??.any help
    thanks for your time and nice video

    1. Kashif Baig Post author

      Hi Bill, I’m not sure I fully understand the first part of your question. It is possible to store the timer value in the Arduino’s eeprom, but be aware that after about 100000 memory write operations, the eeprom becomes unreliable. The best way to do this would be store the timer value in eeprom just before powering off, but you would need special circuitry for that. You would read the timer value in eeprom on power up.

      To power a relay would need a driver IC. A mosfet IC might be a possible alternative to a relay.

  2. Luciano usuelli

    Ho caricato lo sketch led display ma non parte
    Ho caricato le librerie che voi suggerite ma sembra che la libreria multifunction non funzuona
    Cosa posso fare?
    Grazie per la aiuto

    1. Cohesive Computing

      Hi Luciano

      It is possible the library has not installed properly. Have you tried copying the library bundle file instead?

  3. Alaiksander

    I’m planning to make a pH controller. I’m thinking to purchase the hardwares. My setup will be 2 peristaltic pumps to pump pH UP and pH Down and a pH probe. I already have a 4x5v relays. Will this shield help me to achieve my setup?

  4. Walter Pletscher

    Congratulation for this very useful tool. It helped a great deal to get first hand experiences with a variety of Arduino related applications. My question is related to Part 3 – Speedometer. After powering the Arduino, the shield display starts counting back (even without holding button 1) until the number 30 appears (diameter of wheel). The sketch doesn’t react on button 2 or 3 for diameter changes. Sketch compile and upload without any error indication. Would appreciate a short feedback. Using Arduino UNO R3. Thanks.

    1. Kashif Baig Post author

      Hi Walter

      Do the other sketches have similar problems, or just the speedometer? I’m assuming you downloaded the source code zip file from here:

      I’m also assuming the correct board was selected in Arduino studio. Are you using a genuine Arduino UNO, or compatible clone? Btw, I haven’t tested the sketches using the SMD UNO, in case you’re using that edition. If you are, try using the 1.0 version of the library using the link I just mentioned.

      1. Walter Pletscher

        Dear Kashif,
        appreciate your immediate feedback – good support. Following replies:
        – I’ve tested about 6-8 other sketches with no problems at all
        – downloaded the source code (cut/paste into my arduino UNO) from your document (page 25,26)
        – using an Arduino UNO – original no compatible
        – I’ve not tested the sketch with Version 1.0 of the library

        1. Kashif Baig Post author

          Walter, I’ve pasted the same code from the document and can confirm that it does indeed work correctly. It is possible in your case the copy/paste has gone wrong somewhere. The full source code is available as a zip file from the link in my previous reply. Have you tried using that instead?

          1. Walter Pletscher

            Kashif, I’ve used the sketch from your source also, but the result remains the same. A test with older libraries – same result. I can only explain the wrong going, with the Multifunction Board I’ve got from the attached source:


            Please provide the source for your “original” board. Thanks a lot – appreciate again your help.

          2. Kashif Baig Post author

            I have a number of these shields from different sources, including one that is just like you have (look where it is written multi function shield, it is spelled incorrectly). Do you have a jumper block on both J2 pins? Could you also provide a link to the exact Arduino you have.

            Upload and run the Buttons sketch in the Basic Input Output folder of the source code zip file, and open the serial monitor. If no buttons are pressed, nothing should be output in the serial monitor. If you are getting false readings, then run the same sketch without the shield. If the false readings stop, it could be a faulty shield.

  5. Walter Pletscher

    Good evening Kashif,
    perfect advice. It was the missing jumper on J2. I can modify wheel diameter (up or down) with either button 2 or button 3. Thank you for your help. And by the way, it’s a board with the name multi function shield spelled incorrectly. I use an Arduino UNO Board Model UNO R3 with a DIL Version of the ATMEGA328P-PU.

    I would like to adapt your sketch for very tiny wheel diameters (9 to 11mm) and the application will be speed and distance measurement for my model train (H0 scale).
    Once again, your support was just excellent – thank you.

  6. olugbenga adebanjo

    Hi Kashif and welldone for the amazing work you’re doing. I am trying to implement your code on a new but generic MFB. At the moment I can’t get to hear any beeping sound both for the countdown and the alarm clock. Also, how does the J1 and J2 work?

    Thanks in advance for your support.

  7. Luis Enrique Piña Juárez

    Hi, im using the countdown for testing, but I have isuues with the 5 and 6, showing a 9 istead a 5, and a 8 instead the 6, do you know what could be causing this ?

    1. Kashif Baig Post author

      Hi Luis. With some Arduinos, the metal part of the USB connector makes contact with connections under the shield. If that is what you are experiencing, then insulate the part of the USB connector that makes contact.

  8. Wolfgang

    Hi. I have a question.
    When the sketch starts, the display is powered off. When it shows a digit or a letter, if i do MFS.write(OFF) it doesnt power off the display and shows a 0. How can i turn off the display??
    This is the sketch i am trying:


    void setup(){

    void loop(){
    int button;
    byte btn = MFS.getButton();
    if (btn){

    byte buttonNumber = btn & B00111111;
    byte buttonAction = btn & B11000000;
    if (buttonNumber == 1){
    button = LED_1;
    if (buttonNumber == 2){
    button = LED_2;
    if (buttonNumber == 3){
    button = LED_3;
    if (buttonAction == BUTTON_PRESSED_IND){
    MFS.writeLeds(button, ON);

    else if (buttonAction == BUTTON_SHORT_RELEASE_IND)
    MFS.writeLeds(button, OFF);


    1. Kashif Baig Post author

      You can blank out the display by writing a blank string, or string of 4 spaces:


      I hope that helps.

      1. Wolfgang

        Hi Kashif !!

        Thank you very much!! It works as expected!!

        You are the machine!! :)

  9. Christian T.

    I tried to make a loading bar and Found 2 Bugs:
    causes a 3 time overwrite of the first point so that only one Decimal point is displayed. The same is happening with
    of course.

    Now, it is possible to make the workaround with spaces in between, but them the second problem Kicks in:
    MFS.write(" . . . .");
    MFS.write(". . . . ");
    causes not displaying the last point of the four decimalpoints. Trying to workaround by using the rightJustify as follows
    only moves the problem to the opposite side, because the mistake takes place before rightJustify gehts to work.

    For the first one I’ve made the workaround by changing the comparator from

    for (; *text != 0 && idx < sizeof(displayBuf); text++)


    for (; *text != 0 && idx <= sizeof(displayBuf); text++)

    in MultiFuncShield.cpp forcing the last character to be read. Is that the fault of sizeof(), because it doesn’t want to count ending points, as part of the string?
    If there is something else than a point, it gets cut off anyway .. which is unclean .. but it works to solve the second bug.

  10. Uten

    I have just received two cards from China that breaks this library!

    As I’m new to Arduino (and non of the samples found on the net worked ) I thought I had borked the card by short circuiting it against the usb terminal. But when I got the second card and it behaved the same way I figured something has changed in the hw.

    As I understand it the mapping SEGMENT_MAP_* in the code are found by calculating the off segments. On my cards I have to add the ON segments. So 255 – current_value should work (and it does) on my cards. So SEGMENT_MAP_DIGIT, SEGMENT_MAP_ALPHA has to be changed.

    SEGMENT_SELECT also have to be modified: The segment selection on my cards are SEGMENT_SELECT={0x7, 0xB, 0xD, 0xE}. Seems like any multiple of 16 can be added to those numbers. Not that I have tried them all.

    Turning off a segment (witch I think is hard coded as 255?) has to be modified, as 0 now is the SEGMENT_OFF number.

    The function AsciiToSegmentValue has to be changed according to the new “add on led segments” rule.

    So in MultiFuncShield.cpp change these lines:
    const byte SEGMENT_OFF=0; //Uten added this line

    const byte SEGMENT_MAP_DIGIT[] = {63,6,91,79,102,109,124,7,127,111};
    const byte SEGMENT_MAP_ALPHA[] = {119, 124, 94, 94, 121, 113, 111, 116, 48, 14, 173, 56, 173, 84, 92, 115, 103, 80, 109, 120, 28, 73, 73, 73, 110, 73};
    const byte SEGMENT_SELECT[] = {14,13,11,7};

    WriteValueToSegment(15,SEGMENT_OFF); //Turn all off //Uten: was 255

    displayBuf[idx] = SEGMENT_OFF; //Uten was 255

    for (; i_src >= 0 && displayBuf[i_src] == SEGMENT_OFF; i_src–) ; //Uten: was 255

    displayMemory[i_dst] = SEGMENT_OFF; //Uten: was 255

    WriteValueToSegment(displayIdx, SEGMENT_OFF); //Uten: was 255

    WriteValueToSegment(displayIdx == 0 ? 3 : displayIdx-1, SEGMENT_OFF); //Uten: was 255

    switch (ascii)
    case ‘-‘:
    segmentValue = 64; //Uten was 191
    case ‘.':
    segmentValue = 128; //Uten was 127
    case ‘_':
    segmentValue = 8; //Uten was 247
    case ‘ ‘:
    segmentValue = SEGMENT_OFF; //Uten was 255

    Thanks for a great library and tutorial

    Best regards


Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>