Talk to your ROKU device/tv using Ethernet :)

japreja

Active member
So the reason I decided to delve into this is that my Fiancé has Multiple Sclerosis that greatly affects her mobility. She has very limited range of motion and can use a TV/Device remote but with much difficulty. She can use accessibility push buttons/switches as used in hospitals. These buttons/switches are basically a normal button/switch just with a large press area that gives better leverage to the switch using a small amount of pressure, Usually about 3 to 4 inches square with light springs in each corner and the switch in the center.

Our ROKU remotes have very few buttons, a mobility impaired person with very limited range of motion cannot navigate easily to stations requiring multiple presses of the buttons.

Luckily Roku has a developer program, largely designed for channel creators, but they also have an API that communicates over UDP and HTTP. Some commands require placing your TV into Developer Mode which requires a ROKU account and a ROKU Developer account. The Roku device you want to control needs to be setup to developer mode:

https://developer.roku.com/docs/developer-program/getting-started/developer-setup.md

Once done you can use your web browser and the HTTP protocol to send commands to your ROKU TV/Device using information found on this page:

https://developer.roku.com/docs/developer-program/debugging/external-control-api.md

My intent is to use this on Teensy 4.1 with the ethernet library to setup some buttons that tell the TV to go directly to specific channels using accessible buttons/switches. The buttons/switches will need to remotely need to communicate with a Teensy, maybe mounted to the ceiling, so IR from the button to the teensy, then from the teensy to the TV over ethernet. The teensy in a single button will be overkill so a smaller microcontroller for the button itself will probably be implemented, OR, maybe a touchscreen interface using a teensy so one touchscreen can be used as multiple buttons using a rotary encoder or joystick to change the function.

I will edit this Top Post with my progress and maybe a bump post. If you make progress quicker than I can, please do not hijack my thread, just create your own please.
 
I just mustered up this code that works for me, I added most buttons commands one would find on a standard remote but just played around with volume.


Code:
/*
 * Roku Network Remote using Teensy 4.1 with Ethernet
 * 
 * Requirements:
 *    A modern ROKU TV or Device in "Developer Mode" requires a developer account at https://developer.roku.com/docs/developer-program/getting-started/developer-setup.md
 *    A local Ethernet Hub with a free ethernet port
 *    A Teensy 4.1 with Ethernet Module Installed and working properly
 *    
 *    Read the NativeEthernet thread for more info on Ethernet, at https://forum.pjrc.com/threads/60857-T4-1-Ethernet-Library
 *    
 * This sample sends one volume down keypress to the Roku device at the given IP Address in HOST_NAME[] on your
 * local network.
 * 
 * Jorge Joaquin Pareja
 * 
**/


#include <SPI.h> // is this needed on Teensy 4.1 with built in Ethernet?
#include <NativeEthernet.h>


uint8_t mac[6]; // setup array for automaticaly getting the mac
unsigned int localPort = 8888;          // local port for Teensy to listen on


EthernetClient client;


int    HTTP_PORT   = 8060;              // ROKU Device PORT as required by the Roku Documentation
String HTTP_METHOD = "POST";            // GET or POST - Roku Devices will send XML data in return to some commands


// Host name should be the IP address of your Roku TV you want to control
char   HOST_NAME[] = "192.168.1.22";    // ROKU Device IP Address, Change this to your Roku Devices IP Address


/*
 * **************************************************************
 * Roku TV/Device keypress commands from https://developer.roku.com/docs/developer-program/debugging/external-control-api.md#keypress-key-values
 */
String keypress_HOME            = "/keypress/Home";
String keypress_REVERSE         = "/keypress/Rev";
String keypress_FORWARD         = "/keypress/Fwd";
String keypress_PLAY            = "/keypress/Play";
String keypress_SELECT          = "/keypress/Select";
String keypress_LEFT            = "/keypress/Left";
String keypress_RIGHT           = "/keypress/Right";
String keypress_DOWN            = "/keypress/Down";
String keypress_UP              = "/keypress/Up";
String keypress_BACK            = "/keypress/Back";
String keypress_INSTANTREPLAY   = "/keypress/InstantReplay";
String keypress_INFO            = "/keypress/Info";
String keypress_BACKSPACE       = "/keypress/Backspace";
String keypress_SEARCH          = "/keypress/Search";  // activates voice commands? not sure how to send this with audio
String keypress_ENTER           = "/keypress/Enter";


