Skip to content

Page Navigation Using Arduino

Introduction

Arduinos are very common microcontroller boards used to study and design programmable electronics. It is often used with multiple peripherals such as buttons, sliders, sensors and motors.

Together with a TIMI acting as a small fancy display, Arduino boards become a lot more powerful and interesting to use in prototyping.

Requirements

To proceed with the project, the following are required.

Hardware

  • TIMI-96
  • Mates Programmer
  • USB Type A to microUSB cable (for the Mates Programmer)
  • USB Type A to Type B cable (for the Arduino, replace as necessary)
  • Connecting Wires
  • Arduino Uno
  • Breadboard

Software

Graphics Design

Step 1: Open Mates Studio and create a Commander project for TIMI-96 with Reversed Landscape orientation.

Confirm-TIMI-96-LR

Select Commander

Step 2: Browse the library for appropriate page designs.

New Commander Project- Browse Library

For this project, the following pages are used:

Category: Date and Time, Page: Digital Clock

Date and Time- Digital Clock

Category: Notifications, Page: 8 x Flat Round Led

Notification- 8 x Flat Round

Category: Graphs, Page: Various Gauges Green

Graphs- Gauges

Category: Miscellaneous, Page: Various Digits

Miscellaneous- Various Digits

Category: Notifications, Page: 6-Line Black BG Print Area

Notification- 6 Line Black

Category: Notifications, Page: 6-Line Hex Print Area

Notification- 6 Line Hex Print

Category: Audio, Page: Media Spectrum

Audio- Spectrum Media Spectrum

Category: Graphs, Page: Full Scope

Graphs- Full Scope

Category: Notifications, Page: Full Dot Matrix

Notification- Full Dot Matrix

Step 3: After finalizing the design, connect TIMI-96 to your computer

Connect TIMI-96

Step 4: Upload the project to the appropriate COM port

Select Port

Project Upload

Step 5: When prompted, click Proceed to continue with upload.

Day and Time Proceed

Note

It is recommended that the graphics design is finalized before moving to the next steps when working on a project.

Programming the Arduino

Step 1: Install the MatesController library using Arduino’s Library Manager.

Mates Studio

Step 2: Include MatesController.h to your project.

#include "MatesController.h"

Step 3: Create a MatesController instance named mates

MatesController mates = MatesController(Serial);

This will initialize the MatesController instance to the default reset pin 4 using a LOW pulse.

Step 4: (Optional) Create a function for toggling the built-in LED of the Arduino board. This can be used for debugging or showing errors if the Serial monitor can’t be used.

int errLedStatus = LOW;
void ErrorLed_Toggle() {
  errLedStatus = ~errLedStatus;
  digitalWrite(LED_BUILTIN, errLedStatus);
}

Step 5: (Optional) At the beginning of the setup function, set the built-in LED pin to OUTPUT and set it to LOW.

pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, errLedStatus);

Step 6: To start using the MatesController instance, use the begin function

mates.begin();

This will initialize the Serial UART at the default baudrate of 9600

Step 7: (Optional) The begin function can be enclosed in an if condition to handle initialization errors.

if (!mates.begin()) {
  // Display didn't send ready signal in time
  while (1) {
    ErrorLed_Toggle();
    delay(100);
  }
}

Step 8: To simulate each of the pages, functions to handle simulated animations can be prepared.

