Go Down

Topic: Help with 3.5" tft menu (Read 338 times) previous topic - next topic

mannymiller

Hey everyone,

im trying to put together a menu to control  12 vu meters, and 12 standby patterns using a stick of ws2812b.  i have the homepage done, which has 2 sub menus of standby and vu meters. each sub menu has 12 buttons to select each vu meter / or pattern and a return to home button. all woking fine.

now my issue. both home / return buttons work fine.

Code: [Select]
if (currentPage == 1){
      if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
         
          //map(value, fromLow, fromHigh, toLow, toHigh)
          p.x = map( p.x, TS_MINX, TS_MAXX,0,  480 );
          p.y = map( p.y, TS_MINY, TS_MAXY, 0, 320 );
           
          if(p.x>380 && p.x<470 && p.y>260 && p.y<300 ){
              tft.fillRoundRect(380, 260, 60, 30, 8, BLACK);
              tft.drawRoundRect(380, 260, 60 , 30, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE); 
              tft.setCursor(395, 268);
              tft.print("<<");
                      currentPage = 0;         
                      drawHomeScreen();
          }

           if(p.x>360 && p.x<470 && p.y>200 && p.y<300 ){
              tft.fillRoundRect(360, 200, 80, 40, 8, BLACK);
              tft.drawRoundRect(360, 200, 80 , 40, 8, WHITE);
               tft.setTextSize(2);
              tft.setTextColor(WHITE); 
              tft.setCursor(390, 213);
              tft.print("12");
                      currentPage = 0;         
                      drawpageone();
          }

          if(p.x>255 && p.x<470 && p.y>200 && p.y<300 ){
              tft.fillRoundRect(255, 200, 80, 40, 8, BLACK);
              tft.drawRoundRect(255, 200, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE); 
              tft.setCursor(284, 213);
              tft.print("11");
                      currentPage = 0;         
                      drawpagetwo();
          }
      }       
  } // end of page 1


home button is noted as <<, in the menu if i select it, it runs through the return page, then page one, then stops at page two...  what i am trying to achive is it stopping on the selection. so when i select home it does just that, not go through page one, and page two..

be gentle please...

Impulsive

Hi mannymiller --

If you are seeing your display "run through the pages" upon a touch press, then it is likely you are missing some "state" that ensures action is only taken on touch event transitions (ie. when p.z transitions from pressed to released). From the code snippet it is a little hard to get the full context of what your main loop looks like and how the drawHomeScreen() / drawpage*() calls are currently defined. Are you able to share/attach the full sketch to your post? (this should make it easier for people to offer more direct suggestions)
Arduino GUI - https://github.com/ImpulseAdventure/GUIslice

mannymiller

#2
Apr 05, 2019, 09:27 am Last Edit: Apr 05, 2019, 01:39 pm by mannymiller
Hi, Impulsive, thanks for your reply.  here part of the code with a little more info., it wont let me post the full version it seems to have hit its character limit, and yes At this time it is running through the pages.

this is for a vu meter update update on my youtube channel.  ( cine-lights ) obviously any help, credit will be given as always in the posting of the video. thanks again

Code: [Select]



void drawpageone()
{
  
  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 479, 319, 8, RED);     //Page border

  
  tft.setTextSize(2);
  tft.setCursor(170, 30);
  tft.setTextColor(WHITE);
  tft.print("CINE-LIGHTS");
  

  tft.fillRoundRect(60, 100, 360, 40, 8, RED);
  tft.drawRoundRect(60, 100, 360, 40, 8, WHITE);  
  tft.setTextColor(WHITE);
  
  tft.setCursor(185, 115);
  tft.print("VU Meters");
  tft.setTextSize(3);
  tft.setCursor(160, 200);
  tft.setTextColor(WHITE);
  tft.print("Vu Meter 12");    
}

void drawpagetwo()
{
  
  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 479, 319, 8, RED);     //Page border

  
  tft.setTextSize(2);
  tft.setCursor(170, 30);
  tft.setTextColor(WHITE);
  tft.print("CINE-LIGHTS");
  

  tft.fillRoundRect(60, 100, 360, 40, 8, RED);
  tft.drawRoundRect(60, 100, 360, 40, 8, WHITE);  
  tft.setTextColor(WHITE);
  
  tft.setCursor(185, 115);
  tft.print("VU Meters");
  tft.setTextSize(3);
  tft.setCursor(160, 200);
  tft.setTextColor(WHITE);
  tft.print("Vu Meter 11");    
}