String keypress_VOLUME_UP       = "/keypress/VolumeUp";
String keypress_VOLUME_DOWN     = "/keypress/VolumeDown";
String keypress_VOLUME_MUTE     = "/keypress/VolumeMute";


String keypress_CHANNEL_UP      = "/keypress/ChannelUp";
String keypress_CHANNEL_DOWN    = "/keypress/ChannelDown";


String keypress_POWER_OFF       = "/keypress/PowerOff";


String keypress_INPUT_TUNER     = "/keypress/InputTuner";
String keypress_INPUT_HDMI1     = "/keypress/InputHDMI1";
String keypress_INPUT_HDMI2     = "/keypress/InputHDMI2";
String keypress_INPUT_HDMI3     = "/keypress/InputHDMI3";
String keypress_INPUT_HDMI4     = "/keypress/InputHDMI4";
String keypress_INPUT_AV1       = "/keypress/InputAV1";


String keypress_NUMPAD_0        = "/keypress/Lit_0";
String keypress_NUMPAD_1        = "/keypress/Lit_1";
String keypress_NUMPAD_2        = "/keypress/Lit_2";
String keypress_NUMPAD_3        = "/keypress/Lit_3";
String keypress_NUMPAD_4        = "/keypress/Lit_4";
String keypress_NUMPAD_5        = "/keypress/Lit_5";
String keypress_NUMPAD_6        = "/keypress/Lit_6";
String keypress_NUMPAD_7        = "/keypress/Lit_7";
String keypress_NUMPAD_8        = "/keypress/Lit_8";
String keypress_NUMPAD_9        = "/keypress/Lit_9";


void setup()
{
  Serial.begin(115200);
  while (!Serial){
    ; // wait for serial port to connect. Needed for native USB port only
  }


  delay(10);


  teensyMAC(mac);  // Get Teensy built-in mac


  // start the Ethernet connection:
  Serial.println("Initialize Ethernet with DHCP:");


  if (Ethernet.begin(mac) == 0){
    Serial.println("Failed to configure Ethernet using DHCP");


    if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
      //
      //  Do something when no hardware
      //
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    }
    else if (Ethernet.linkStatus() == LinkOFF)
    {
      //
      // do something when cable is not connected
      //
      Serial.println("Ethernet cable is not connected.");
    }
    while (true)
    {
      delay(1);
    }
  }
  
  // print your local IP address:
  Serial.print("Teensy IP address is: ");
  Serial.println(Ethernet.localIP());


  // connect to Roku TV/Device on port 8060:
  if(client.connect(HOST_NAME, HTTP_PORT)) {
    Serial.println("Connected to Roku Device");


    client.println(HTTP_METHOD + " " + keypress_VOLUME_DOWN + " HTTP/1.1"); // sends one press of the volume - (down) button
    client.println("Host: " + String(HOST_NAME));
    client.println("Connection: close");
    client.println(); // end HTTP header


    while(client.connected()) {
      if(client.available()){
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }


    // the server's disconnected, stop the client:
    client.stop();
    Serial.println();
    Serial.println("disconnected");
  } else {// if not connected:
    Serial.println("connection failed");
  }
}