void Day_and_Time_Animation(void) {

  // Days of Week Strings
  const char * daysOfWeek[] = {
    "SUNDAY",
    "MONDAY",
    "TUESDAY",
    "WEDNESDAY",
    "THURSDAY",
    "FRIDAY",
    "SATURDAY"
  };

  // Test Start Values: Monday, 23:59:47 (will actually start at 48 seconds)
  uint8_t lastDay = 1;
  uint8_t day = 1;
  int16_t hrs = 23;
  int16_t min = 59;
  int16_t sec = 47;

  mates.updateTextArea(0, daysOfWeek[day]);

  // Simulated Timer Variable
  unsigned long lastUpdate = millis() - 1000; // Ensures first write

  // stop at Day 2, Tuesday, 00:00:0  7
  while (day != 2 || hrs != 0 || min != 0 || sec != 7) {

    if (millis() - lastUpdate >= 1000) {

      lastUpdate = millis();

      sec++;
      if (sec == 60) {
        sec = 0;
        min++;
      }
      if (min == 60) {
        min = 0;
        hrs++;
      }
      if (hrs == 24) {
        hrs = 0;
        day++;
      }
      day %= 7;

      // mates.setWidgetValue(MATES_LED_DIGITS, 0, hrs);
      // mates.setWidgetValue(MATES_LED_DIGITS, 1, min);
      // mates.setWidgetValue(MATES_LED_DIGITS, 2, sec);
      mates.setLedDigitsValue(0, hrs);
      mates.setLedDigitsValue(1, min);
      mates.setLedDigitsValue(2, sec);
      if (lastDay != day) {
        mates.updateTextArea(0, daysOfWeek[day]);
        lastDay = day; // prevents writing the same text to TextArea
      }

    }

  }
}

void Numbered_LEDs_Animation(void) {

  mates.setWidgetValue(MATES_MEDIA_LED, 0, 1);

  uint8_t ledOff = 0;
  uint8_t ledOn = 1;

  for (int i = 0; i < 20; i++) {

    delay(500);

    mates.setWidgetValue(MATES_MEDIA_LED, ledOff, 0);
    mates.setWidgetValue(MATES_MEDIA_LED, ledOn, 1);

    ledOff = ledOn;
    ledOn++;
    ledOn %= 8;

  }

  mates.setWidgetValue(MATES_MEDIA_LED, ledOff, 0);

}

void Various_Gauges_Animation(void) {
  int16_t value = 0;
  int8_t inc = 1;

  unsigned long lastUpdate = millis();

  while (millis() - lastUpdate <= 10000) {

    value += inc;
    if (value == 100) inc = -1;
    if (value == 0) inc = 1;

    mates.setWidgetValue(MATES_GAUGE_A, 0, value);
    mates.setWidgetValue(MATES_LED_DIGITS, 3, value);
    mates.setWidgetValue(MATES_MEDIA_GAUGE_B, 0, value);

  }
}

void Various_Digits_Animation(void) {
  int16_t value = 0;
  int32_t longValue = 100000;
  float floatValue = 3.1416;

  unsigned long lastUpdate = millis();

  while (millis() - lastUpdate <= 5000) {

    // mates_setWidgetValue(MATES_LED_DIGITS, 4, value);
    mates.setLedDigitsValue(4, value);
    mates.setLedDigitsValue(5, longValue);
    mates.setLedDigitsValue(6, floatValue);

    value++;
    longValue += 12345;
    floatValue += 3.1416;

  }
}

void Print_Strings_Animation(void) {

  const char * msg = "Mates Studio offers a variety of widgetswhich includes this Print Area. For moreinfo, please refer  to our manuals.";

  uint8_t len = (uint8_t) strlen(msg);

  char str[2];

  mates.appendToPrintArea(0, msg);

  delay(2000);

  mates.clearPrintArea(0);

  for (uint8_t i = 0; i < len; i++) {
    str[0] = msg[i];
    str[1] = 0;
    mates.appendToPrintArea(0, str);
    delay(50);
  }

}

void Print_Hex_Values_Animation(void) {
  const int16_t colors[] = {
    (int16_t) 0xFFFF, (int16_t) 0xF800, (int16_t) 0x07E0, (int16_t) 0x001F,
    (int16_t) 0x07FF, (int16_t) 0xF81F, (int16_t) 0xFFE0, (int16_t) 0x39FF
  };

  int8_t val = 0;
  int8_t ctr = 0;

  unsigned long lastUpdate = millis();

  while (millis() - lastUpdate <= 5000) {

    if (ctr >= 42) {
      mates.clearPrintArea(0);
      ctr = 0;
    }

    mates.setPrintAreaColor(1, colors[ctr % 8]);
    mates.appendToPrintArea(1, &val, 1);
    ctr++;
    val++;

    delay(100);

  }
}