void loop(void) {
  
 
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);
  
  buttonEnabled = true;
  
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  
   if (currentPage == 0){
      if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
              
          //map(value, fromLow, fromHigh, toLow, toHigh)
          p.x = map( p.x, TS_MINX, TS_MAXX,0,  480 );
          p.y = map( p.y, TS_MINY, TS_MAXY, 0, 320 );                
          
          if(p.x>60 && p.x<400 && p.y>100 && p.y<120 )// The user has pressed inside the red rectangle
          {
                            
              currentPage = 1;
     //// ......    PAGE 1 IS THE SAME AS PAGE 2 - HAD TO REMOVE IT DUE TO EXCEEDING CHARACTER
                     LIMIT


              currentPage = 2;
              tft.fillScreen(BLACK);
              tft.drawRoundRect(0, 0, 479, 319, 8, BLUE);     //Page border


               // top row buttons

              
              tft.fillRoundRect(40, 80, 80, 40, 8, RED);
              tft.drawRoundRect(40, 80, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(74, 93);
              tft.print("1");

              tft.fillRoundRect(145, 80, 80, 40, 8, RED);
              tft.drawRoundRect(145, 80, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(179, 93);
              tft.print("2");
              

              tft.fillRoundRect(255, 80, 80, 40, 8, RED);
              tft.drawRoundRect(255, 80, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(289, 93);
              tft.print("3");

              tft.fillRoundRect(360, 80, 80, 40, 8, RED);
              tft.drawRoundRect(360, 80, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(394, 93);
              tft.print("4");

              // middle row buttons

              tft.fillRoundRect(40, 140, 80, 40, 8, RED);
              tft.drawRoundRect(40, 140, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(74, 153);
              tft.print("5");

              tft.fillRoundRect(145, 140, 80, 40, 8, RED);
              tft.drawRoundRect(145, 140, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(179, 153);
              tft.print("6");

              tft.fillRoundRect(255, 140, 80, 40, 8, RED);
              tft.drawRoundRect(255, 140, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(289, 153);
              tft.print("7");
 

              tft.fillRoundRect(360, 140, 80, 40, 8, RED);
              tft.drawRoundRect(360, 140, 80 , 40, 8, WHITE);
               tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(394, 153);
              tft.print("8");

              // lower row buttons

              tft.fillRoundRect(40, 200, 80, 40, 8, RED);
              tft.drawRoundRect(40, 200, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(74, 213);
              tft.print("9");

              tft.fillRoundRect(145, 200, 80, 40, 8, RED);
              tft.drawRoundRect(145, 200, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(174, 213);
              tft.print("10");

              tft.fillRoundRect(255, 200, 80, 40, 8, RED);
              tft.drawRoundRect(255, 200, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(284, 213);
              tft.print("11");

              tft.fillRoundRect(360, 200, 80, 40, 8, RED);
              tft.drawRoundRect(360, 200, 80 , 40, 8, WHITE);
               tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(390, 213);
              tft.print("12");

              tft.fillRoundRect(380, 260, 60, 30, 8, RED);
              tft.drawRoundRect(380, 260, 60 , 30, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(395, 268);
              tft.print("<<");
                            
              tft.setTextSize(2);
              tft.setCursor(170, 30);
              tft.setTextColor(WHITE);
              tft.print("STANDBY MENU");
    
              if(p.x>390 && p.x<435 && p.y>270 && p.y<285 ){
                  currentPage = 0;
                  drawHomeScreen();
                  
              }
              
      
          }
      }
  }


  if (currentPage == 1){
      if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
        
          //map(value, fromLow, fromHigh, toLow, toHigh)
          p.x = map( p.x, TS_MINX, TS_MAXX,0,  480 );
          p.y = map( p.y, TS_MINY, TS_MAXY, 0, 320 );
          
          if(p.x>380 && p.x<470 && p.y>260 && p.y<300 ){
              tft.fillRoundRect(380, 260, 60, 30, 8, BLACK);
              tft.drawRoundRect(380, 260, 60 , 30, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(395, 268);
              tft.print("<<");
                      currentPage = 0;          
                      drawHomeScreen();
          }

           if(p.x>360 && p.x<470 && p.y>200 && p.y<300 ){
              tft.fillRoundRect(360, 200, 80, 40, 8, BLACK);
              tft.drawRoundRect(360, 200, 80 , 40, 8, WHITE);
               tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(390, 213);
              tft.print("12");
                      currentPage = 0;          
                      drawpageone();
          }

          if(p.x>255 && p.x<470 && p.y>200 && p.y<300 ){
              tft.fillRoundRect(255, 200, 80, 40, 8, BLACK);
              tft.drawRoundRect(255, 200, 80 , 40, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(284, 213);
              tft.print("11");
                      currentPage = 0;          
                      drawpagetwo();
          }
      }      
  } // end of page 1

  if (currentPage == 2){
      if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
        
          //map(value, fromLow, fromHigh, toLow, toHigh)
          p.x = map( p.x, TS_MINX, TS_MAXX,0,  480 );
          p.y = map( p.y, TS_MINY, TS_MAXY, 0, 320 );
          
           if(p.x>380 && p.x<470 && p.y>260 && p.y<300 ){
              tft.fillRoundRect(380, 260, 60, 30, 8, BLACK);
              tft.drawRoundRect(380, 260, 60 , 30, 8, WHITE);
              tft.setTextSize(2);
              tft.setTextColor(WHITE);  
              tft.setCursor(395, 268);
              tft.print("<<");
                      currentPage = 0;          
                      drawHomeScreen();
          }
      }      
  } // end of page 2

}

Impulsive

Thanks for the update. To avoid the character limit restriction, could you try attaching the full sketch to your post? (the file attachment option is located below the reply window) It would be useful to see your drawHomeScreen() and setup() functions.
Arduino GUI - https://github.com/ImpulseAdventure/GUIslice

mannymiller

Hi Impulsive.. i didnt see that option. thanks

Impulsive

#5
Apr 07, 2019, 08:37 am Last Edit: Apr 07, 2019, 08:41 am by Impulsive
Hi mannymiller --

I have now gone through your code in detail and have a number of suggestions. I can see the problem you encountered with the code "running through the screens". As you are probably aware, there are many areas where the code could be optimized (and constructed easier to maintain), but I thought it might be helpful to begin by showing you how to address the specific problems you described in your post.

What I did (in the attached MENU-mod1.ino code) was:
  • Rearrange your code to split out the screen display functionality from the touch handling. I suspect this was one hurdle you may have encountered when writing the code. By separating the display from the user input, it actually becomes much easier since each part works independent of the other (and there is a clear means of communicating between the two).
  • Changed the code to use edge-detection on touch presses, so that only touch releases will trigger a selection
  • Adjusted the touch detection to use the same coordinate ranges as your buttons.
  • Please note that I deliberately attempted to minimize the changes to your code as I thought it may be easier to recognize this concept before moving on to other optimizations, button highlighting, etc.


I would estimate that the length of your code could potentially be reduced 90% after constructing a few reusable functions to display buttons, track their placement, etc. Doing so would also make it much easier to maintain (I would recommend creating a "drawButton" that accepts a coordinate, label and potentially a "selected" state). Note that I don't have the same screen or calibration settings as you, so you may still need to make some mods to match your setup.

I hope this is helpful to give you a start. Sounds like a fun project!

It is probably also worth noting that there are far easier ways to approach the creation of user interfaces like this. GUI libraries are generally able to handle most of the code responsible for drawing the controls, tracking their presses, highlights, redraws, etc. But writing it yourself is also a great way to learn the fundamentals of how they work!
Arduino GUI - https://github.com/ImpulseAdventure/GUIslice

mannymiller

Hey Impulsive.

Great Job, Thankyou so much. i have made many vu meters, with mic, line in, mono and stereo versions. using the msgeq7 breakout board ( cine-lights ).

I have tried many switching methods, the last being bluetooth which worked ok, except for the interupt issues.  it was just about ok on the mono versions, but stereo was almost unusable. , so thought i would try something different. ( reason for the touchscreen).

i have one or 2 projects left before i can jump on this one again. once done i will post a video of the working project. obviosuly full credit to you for your help. very much appreciatted.

mannymiller

Hey everyone.. im after some help again.

Impulsive did a great job helping with getting my menu working, which works perfect so far.

The idea is to have a full working menu being able to control a stick of neopxiels. so far i have  bootscreen that boots into a 2 button menu ( vu meters) & ( standby patterns). on each selection you are greeted with another menu of 12 buttons a= auto mode, and 11 selections and a return button.

The idea is to have 11 vu meters, and auto mode to cycle through all 11 modes., the same apply to standby patterns, 11 patterns and an automode.

i have added all the vu meter patterns. when adding them to the selected button code i just get a few lit leds, then nothing.

Code: [Select]
   }  if (p.x>145 && p.x<(145+80) && p.y>80 && p.y<(80+40)) {
          vu(); // <====== link to vu meter
          tft.fillRoundRect(145, 80, 80, 40, 8, BLACK);
          tft.drawRoundRect(145, 80, 80 , 40, 8, WHITE);
          tft.setTextSize(2);
          tft.setTextColor(WHITE); 
          tft.setCursor(179, 93);
          tft.print("1");
          currentPage = PG_VU; // Not sure what you want to do here
          bNeedRedraw = true;



 i have added a push button list which works.  i can not seem to work out how to get the vu meter to work with the screen button, instead of the push button.

i have attached the code. the push button menu is still inserted. i have also added my attempt to the first 3 buttons All2, and vu, vu1 which do not work

any help or direction would be great.

Impulsive

Hi mannymiller --

If I understand your question correctly, you'd like to replace your buttonState logic with the touchscreen menu (perhaps the VU meter page)? Ie. you would like to have the twelve on-screen buttons on PG_VU react like toggle buttons (only one can be pressed at a time) and then initiate the NeoPixel vu*() actions?
Arduino GUI - https://github.com/ImpulseAdventure/GUIslice

Go Up