Menu and encoder handling how?

Status
Not open for further replies.

Bastiaan

Well-known member
Hello guys,

i am currently trying some stuff, i am using the st7735 with a teensy3.2 and encoder from Sparkfun. i am using the buttonEvent to scroll down and up(double click in the menu).

there are two questions i have.

i would like to see the value of the encoder first on the screen by turning the encoder, and then if i press the push button the value should be saved on the screen. momentarily i have it reversed, because i have multiple states and require therefore specific limits for (hours, minutes, seconds, R,G,B, ON and OFF times and Intensity). the current (rotating encoder) doesnt show the update of the values on the screen, only if I push the pushbutton and it goes to step 2 of the menu.

i have this done over 2 functions. Menucount and MenuCountdown both function run parallel and react to the menu states.

is there a better way, so that the values on the screen become visable?

second question: i would like to erase the values on the screen if i reach the end of the menu and start all over again, is there a way?


i tried this also on a Oled display and this works much better, and i would like to understand it why.

Code:
#define ENCODER_OPTIMIZE_INTERRUPTS

/*

 * *
   MENU
   Set RGB Color combination. double click for moving backwards.

   wavelength ws2812 max is at
   RED=630nm at 78mw/m2
   Green=520 at 37mw/m2
   Blue=455nm at 180mW/m2

  MENU1 set RED value till 255
  MENU2 Set Green value till 255
  MENU3 set Blue value till 255
  MENU4 set Intensity in PWM
  ///////////////////////

  MENU5 set Start
  MENU6 set Stop

  ///////////////////////

  MENU 7 Seconds
  MENU 8 Minutes
  MENU 9 Hours

  MENU 10 Start



*/

///
/*
   changes that are made since 2020, other buttonevent library is installed,allowing forward and backward movement of the menu (double Click)
   Clean up of the whole code.

*/



#include <Encoder.h>
#include <stdio.h>
#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h>
#include <FlickerFreePrint.h>
#include <ADC.h>
#include <ButtonEvents.h>
#include <CountUpDownTimer.h> //:)
#include <Adafruit_NeoPixel.h>
// Hardware-specific library for ST7789

// Core graphics library
#include <FlickerFreePrint.h>
// library to draw w/o flicker
// custom fonts for the ILI9341_t3.h

// some defines for pins
#define TFT_MISO  12
#define TFT_MOSI  11  //a12
#define TFT_SCK   13  //a13
#define TFT_DC   10
#define TFT_CS   9
#define TFT_RST  8


#define C_BLACK       0x0000
#define C_BLUE        0x001F
#define C_RED         0xF800
#define C_GREEN       0x07E0
#define C_CYAN        0x07FF
#define C_MAGENTA     0xF81F
#define C_YELLOW      0xFFE0
#define C_WHITE       0xFFFF



#define PIN     7
#define NUMPIXELS      64




///Function CountDownTimer
int PWMValue = 0;
const byte buttonPin = 2;


byte menuCount = 1;
byte IntCount = 1;
byte HoldCount = 1;
byte dir = 0;
bool runState = false;
bool runState2 = false;

long oldPosition  = -255;
long newPosition = 0;
long Position;

long oldPWMPosition = -100;
long PWMPosition = 1;

unsigned long Days = 1;
unsigned long Hours = 0;
unsigned long Minutes = 0;
unsigned long Seconds = 0;

signed long Sec = 0;

unsigned long startTime;
unsigned long oneSecond = 1000UL;

int awake;

/*  Teensy3.2 Pins
  FTM0 5, 6, 9, 10, 20, 21, 22, 23 488.28 Hz
  FTM1  3, 4  488.28 Hz
  FTM2  25, 32  488.28 Hz


*/


unsigned int RED = 0;
unsigned int BLUE = 0;
unsigned int GREEN = 0;
unsigned int INTENSITY = 0;
unsigned int ON_Time1 = 0; // default
unsigned int OFFTime1 = 0;// default

//maybe make this new... with buttonevents
unsigned int count = 0;            // how many times has it changed to low
unsigned long countAt = 0;         // when count changed
unsigned int countPrinted = 0;

unsigned int icount = 0;            // how many times has it changed to low
unsigned long icountAt = 0;         // when count changed
unsigned int icountPrinted = 0;

//Function Interval Timer

int ON_LT3760 = LOW;
int minimumLT3760 = 10; //minimum pwm width needed to switch on off the lt3760

unsigned long PreviousMillis = 0;
unsigned long nowMillis;//important
elapsedMillis ElapsedOFF;
elapsedMillis ElapsedON;
int repeats = 1;
int Intensity = 0;
int i = 0;

