Buttons/lcd problems

Okay I know the code is a hot mess but I am very new to this... I have an Arduino Mega with a 2.4 tft lcd (no touch) connected with four push buttons and an lcd strip. When you press button one screen shows number 1 led lights change color same with 2,3,4.. Trouble is I need to press the buttons several times before it kicks in, think I maybe need delay or something somewhere. Also the lcd screen blinks the words. Thinking maybe everytime it loops? Maybe a delay or something will help that I have tried but it only made the blink slower. Serial stuff is in there because I am going to pair it to another mega but waiting on parts to come in. Code is below and sorry its a mess any help would be great!

#include <EasyTransfer.h>
#include <mega_24_shield.h>
#include <uno_24_shield.h>
#include <EasyTransfer.h> //https://github.com/madsci1016/Arduino-EasyTransfer#include "OneButton.h"
#include <Wire.h>                        // Include Wire library (required for I2C devices)
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
uint16_t version = MCUFRIEND_KBV_H_;

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define GRAY    0x8410
#define LOOP_STATE_STOPPED 0
#define LOOP_STATE_STARTED 1

int bt_state = 3;
int BT_connected = 0;

#include <SoftwareSerial.h>
#include "OneButton.h"
SoftwareSerial HC12(50, 51);

// Setup a new OneButton on pin A1.
OneButton button1(22, true);
// Setup a new OneButton on pin A2.
OneButton button2(23, true);
// Setup a new OneButton on pin A1.
OneButton button3(24, true);
// Setup a new OneButton on pin A2.
OneButton button4(25, true);

#include <FastLED.h>
#define LED_PIN     27
#define NUM_LEDS    30
CRGB leds[NUM_LEDS];

int state = 0;
int period = 500; // 500 ms
unsigned long time_now = 0, time_now_2 = 0;

struct SEND_DATA_STRUCTURE
{
  // state of 4 buttons
  int btn1_state;
  int btn2_state;
  int btn3_state;
  int btn4_state;
  
};
int btn_state = 0;
SEND_DATA_STRUCTURE data;
EasyTransfer ETout;
void setup() {
  // put your setup code here, to run once:
   Serial.begin(9600);
    if (!Serial) delay(5000);           //allow some time for Leonardo
    uint16_t ID = tft.readID(); //
    tft.print(F("Diagnose whether this controller is supported"));
    tft.begin(ID);
    ETout.begin(details(data), &Serial);
     //tft.fillScreen(BLACK);

  // link the button 1 functions.
  button1.attachClick(click1);

  // link the button 2 functions.
  button2.attachClick(click2);
  //link the button 3 functions.
  button3.attachClick(click3);

  // link the button 4 functions.
  button4.attachClick(click4);

  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  HC12.begin(9600);
  ETout.begin(details(data), &HC12);
}

void loop() {
  // put your main code here, to run repeatedly:
   static uint8_t aspect = 0;
    const char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" };
    uint16_t colormask[] = { BLUE, GREEN, RED, GRAY };
    uint16_t ID = tft.readID(); //
    tft.setRotation(1);
    int width = tft.width();
    int height = tft.height();
    tft.fillScreen(colormask[aspect]);
    // tft.fillScreen(BLACK);
    tft.setTextSize(5);
    tft.setTextColor(RED);
    tft.setCursor(0, 20);
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
  //ETout.sendData();
  HC12.write(btn_state);
  if (btn_state == 1)
  {
    for (int i = 0; i <= 19; i++) {
      leds[i] = CRGB ( 0, 255, 0);
      FastLED.show();
      //delay(100);

    }
      tft.println("number 1");
      Serial.print ("number 1");

      if (btn_state ==1)
      delay(1);

  }
  if (btn_state == 2)
  {
    for (int i = 0; i <= 19; i++) {
      leds[i] = CRGB ( 255, 0, 0);
      FastLED.show();
      //delay(100);

    }
    tft.print("number2");
  }
  if (btn_state == 3)
  {
    if (millis() >= time_now + period) {
      time_now += period;
      state = !state;
    }
    if (state)
    {
      for (int i = 0; i <= 19; i++) {
        leds[i] = CRGB ( 255, 140, 0);
        FastLED.show();
        //delay(100);
      }
    }
    else
    {
      for (int i = 0; i <= 19; i++) {
        leds[i] = CRGB ( 0, 0, 0);
        FastLED.show();
        //delay(100);
      }
    }
    tft.print("number 3");
  }
  if (btn_state == 4)
  {
    if (millis() >= time_now_2 + period) {
      time_now_2 += period;
      state = !state;
    }
    if (state)
    {
      for (int i = 0; i <= 19; i++) {
        leds[i] = CRGB ( 255, 100, 0);
        FastLED.show();
        //delay(100);
      }
    }
    else
    {
      for (int i = 0; i <= 19; i++) {
        leds[i] = CRGB ( 0, 0, 0);
        FastLED.show();
        //delay(1000);
      }
    }
    tft.print("number4");
  }


}

Generally that will make things worse. Any delay means you can’t poll your buttons so it will only detect a button push at the right time. Stick a serial print in to tell you what the millis is so you can se how slow your loop is. Fast is good for buttons otherwise you need interrupts and that is rarely the answer.
You have lots of delays and commented out delays.

You mean like below? Thank you for the advice btw

 }
    tft.print("number4");
    Serial.print ("number 4");
  }