void Audio_Spectrum_Animation(void) {
  uint8_t col = 1;

  unsigned long lastUpdate = millis();

  while (millis() - lastUpdate <= 5000) {

    // mates.setSpectrumValue(MATES_MEDIA_SPECTRUM, 0, (uint8_t) (rand() % 101));
    mates.setMediaSpectrumValue(0, col, (uint8_t) (rand() % 101));

    col++;
    if (col == 6) col = 0;

  }
}

void Updating_Scope_Animation(void) {
  // uint16_t deg = 270; // Use for computed version
  int16_t value = 18;

  const int16_t values[] = {
    40, 50, 59, 67, 73, 77, 79, 77, 73, 67, 59, 50,
    40, 29, 20, 12, 6, 2, 1, 2, 6, 12, 20, 29
  };

  unsigned long lastUpdate = millis();

  while (millis() - lastUpdate <= 5000) {

    // Computed version START
    /*
    deg += 15;
    if (deg >= 360) {
      deg %= 360;
    }

    // 180 / PI = 57.29578
    // value = (int16_t) (39 * sin(deg * 3.1416 / 180)) + 40;
    value = (int16_t) (39 * sin(deg / 57.29578)) + 40;
    // Float computations can take a significant time

    mates.setWidgetValue(MATES_SCOPE, 0, value);
    */
    // Computed version END

    // Pre-computed version START

    value++;
    if (value >= 24) value = 0;
    mates.setWidgetValue(MATES_SCOPE, 0, values[value]);

    // Pre-computed version END

  }
}

void Update_Dot_Matrix(void) {
  char buffer[25] = "DotMatrxVal1 XXXVal2 XXX"; // 24 characters + null terminator (8 * 3 + 1 = 25)
  char * val1ptr = buffer + 13;
  char * val2ptr = buffer + 21;

  uint8_t val1 = 0;
  uint8_t val2 = 255;

  unsigned long lastUpdate = millis();

  while (millis() - lastUpdate <= 5000) {

    // START of Simulated Values
    val1++;
    val2--;

    if (val1 < 100) {
      val1ptr[0] = ' ';
    } else {
      val1ptr[0] = '0' + (val1 / 100);
    }

    if (val1 < 10) {
      val1ptr[1] = ' ';
    } else {
      val1ptr[1] = '0' + ((val1 % 100) / 10);
    }

    val1ptr[2] = '0' + (val1 % 10);

    if (val2 < 100) {
      val2ptr[0] = ' ';
    } else {
      val2ptr[0] = '0' + (val2 / 100);
    }

    if (val2 < 10) {
      val2ptr[1] = ' ';
    } else {
      val2ptr[1] = '0' + ((val2 % 100) / 10);
    }

    val2ptr[2] = '0' + (val2 % 10);
    // END of Simulated Values

    mates.updateDotMatrix(0, buffer);

  }
}

Step 9: Each function can then be defined into a function pointer array

void (* animations[])(void) = {
  Day_and_Time_Animation,
  Numbered_LEDs_Animation,
  Various_Gauges_Animation,
  Various_Digits_Animation,
  Print_Strings_Animation,
  Print_Hex_Values_Animation,
  Audio_Spectrum_Animation,
  Updating_Scope_Animation,
  Update_Dot_Matrix
};

Step 10: In the loop function, the page navigation is done every iteration.

void loop() { 
  static uint16_t page = 0;
  (*animations[page])();
  page++;
  page %= 9;
  mates.setPage(page);
}

As shown, the loop starts by performing the animation. The page counter is then incremented until the last page number and reset as necessary. The next page is then activated at the end of the loop.

Running the Project

After designing the user interface for TIMI and writing code for the Arduino and programming them, it is time to connect the devices together. Follow the diagram below for the connection between TIMI and Arduino.

arduino-timi

Finally, supply power to the Arduino and observe the behavior of the project.

Downloadable Resources

Here are the links to the software applications, libraries and completed project files.