int Readout_pinA10;

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
FlickerFreePrint<Adafruit_ST7735> Data2(&tft, C_WHITE, C_BLACK);

Encoder Timer_1(3, 4);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); //led matrix cjmcu-8x8

float j;
unsigned long StartTime, EndTime;
char str[30];
elapsedMillis msecs;

// 10 ms debounce

ADC *adc = new ADC(); // adc object

ButtonEvents myButton;
//SPI connection ST7735

void setup()
{



  pixels.begin();





  Serial.begin(115200);
  pinMode(buttonPin, INPUT_PULLUP);
  myButton.attach(buttonPin);
  myButton.activeHigh();
  myButton.debounceTime(15); //apply 15ms debounce
  myButton.doubleTapTime(250);//apply 250ms Double click detection
  myButton.holdTime(2000); // require button to be held for 2000ms before triggering a hold event
  pixels.begin();
  pinMode(6, OUTPUT); //SHDN Not Pin, switch on the LT3760
  //analogPin for switching between UV to IR current limitation.

  tft.initR(INITR_BLACKTAB);
  tft.setRotation(4);
  tft.fillScreen(C_BLACK);
  tft.setTextSize(1);
  tft.fillRect(0, 0, 150, 5, C_RED);

  //Menu0

  tft.setCursor(5, 10);
  tft.print("Days");
  //Menu1
  tft.setCursor(5, 20);
  tft.print("Hours");
  //Menu2
  tft.setCursor(5, 30);
  tft.print("Minutes");
  //Menu3
  tft.setCursor(5, 40);
  tft.print("Seconds");
  //Menu4
  tft.setCursor(5, 50);
  tft.print("OFFTime");
  //Menu5
  tft.setCursor(5, 60);
  tft.print("ONTime   ");
  //Menu5
  tft.setCursor(5, 70);
  tft.print("RED ");
  //Menu6
  tft.setCursor(5, 80);
  tft.print("GREEN ");
  //Menu7
  tft.setCursor(5, 90);
  tft.print("BLUE ");
  //Menu8
  tft.setCursor(5, 100);
  tft.print("INTENSITY");



}

void loop()
{

  Menu1Check();


  Menu1Countdown();

}










//this one is important because it controls all the menus
//read PWM Timer_1oder


