[SOLVED] Serial.read slowing down buttons actions

Hello guys.
Thank you for your incredible support.

I’m building a project where I have one Arduino Mega that when I press a button in the attached tft shield send a data via Serial.write to an Arduino Leonardo, that is received via Serial.read. The Leonardo also has attached a tft shield and have two “pages” of buttons programmed.

The idea is that the buttons on the Mega (1, 2, 3, 4…etc) make the pages in the Leonardo change (1, 2, 3, 4…) and then I use the Leonardo’s buttons to send key presses.

The problem is that when I put in the sketch the readBytes line, the functions on the buttons slow down to the point that some of them just don’t work sometimes… in other hand, if I just put a line to change de pages manually with any of the buttons in the Leonardo, everything works fine.

This is the code for the Leonardo Receiver (Please check the comment at line 84):


#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <Keyboard.h>
#include <TouchScreen.h>
#define MINPRESSURE 200
#define MAXPRESSURE 1000
char mystr[6];
char mystr2[8];
// Results from TouchScreen_Calibration
const int XP = 8, XM = A2, YP = A3, YM = 9; //ID=0x9341
const int TS_LEFT = 949, TS_RT = 92, TS_TOP = 901, TS_BOT = 128;
char control;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_GFX_Button on_btn, off_btn, luis_btn, luis2_btn, luis3_btn, next1_btn, back1_btn, color1_btn, color2_btn, color3_btn, oninvert_btn, offinvert_btn, luisinvert_btn, luis2invert_btn, luis3invert_btn, next1invert_btn, back1invert_btn, color1invert_btn, color2invert_btn, color3invert_btn;
int pixel_x, pixel_y;     //Touch_getXY() updates global vars
bool Touch_getXY(void)
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);   //because TFT control pins
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    pixel_x = map(p.y, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
    pixel_y = map(p.x, TS_TOP, TS_BOT, 0, tft.height());
  return pressed;
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
int ;

void setup(void)
  uint16_t ID = tft.readID();
  Serial.println("Calibrate for your Touch Panel");
  if (ID == 0xD3D3) ID = 0x9486; // write-only shield
  tft.setRotation(1);            //LANDSCAPE
  control = '0';
void loop(void)
  bool down = Touch_getXY();
  if (control == '0') {
    on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
    off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
    luis_btn.press(down && luis_btn.contains(pixel_x, pixel_y));
    luis2_btn.press(down && luis2_btn.contains(pixel_x, pixel_y));
    luis3_btn.press(down && luis3_btn.contains(pixel_x, pixel_y));
    next1_btn.press(down && next1_btn.contains(pixel_x, pixel_y));

    if (on_btn.justReleased    ())  on_btn.drawButton();
    if (off_btn.justReleased   ())  off_btn.drawButton();
    if (luis_btn.justReleased  ())  luis_btn.drawButton();
    if (luis2_btn.justReleased ())  luis2_btn.drawButton();
    if (luis3_btn.justReleased ())  luis3_btn.drawButton();

    if (luis_btn.justPressed   ())  {
      Keyboard.press('j'); Keyboard.releaseAll();
    if (luis2_btn.justPressed  ())  {
      Keyboard.press('k'); Keyboard.releaseAll();
    if (luis3_btn.justPressed  ())  {
      Keyboard.press('l'); Keyboard.releaseAll();
    //if (next1_btn.justPressed  ())  //If I put this line instead of the one below, the buttons work perfect, but can not change pages from the Mega of course... the same in the other case.
    if (Serial1.readBytes(mystr2, 8) == 8) {
      control = '1';
  if (control == '1') {
    back1_btn.press(down && back1_btn.contains(pixel_x, pixel_y));
    color1_btn.press(down && color1_btn.contains(pixel_x, pixel_y));
    color2_btn.press(down && color2_btn.contains(pixel_x, pixel_y));
    color3_btn.press(down && color3_btn.contains(pixel_x, pixel_y));
    if (back1_btn.justReleased ())  back1_btn.drawButton();
    if (color1_btn.justReleased    ())  color1_btn.drawButton();
    if (color2_btn.justReleased   ())  color2_btn.drawButton();
    if (color3_btn.justReleased  ())  color3_btn.drawButton();

    if (Serial1.readBytes(mystr, 6) == 6) {
      control = '0';
void first_Page() {
  next1_btn.initButton(&tft, 410, 25, 140, 30, GREEN, BLACK, GREEN, "TO COLOR", 2);
  on_btn.initButton(&tft,  70, 150, 100, 40, WHITE, BLACK, GREEN, "CUT", 2);
  off_btn.initButton(&tft, 410, 150, 100, 40, WHITE, BLACK, GREEN, "FADE", 2);
  luis_btn.initButton(&tft, 70, 250, 140, 60, GREEN, BLACK, WHITE, "REWIND", 2);
  luis2_btn.initButton(&tft, 240, 250, 140, 60, GREEN, BLACK, WHITE, "STOP", 2);
  luis3_btn.initButton(&tft, 410, 250, 140, 60, GREEN, BLACK, WHITE, "FORWARD", 2);
void second_Page() {
  back1_btn.initButton(&tft, 70, 25, 140, 30, MAGENTA, BLACK, GREEN, "TO EDIT", 2);
  color1_btn.initButton(&tft, 70, 250, 140, 60, MAGENTA, BLACK, YELLOW, "CURVES", 2);
  color2_btn.initButton(&tft, 240, 250, 140, 60, MAGENTA, BLACK, YELLOW, "LUTS", 2);
  color3_btn.initButton(&tft, 410, 250, 140, 60, MAGENTA, BLACK, YELLOW, "BALANCE", 2);


The forum limit do not let me put the complete transmiter code, but this the part that send the data:

if (page1_btn.justPressed     ())  {
      Serial.write(mystr, 6);

Any help will be very appreciated.

Thanks in advance :slight_smile:

Serial.readbytes ties up the processor 100% UNTIL it either receives the specified number of bytes, or times out. Either way, it is preventing ANYTHING else from happening for a very long time.

Read and follow the thread at the top of the forum on how to PROPERLY handle serial input.

Ray L.

Have a look at the examples in Serial Input Basics - simple reliable, non-blocking ways to receive data.


As sugested, I went to the examples basics and learn the correct way… thanks, is working fine now :slight_smile:

I have another issue… when changing pages, the buttons of the first one (visually) disappear as they should, but when I press the buttons of the second page some of them execute the commands corresponding to buttons that are in the first page.

I have tried for many hours changing the place where the initButton is located and things like that…

The code exceeds the allowed characters, thats why I put it as an atachment

Any idea of what could be happening?
Thanks a lot

MEGA_control__LEONARDO_Check.ino (8.77 KB)

I am not familiar with the Adafruit_GFX library which seems to be controlling the buttons.


if (page1_btn.justPressed     ())  {
      Serial.write(mystr, 6);

That "delay(500);" will prevent your sketch from doing anything for half a second. Remove it.

Have you tried a higher serial baud rate?

Tom.. :slight_smile:

Hello all.
I solved the problem!!!

The reason of the wrong actions was that the code was swaping ALT and SHIFT presses.
I put this at the beginning of the code:

char ctrlKey = KEY_LEFT_CTRL; 
char altKey = KEY_LEFT_ALT; 
char shiftKey = KEY_LEFT_SHIFT;

And then I use it in the loop this way:

if (next1_btn.justPressed  ())  {
      Keyboard.press(shiftKey); Keyboard.press('6');Keyboard.releaseAll();
      next1invert_btn.drawButton(); oninvert_btn.drawButton(); offinvert_btn.drawButton(); luisinvert_btn.drawButton(); luis2invert_btn.drawButton(); luis3invert_btn.drawButton();
      control = '1';

Hope this could help someone else whit the same problem.

How can be edited the topic to "SOLVED"?

Thank you all :slight_smile:

How can be edited the topic to "SOLVED"?

If you modify your Original Post you can add the word SOLVED to the title.