void loop()
{
  switch (Ethernet.maintain())
  {
    case 1:
      //renewed fail
      Serial.println("Error: renewed fail");
      break;


    case 2:
      //renewed success
      Serial.println("Renewed success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;


    case 3:
      //rebind fail
      Serial.println("Error: rebind fail");
      break;


    case 4:
      //rebind success
      Serial.println("Rebind success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;


    default:
      //nothing happened
      break;
  } // END switch(Ethernet.maintain())


}


// From the forums, https://forum.pjrc.com/threads/62932-Teensy-4-1-MAC-Address
//   Detects the pre-programed unique mac address on all Teensy 4.1's, I don't think
//   any libs are required for this to work...
void teensyMAC(uint8_t *mac) {
    for(uint8_t by=0; by<2; by++) mac[by]=(HW_OCOTP_MAC1 >> ((1-by)*8)) & 0xFF;
    for(uint8_t by=0; by<4; by++) mac[by+2]=(HW_OCOTP_MAC0 >> ((3-by)*8)) & 0xFF;
    Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
 
Code Additions

I have not changed any code for the network and Roku, but I did add my old 5 page menu system that I used on arduino and ran out of memory, putting that project on hold. Luckily the teensy has plenty memory to revitalize this project.

Added 3 buttons, left right, and select. Need to add atleast 2 more buttons for Up and Down. I may also just use an ADS1115 for a Joystick....
Added a 128x128 display (part from amazon linked in code comments)
Added my Menu System to the code.
Added MIT License

Code is not utilizing the menu other than changing screens at the moment, but I wanted to keep anyone interested updated on my progress. When I get Networking information updated to only display on the screen on one of the pages without the need for Serial Terminal, I will stick to my following comments and update the OP with versioning and Release Notes to make it easier incase this thread gets large. I will also add Photos and wiring diagrams as the project progresses.

Two Code files in seperate code blocks:

Code:
/* Copyright 2018-2022 Jorge Joaquin Pareja
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"),  to deal in the Software without restriction, including without
limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so, subject to the following
conditions:


The above copyright notice and this permission notice shall be included in all copies or substantial portions
of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/


/*
 * Roku Network Remote using Teensy 4.1 with Ethernet
 * 
 * Requirements:
 *    A modern ROKU TV or Device in "Developer Mode" requires a developer account at https://developer.roku.com/docs/developer-program/getting-started/developer-setup.md
 *    A local Ethernet Hub with a free ethernet port
 *    A Teensy 4.1 with Ethernet Module Installed and working properly
 *    
 *    Read the NativEthernet thread for more info on Ethernet, at https://forum.pjrc.com/threads/60857-T4-1-Ethernet-Library
 *    
 * This sample sends one volume down keypress to the Roku device at the given IP Address in HOST_NAME[] on your
 * local network.
 * 
 * Jorge Joaquin Pareja
 * 
**/


/* Impliment a UTFT 128x128 SPI display menu template


This code is for the 1.44" TFT LCD Module using Adafruit's current libraries pulled fresh from github,
ignore the products linked video since the links included in the video, from the amazon seller, have
some older code that causes errors on this screen.


 * 1.44" TFT LCD  https://www.amazon.com/gp/product/B07B4BDWCL
 * Adafruit GFX library https://github.com/adafruit/Adafruit-GFX-Library
 * Adafruit HW Specific Library https://github.com/adafruit/Adafruit-ST7735-Library


  Pinout Display:
  These budget displays have what seem to be a misprinted silkscreen text that, at first sight, one
  will think these are I2C.  They are not!  They are in fact SPI.  Wire them as follows:


  Display | Arduino
    * 5V  to +5V
    * GND to GND
    * GND to GND
    * NC
    * NC
    * LED to 5V
    * SCL to Digital 13
    * SDA to Digital 11
    * RS  to Digital  7
    * RST to Digital  6
    * CS  to Digital  5


  Pinout Buttons (Active Low With Internal PU Resistors enabled, see setup().)
    * Left   to pin 4
    * Right  to pin 3
    * Select to pin 2 ( not yet implimented )
*/


#include <Adafruit_GFX.h>    // Core graphics library ( https://github.com/adafruit/Adafruit-GFX-Library )
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735 ( https://github.com/adafruit/Adafruit-ST7735-Library )
#include <SPI.h> // is this needed on Teensy 4.1 ?
#include "namedColors.h"
#include <NativeEthernet.h>


const byte TFT_CS    =    7;  // Silkscreen label CS
const byte TFT_RST   =    6;  // Silkscreen label RST
const byte TFT_DC    =    5;  // Silkscreen label RS
//const byte TFT_SCLK  =   13;  // Silkscreen label SCL  (Needs to be Connected even if this line is commented)
//const byte TFT_MOSI  =   11;  // Silkscreen label SDA  (Needs to be Connected even if this line is commented)


// For 1.44" TFT with ST7735 use
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);


///// Display, Font, and Padding constants, may need to be changed to int instead of byte values for larger
// screens when the values will excede 255
// Display Properties
const byte screenWidth  = 128; // in pixels
const byte screenHeight = 128; // in pixels


// font properties
const byte fntWidth  = 6; // in pixels
const byte fntHeight = 8; // in pixels


const byte screenMaxCharsPerLine = screenWidth/fntWidth;
const byte screenMaxLines = screenHeight/fntHeight;


// Padding in pixels, incase font is slightly off screen
const byte cpadding = 0; // column padding
const byte rpadding = 0; // row/line padding


// 21 Columns on a 1.44 (128x128) display.  I use this for calculating the
// columns for text placement using setCursor, default font 6x8!
// DONE!! This can be populated in a for loop and account for alternate screen
// and font sizes, and also to possibly save memory, see setup().
int tft144Col[screenMaxCharsPerLine];
int tft144Row[screenMaxLines];


void cls(int color = c_black, byte rotation = 1);


// Buttons
// TODO Add Up and down buttons also
const byte bSelect = 2; // not yet implimented
const byte bLeft = 3;
const byte bRight = 4;


// Menu Settings and variables
byte mIndex = 5; // menu index   5= default title screen
byte pIndex = 5; // previous page
byte cIndex = 5; // current page
const String sVersion = "V1.0";






uint8_t mac[6]; // setup array for automaticaly getting the mac
unsigned int localPort = 8888;          // local port for Teensy to listen on


EthernetClient client;


int    HTTP_PORT   = 8060;              // ROKU Device PORT as required by the Roku Documentation
String HTTP_METHOD = "POST";            // GET or POST - Roku Devices will send XML data in return to some commands


// Host name should be the IP address of your Roku TV you want to control
char   HOST_NAME[] = "192.168.1.22";    // ROKU Device IP Address, Change this to your Roku Devices IP Address


/*
 * **************************************************************
 * Roku TV/Device keypress commands from https://developer.roku.com/docs/developer-program/debugging/external-control-api.md#keypress-key-values
 */
String keypress_HOME            = "/keypress/Home";
String keypress_REVERSE         = "/keypress/Rev";
String keypress_FORWARD         = "/keypress/Fwd";
String keypress_PLAY            = "/keypress/Play";
String keypress_SELECT          = "/keypress/Select";
String keypress_LEFT            = "/keypress/Left";
String keypress_RIGHT           = "/keypress/Right";
String keypress_DOWN            = "/keypress/Down";
String keypress_UP              = "/keypress/Up";
String keypress_BACK            = "/keypress/Back";
String keypress_INSTANTREPLAY   = "/keypress/InstantReplay";
String keypress_INFO            = "/keypress/Info";
String keypress_BACKSPACE       = "/keypress/Backspace";
String keypress_SEARCH          = "/keypress/Search";  // activates voice commands? not sure how to send this with audio
String keypress_ENTER           = "/keypress/Enter";


String keypress_VOLUME_UP       = "/keypress/VolumeUp";
String keypress_VOLUME_DOWN     = "/keypress/VolumeDown";
String keypress_VOLUME_MUTE     = "/keypress/VolumeMute";


String keypress_CHANNEL_UP      = "/keypress/ChannelUp";
String keypress_CHANNEL_DOWN    = "/keypress/ChannelDown";


String keypress_POWER_OFF       = "/keypress/PowerOff";


String keypress_INPUT_TUNER     = "/keypress/InputTuner";
String keypress_INPUT_HDMI1     = "/keypress/InputHDMI1";
String keypress_INPUT_HDMI2     = "/keypress/InputHDMI2";
String keypress_INPUT_HDMI3     = "/keypress/InputHDMI3";
String keypress_INPUT_HDMI4     = "/keypress/InputHDMI4";
String keypress_INPUT_AV1       = "/keypress/InputAV1";


String keypress_NUMPAD_0        = "/keypress/Lit_0";
String keypress_NUMPAD_1        = "/keypress/Lit_1";
String keypress_NUMPAD_2        = "/keypress/Lit_2";
String keypress_NUMPAD_3        = "/keypress/Lit_3";
String keypress_NUMPAD_4        = "/keypress/Lit_4";
String keypress_NUMPAD_5        = "/keypress/Lit_5";
String keypress_NUMPAD_6        = "/keypress/Lit_6";
String keypress_NUMPAD_7        = "/keypress/Lit_7";
String keypress_NUMPAD_8        = "/keypress/Lit_8";
String keypress_NUMPAD_9        = "/keypress/Lit_9";


void setup()
{
  Serial.begin(115200);
  while (!Serial){
    ; // wait for serial port to connect. Needed for native USB port only
  }


  delay(10);


  teensyMAC(mac);  // Get Teensy built-in mac


  // start the Ethernet connection:
  Serial.println("Initialize Ethernet with DHCP:");


  if (Ethernet.begin(mac) == 0){
    Serial.println("Failed to configure Ethernet using DHCP");


    if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
      //
      //  Do something when no hardware
      //
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    }
    else if (Ethernet.linkStatus() == LinkOFF)
    {
      //
      // do something when cable is not connected
      //
      Serial.println("Ethernet cable is not connected.");
    }
    while (true)
    {
      delay(1);
    }
  }
  
  // print your local IP address:
  Serial.print("Teensy IP address is: ");
  Serial.println(Ethernet.localIP());


  // connect to Roku TV/Device on port 8060:
  if(client.connect(HOST_NAME, HTTP_PORT)) {
    Serial.println("Connected to Roku Device");


    client.println(HTTP_METHOD + " " + keypress_VOLUME_DOWN + " HTTP/1.1"); // sends one press of the volume - (down) button
    client.println("Host: " + String(HOST_NAME));
    client.println("Connection: close");
    client.println(); // end HTTP header


    while(client.connected()) {
      if(client.available()){
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }


    // the server's disconnected, stop the client:
    client.stop();
    Serial.println();
    Serial.println("disconnected");
  } else {// if not connected:
    Serial.println("connection failed");
  }


  // Use this for a 1.44" TFT
  tft.initR(INITR_144GREENTAB);


  // setup easy access for text positions
  for (byte i = 0; i < screenMaxCharsPerLine; i++){
    tft144Col[i] = (cpadding+(i*fntWidth));
  }
  for (byte i = 0; i < screenMaxLines; i++){
    tft144Row[i] = (rpadding+(i*fntHeight));
  }


  // set the text color, and the background color so that new text will cover over any old text
  // without having to blank the entire screen
  setTextWhiteBlack(); // white text on black background, prevents having to redraw the entire screen
  tft.setTextWrap(false); // disable wrapping of text


  cls(c_black, 1);


  // configure buttons
  pinMode(bSelect, INPUT_PULLUP);
  pinMode(bLeft,   INPUT_PULLUP);
  pinMode(bRight,  INPUT_PULLUP);
  
}


void loop()
{
  switch (Ethernet.maintain())
  {
    case 1:
      //renewed fail
      Serial.println("Error: renewed fail");
      break;


    case 2:
      //renewed success
      Serial.println("Renewed success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;


    case 3:
      //rebind fail
      Serial.println("Error: rebind fail");
      break;


    case 4:
      //rebind success
      Serial.println("Rebind success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;


    default:
      //nothing happened
      break;
  } // END switch(Ethernet.maintain())


  
  
  layoutScreen();
  delay(100);
}


// From the forums, https://forum.pjrc.com/threads/62932-Teensy-4-1-MAC-Address
//   Detects the pre-programed unique mac address on all Teensy 4.1's, I don't think
//   any libs are required for this to work...
void teensyMAC(uint8_t *mac) {
    for(uint8_t by=0; by<2; by++) mac[by]=(HW_OCOTP_MAC1 >> ((1-by)*8)) & 0xFF;
    for(uint8_t by=0; by<4; by++) mac[by+2]=(HW_OCOTP_MAC0 >> ((3-by)*8)) & 0xFF;
    Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}


////////////////////////////
// TFT Code
////////////////////////////
void layoutScreen(){
  processButtons();
  drawMenu(mIndex);


  switch(mIndex){
    case 1:
      Page1();
      break;
    case 2:
      Page2();
      break;
    case 3:
      Page3();
      break;
    case 4:
      Page4();
      break;
    case 5:
      Page5();
      break;
    default:
      Page5();
      break;
  }
}


void processButtons(){
  // read the state of the pushbutton value:
  int bSelectState = digitalRead(bSelect);
  int bLeftState = digitalRead(bLeft);
  int bRightState = digitalRead(bRight);
  
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if ((bLeftState == HIGH) && (bRightState == LOW)){
    pIndex = mIndex;
    mIndex -= 1;
  }
  
  if ((bRightState == HIGH) && (bLeftState == LOW)){
    pIndex = mIndex;
    mIndex += 1;
  }
  
  if( mIndex <= 0){
    mIndex = 5;
  }
  else if (mIndex > 5){
    mIndex = 1;
  }
}


void Page1(){ // display Page 1
  setTextWhiteBlack();
}


void Page2(){ // display Page 2
}


void Page3(){ // display Page 3
}


void Page4(){ // display Page 4
}


void Page5(){// Main Screen Page - Title Screen
  // "0123456789012345678901" // max 22 chars per line referance on 128x128px display (1.44 inch
  pl("Menu Template", 2,4);
  pl(sVersion, 3, 8);
  pl("using a",6,7);
  pl("1.44\" TFT LCD", 7,4);
  pl("By", 8,10);
  pl("Jorge Pareja", 9, 5);
  tft.setTextColor(c_red, c_black);
  pl("Press Left Or Right", 13, 1);
  pl("buttons To Begin", 14, 3);
}


void drawMenu(byte index) {// calling this will clear the screen and draw the menu on line 0, similar to tabbed pages.  No need to modify, add code to Page#() functions instead
  String page0 = " P1 ";
  String page1 = " P2 ";
  String page2 = " P3 ";
  String page3 = " P4 ";


  cIndex = index;


  setTextWhiteBlue();


  if(pIndex != cIndex){
    cls();
    pIndex = cIndex;
  }


  if(index == 1){
    setTextBlackRed();
    pl(page0, 0, 1);
    setTextWhiteBlue();
    pl(page1, 0, 6);
    pl(page2, 0, 11);
    pl(page3, 0, 16);
  }
  else if(index == 2){
    pl(page0, 0, 1);
    setTextBlackRed();
    pl(page1, 0, 6);
    setTextWhiteBlue();
    pl(page2, 0, 11);
    pl(page3, 0, 16);
  }
  else if(index == 3){
    pl(page0, 0, 1);
    pl(page1, 0, 6);
    setTextBlackRed();
    pl(page2, 0, 11);
    setTextWhiteBlue();
    pl(page3, 0, 16);
  }
  else if(index == 4){
    // Page 4
    pl(page0, 0, 1);
    pl(page1, 0, 6);
    pl(page2, 0, 11);
    setTextBlackRed();
    pl(page3, 0, 16);
  }
  else if(index == 5){
    // menu item not selected
    pl(page0, 0, 1);
    pl(page1, 0, 6);
    pl(page2, 0, 11);
    pl(page3, 0, 16);
  }
  setTextWhiteBlack();
}


void setTextWhiteBlue() {tft.setTextColor(c_white, c_blue);}
void setTextWhiteBlack(){tft.setTextColor(c_white, c_black);}
void setTextBlackRed()  {tft.setTextColor(c_black, c_red);}


void uprint(String txt, int fg_color, int bg_color, byte lineNumber, byte columnNumber){
  tft.setTextColor(fg_color, bg_color);
  tft.setCursor(tft144Col[columnNumber], tft144Row[lineNumber]);
  tft.print(txt);
}


void pl(String txt, byte lineNumber, byte columnNumber) { // print string based on the line and column numbers, calculated in the arrays
  tft.setCursor(tft144Col[columnNumber], tft144Row[lineNumber]);
  tft.print(txt);
}


void cls(int color = c_black, byte rotation = 1){ // Clear the Screen w/ screen rotation
  tft.setRotation(rotation);
  tft.fillScreen(color);
}

and namedColors.h :

Code:
// From Adafruit library
#define c_black   ST77XX_BLACK
#define c_white   ST77XX_WHITE
#define c_red     ST77XX_RED
#define c_green   ST77XX_GREEN
#define c_blue    ST77XX_BLUE
#define c_cyan    ST77XX_CYAN
#define c_magenta ST77XX_MAGENTA
#define c_yellow  ST77XX_YELLOW
#define c_orange  ST77XX_ORANGE


// from https://cgit.freedesktop.org/xorg/app/rgb/tree/rgb.txt
// converted with http://www.rinkydinkelectronics.com/calc_rgb565.php
#define c_AliceBlue 0xF0F8FF
#define c_Snow      0xFFFAFA
 
Back
Top