int Menu1Check()
{
  if (myButton.update() == true)

  {





    switch (myButton.event())

    {

      // things to do if the button was tapped (single tap)

      case (tap) :

        {

          Serial.print("Single Click event detected = ");



          menuCount = menuCount + 1;

          Serial.print("MenuCountUp = ");

          //(menuCount);

          break;

        }

      case (doubleTap) :                                            //double click function move back in menu-1

        {

          Serial.print(" DOUBLE-TAP event detected ");

          menuCount = menuCount - 1;

          Serial.print(" DB TAP Count Down ");


          //(menuCount);

          break;

        }
      case (hold) :
        {
          Serial.println("HOLD event detected");
          break;
          HoldCount = HoldCount + 1; //To activate timer.
        }

    }



    //limit the menu, Timer_1oder buttonpin

    if (menuCount > 13)
    { Serial.print("menu larger as 10");
      menuCount = 0;

    }

    if (menuCount == 1)
    {
      Serial.println("Menu1");
      if (oldPosition >= 0 && oldPosition <= 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition) //overwrite value compare with previous value

      {
        oldPosition = newPosition;




      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }

      if (newPosition > 0 && newPosition < 30)
      {

        Days = newPosition;


      }
      else
      {
        Days = 1;
      }
    }






    if (menuCount == 2)
    {

      Serial.println("Menu2");


      if (oldPosition >= 0 && oldPosition <= 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition) //overwrite value compare with previous value

      {
        oldPosition = newPosition;




      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }

      if (newPosition > 0 && newPosition < 59)
      {

        Hours = newPosition;


      }
      else
      {
        Hours = 12;
      }
    }

    if (menuCount == 3)
    { Serial.print("Menu3");

      if (oldPosition >= 0 && oldPosition <= 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition)

      {


        oldPosition = newPosition;


      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }

      if (newPosition > 0 && newPosition < 99)
      {

        Minutes = newPosition;


      }
      else
      {
        Minutes = 0;
      }





    }
    if (menuCount == 4)
    { Serial.print("Menu7");

      if (oldPosition >= 0 && oldPosition <= 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition)

      {

        oldPosition = newPosition;
      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }


      if (newPosition > 0 && newPosition < 59)
      {

        Seconds = newPosition;


      }
      else
      {
        Seconds = 0;
      }

    }
    //


    if (menuCount == 5)
    {

      Serial.println("set timer 1");

      Timer_1.write(0);

    }

    if (menuCount == 6)
    {


      if (oldPosition >= 0 && oldPosition <= 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition)

      {
        oldPosition = newPosition;



      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }

      if (newPosition > 0 && newPosition < 255)
      {

        OFFTime1 = (newPosition * 100);
      }
      else
      {
        OFFTime1 = 20000;
      }

    }





    if (menuCount == 7)
    {

      if (oldPosition >= 0 && oldPosition <= 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition)

      {
        oldPosition = newPosition;

      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }
      if (newPosition > 0 && newPosition < 255)
      {

        ON_Time1 = newPosition * 100; //Default value if new Position is not pressed


      }
      else
      {
        ON_Time1 = 10000;
      }


    }

    if (menuCount == 8)
    {

      if (oldPosition >= 0 && oldPosition < 255)

        oldPosition = 0;

      newPosition = Timer_1.read();
      newPosition = newPosition / 4;
      if (newPosition != oldPosition)
      {
        oldPosition = newPosition;





      }   else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }

      if (newPosition > 0 && newPosition < 255)
      {
        RED = newPosition;
        //RED = constrain(RED, 0, 255);
      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        RED = 0;
      }

    }

    if (menuCount == 9)
    {



      if (oldPosition >= 0 && oldPosition < 255)

        oldPosition = 0;


      newPosition = Timer_1.read();


      newPosition = newPosition / 4;
      if (newPosition != oldPosition)

      {
        oldPosition = newPosition;
      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);

      }


      if (newPosition > 0 && newPosition < 255)
      {
        GREEN = newPosition;
        // GREEN = constrain(GREEN, 0, 255);

      }  else //everything that is beyond the oldPosition or not equal to newPosition
      {
        GREEN = 247;
      }
    }

    if (menuCount == 10)
    {

      if (oldPosition >= 0 && oldPosition < 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition)

      {
        oldPosition = newPosition;




      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }


      if (newPosition > 0 && newPosition < 255)
      {
        BLUE = newPosition;


      }  else
      {
        BLUE = 255;
      }
    }

    if (menuCount == 11)
    {
      if (oldPosition >= 0 && oldPosition < 255)

        oldPosition = 0;



      newPosition = Timer_1.read();


      newPosition = newPosition / 4;

      if (newPosition != oldPosition)

      {
        oldPosition = newPosition;




      }
      else //everything that is beyond the oldPosition or not equal to newPosition
      {
        Timer_1.write(0);
      }


      if (newPosition > 0 && newPosition < 255)
      {
        INTENSITY = newPosition;


      }  else
      {
        INTENSITY = 255;
      }
    }



    if (menuCount == 12)
    {
      //start timer
      Serial.println(" starting Timer");





    }

    if (menuCount == 13)
    {
      //set repeats how many?
      //loop Timer 1
      Serial.print("condition T2 has ended, Back To Timer 1 which Menu = ");
      Serial.print(menuCount);
      menuCount = 1;
      PWMValue = 1;
    }

  }
}

///////////////////////////////////////end of MenuInterval
//Display with Menu function u8g2
//countdown menu screen