No just print millis to the serial monitor once per loop. You will see how fast each loop is. I.è the time between one millis and the next. You want to make your loop fast. Get rid of delays. Think about state machines, debouncing and non blocking timing

Ah okay sorry pretty fast I believe..
1386
1829
2272
2715
3158
3601
4043

Fast? :astonished:

Those figures look extremely slow! If that is in your loop(), then 500 ms between each - a whole half second - is ridiculously slow and there is an obvious problem with the code.

Unless it actually takes half a second to print six characters of course. :thinking:


Grave accent?

Your Euro keyboard is showing. :rofl:

1 Like

Ahh as I said I am a newbie here and I know there is problems with the code, any suggestions on fixing the problems with the buttons/lcd? I would image the slow loops would resolve with that as well.. Thank you!

Future time stamps cause timing errors every few days because of integer rollover.

Did you write this code, or copy it from somewhere and modify it?

Look up millis, blink without delay, state machines. The idea here is to learn how to code your project. There is a section where you can pay others to do it if you don’t wish to learn.
It is normally best to break your project down into individual chunks and work on getting each one functioning. You save each chunk in an appropriately named sketch and then start combining them at the end. Eg LCD screen, buttons, lcd and buttons! Thy way you can isolate errors and wind back to functioning code. It also makes it easier to encapsulate your code.

Ah okay good to know.. No I did not write this code just put several examples together to sorta do what I am trying to accomplish

Thank you for the great advice, I will look that stuff up now.. No, I do wish to learn and I have learned alot over the last few weeks but now that I sort of have it working I was just looking for advice on while it works sometimes.. I will check out your tips, thank you!

Use examples to test and understand, not as boilerplate code.

Okay just looking for direction here, I have worked on this and fixed the problem with the buttons and lcd by calling a new function but by doing so I only get the led lights to blink once, so I tried to add something to loop like if serial = this then the led but kept getting errors. Is there a way in the new function to keep blinking until a new button is pushed?

void longPressStart1() {
  Serial.println("Button 1 longPress start");
   tft.fillScreen(BLACK);
    tft.setTextColor(RED, GREY);
    tft.setTextSize(5);
    tft.setCursor(50, 120);
  tft.print("Button 1 longpress");
 
 fill_solid (leds, NUM_LEDS, CRGB(255,0,0));
  FastLED.show();
  delay(500);
  // Now turn the LED off, then pause
 fill_solid (leds, NUM_LEDS, CRGB (0,0,0));
  FastLED.show();
  delay(500);

Yes.

Post your sketch, well formated, with comments and in so called code tags "</>" to see how we can help.
Have a nice day and enjoy coding in C++.

Note that I have only made it down to button1 so far, everything runs and works but the led only blinks once.. Any advice would be great! Thank you!

#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
MCUFRIEND_kbv tft;
#include "OneButton.h"
#include <FreeDefaultFonts.h>
#include <FastLED.h>
#define NUM_LEDS 30
#define DATA_PIN 27
CRGB leds[NUM_LEDS];
int LedStat;
//Display colors 
#define BLACK   0x0000
#define RED     0xF800
#define GREEN   0x07E0
#define WHITE   0xFFFF
#define GREY    0x8410

//Setting button pins
OneButton button1(22, true);
OneButton button2(23, true);
OneButton button3(24, true);
OneButton button4(25, true);
void setup() {
  // put your setup code here, to run once:
 Serial.begin(115200);
 {
  //Display settings
  uint16_t ID = tft.readID();
  if (ID == 0xD3D3) ID = 0x9481; //force ID if write-only display
    tft.begin(ID);
    tft.setRotation(1);
    tft.setTextSize(5);
    tft.print("Starting");

    //Led setup
    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
  }

  //Button linking to function
  Serial.println("Starting...");
  button1.attachLongPressStart(longPressStart1);
  button2.attachLongPressStart(longPressStart2);
  button3.attachLongPressStart(longPressStart3);
  button4.attachLongPressStart(longPressStart4);

 

}

void loop() {
  // put your main code here, to run repeatedly:
  //Button Ticks looking for press
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
 Serial.print('Starting');

 

}


// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  Serial.println("Button 1 longPress start");  //Printing to LCD
   tft.fillScreen(BLACK);
    tft.setTextColor(RED, GREY);
    tft.setTextSize(5);
    tft.setCursor(50, 120);
  tft.print("Button 1 longpress");
 
 fill_solid (leds, NUM_LEDS, CRGB(255,0,0));  //Blinking LED
  FastLED.show();
  delay(500);
  // Now turn the LED off, then pause
 fill_solid (leds, NUM_LEDS, CRGB (0,0,0));
  FastLED.show();
  delay(500);
   
  }
   


// This function will be called once, when the button2 is pressed for a long time.
void longPressStart2() {
  Serial.println("Button 2 longPress start");
 
   
}


// This function will be called once, when the button3 is pressed for a long time.
void longPressStart3() {
  Serial.println("Button 3 longPress start");
  
   
} 


// This function will be called once, when the button4 is pressed for a long time.
void longPressStart4() {
  Serial.println("Button 4 longPress start");

      
} 

See reply #9. You have no state machine, you have no use of millis(), you have used delay() for timing instead. Thus you can not blink or implement any LED sequence that runs concurrently with the rest of the program logic.

That is your real problem, not that the function only blinks once. If you make it blink continuously without fundamentally changing your program structure to the mentioned approach, it will blink but it will freeze all other program activity.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.