int Menu1Countdown() //Menu 1
{


  // fill to the end of field with background color.
  // menus on the display: giving in Values, other static text is in void setup




  if (menuCount > 0 && menuCount == 1)
  { pixels.clear();
    tft.setCursor(70, 10);
    Data2.print(Days);
  }

  if (menuCount > 1 && menuCount == 2)
  {
    tft.setCursor(70, 20);
    Data2.print(Hours);
  }

  if (menuCount > 3 && menuCount == 4)
  {
    tft.setCursor(70, 30);
    Data2.print(Minutes);
  }

  if (menuCount > 4 && menuCount == 5)
  {
    tft.setCursor(70, 40);
    Data2.print(Seconds);
  }

  if (menuCount > 5 && menuCount == 6)
  {
    tft.setCursor(70, 50);
    Data2.print(OFFTime1);



  }

  if (menuCount > 6 && menuCount == 7)
  {

    tft.setCursor(70, 60);
    Data2.print(ON_Time1);

    //
    //tft.fillRect(x_text_cursor, 25, 40, 25, C_BLACK);

  }


  if (menuCount > 7 && menuCount == 8)
  {

    tft.setCursor(70, 70);
    Data2.print(RED);
  }
  if (menuCount > 8 && menuCount == 9)
  {

    tft.setCursor(70, 80);
    Data2.print(GREEN);
  }

  if (menuCount > 9 && menuCount == 10)
  {

    tft.setCursor(70, 90);
    Data2.print(BLUE);


  }

  if (menuCount > 10 && menuCount == 11)
  {
    tft.setCursor(70, 100);
    tft.setTextSize(1);
    Data2.print(INTENSITY);
    tft.setCursor(1, 110);
    tft.setTextSize(2);
    tft.println("Press -->");
    //    tft.setCursor(5, 120);
    //    tft.println(" Start");
  Sec = round(Seconds * 1) + round(60 * Minutes) + round(60 * 60 * Hours) + round(60 * 60 * 24 * Days);
    
  }

  //
  if (menuCount > 11 && menuCount == 12)
  {
    pixels.clear();
    if (millis() - startTime >= oneSecond)
    {
      startTime += oneSecond;

      if (Sec < 0)
      {
        Sec = 0;

      }
      else
      {



        /// blink during the menuCount check later on Countdown Zero or not Jump to MenuCount 1
        if ((ON_LT3760 == HIGH) && (ElapsedOFF >= OFFTime1)) //OFFTime first
        {

          ON_LT3760 = LOW;
          // ElapsedOFF=ElapsedOFF-OFFTime1;
          for (int i = 0; i < NUMPIXELS; i++)
          {
            // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
            pixels.setPixelColor(i, pixels.Color(RED, GREEN, BLUE)); // Moderately bright BLUE
            pixels.setBrightness(50);
            pixels.show(); // This sends the updated pixel color to the hardware.
            //delay(delayval);
          }


          ElapsedOFF = 0; ElapsedON = 0;
          //      tft.setRotation(4);
          tft.fillRect(110, 145, 10, 10, C_RED);
        }
        else if ((ON_LT3760 == LOW) && (ElapsedON >= ON_Time1)) //ONTime Second
        {
          ON_LT3760 = HIGH;
          //    delay(OFFTime1+minimumLT3760);
          //digitalWrite(6, HIGH);
          //      tft.setRotation(4);
          tft.fillRect(110, 130, 10, 10, C_RED);
          //    delay(ON_Time1+minimumLT3760);
          ElapsedOFF = 0; ElapsedON = 0;
          for (int i = 0; i < NUMPIXELS; i++)
          { // For each pixel...
            pixels.setPixelColor(i, pixels.Color(0, 0, 0));

            pixels.show();
          }

          pixels.clear();

        }
        if (ON_LT3760 == LOW) tft.fillRect(110, 145, 10, 10, C_YELLOW); //blinking boxes depended on high low state Interval
        else       tft.fillRect(110, 130, 10, 10, C_BLUE);


        Days  =     Sec / 86400;
        Hours =     Sec / 3600;
        Minutes   = Sec / 60;
        Seconds   = Sec % 60;//end of countdown
      }

      //check countdown on Zero.

      tft.setTextSize(2);
      tft.setCursor(5, 130); //this cannot be positioned in the TimehasChanged if statement,
      //this is because the screen works with a different update on the screen. it will freeze over.


    
    // Serial.println(" R T1 ");

    Data2.print((Hours % 60) % 60);
    tft.print(":");
    Data2.print(Minutes % 60);
    tft.print(":");
    Data2.print(Seconds);


      Serial.print((Hours % 60) % 60);
      Serial.print(":");
      Serial.print(Minutes % 60);
      Serial.print(":");
      Serial.print(Seconds);
      Serial.println("end");
    Sec--;


  }
}

if (menuCount > 12 && menuCount == 13)
{
  digitalWrite(14, LOW); // digitalWrite(20,LOW);digitalWrite(19,HIGH);



  // remove all cursors clear all values on screen
  tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
  tft.setCursor(70, 20);
  tft.print("      ");           //Hours
  tft.setCursor(70, 30);
  tft.print("       ");          //Minutes
  tft.setCursor(70, 40);
  tft.print("       ");          //Seconds
  tft.setCursor(70, 50);
  tft.print("       ");          //Offtime
  tft.setCursor(70, 60);
  tft.print("       ");          //Ontime
  tft.setCursor(70, 70);
  tft.print("       ");          //Red
  tft.setCursor(70, 80);
  tft.print("       ");          //Green
  tft.setCursor(70, 90);
  tft.print("       ");          //Blue
  tft.setCursor(70, 100);
  tft.print("       ");          //Intensity
  tft.setTextSize(2);
  tft.setCursor(1, 110);
  tft.println("          ");  //Press-->
  tft.setTextSize(2);
  tft.setCursor(5, 130);
  tft.print("           ");    //Hours:Minutes:Seconds
  menuCount = 1;
}

tft.setTextSize(1);
tft.setCursor(5, 150 ); //just a symbol to show where I am in the Menu
Data2.print(menuCount);

}
 
Status
Not open for further replies.
Back
Top