Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Creating a GUI of sorts - Teensy 3.1 and 2.2" ILI9341 Display

  1. #1
    Junior Member
    Join Date
    Jan 2015
    Posts
    5

    Creating a GUI of sorts - Teensy 3.1 and 2.2" ILI9341 Display

    Hey all... round two of questions

    Here's a synopsis of my design:

    I'm creating a MIDI controllable guitar pedal. Ideally, I'll have my void loop running as quickly as possible to keep up with / process any incoming MIDI signals (program change and CC messages). I would like to have visual feedback on my LCD display as the program is running (for example, if there are no incoming MIDI messages it will show the currently selected preset, if there is a program change the number on the display will update accordingly). Later on, I'll be implementing a rotary encoder to scroll through a menu to change any options I need to.

    The first (expected) problem that arrises is that my display will constantly refresh with the loop. I am hesitant to add a delay inside any of the TFT functions because I don't want to slow down the MIDI read process. I've tried a couple iterations of while and do while loops to try and solve the problem but to no avail. My current code is below(I do have a delay in the main loop just so I don't die from the strobe effect). In essence, I want the MIDI.read() function to constantly be waiting for an input while I have a steady output to my display.

    My intuition tells me that interrupts will have to be implemented somehow, but I'm not sure quite how to start with such an endeavour. Any guidance would be heartily appreciated!



    Code:
    #include "SPI.h"
    #include "ILI9341_t3.h"
    #include <Wire.h>
    #include <EEPROM.h>
    #include <MIDI.h>
    #include <midi_Defs.h>
    #include <midi_Message.h>
    #include <midi_Namespace.h>
    #include <midi_Settings.h>
    
    
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, MIDI);  // create an instance of MIDI using hardware serial serial 3 port
    
     struct Preset{
      byte lOhm;
      byte lWet;
      byte rOhm;
      byte rWet;
    };
    
    // MIDI Function Prototypes
    
    void PresetStore(struct Preset pToWrite, int presetNum);
    struct Preset PresetRead(int presetNum);
    void GlobalSettings();
    
    
    // For the Adafruit shield, these are the default.
    #define TFT_DC 9
    #define TFT_CS 10
    
    // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
    // If using the breakout, change pins as desired
    //Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
    
    
    
    void setup() {
      Serial.begin(9600);
      
      // MIDI Setup
      MIDI.setHandleProgramChange(DealWithProgramChange);
      MIDI.setHandleControlChange(DealWithControlChange);
      MIDI.begin(MIDI_CHANNEL_OMNI);
      
      // ILI9341 Setup
      Serial.println("ILI9341 Test!"); 
      tft.begin();
    
      // read diagnostics (optional but can help debug problems)
      uint8_t x = tft.readcommand8(ILI9341_RDMODE);
      Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDMADCTL);
      Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDPIXFMT);
      Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDIMGFMT);
      Serial.print("Image Format: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDSELFDIAG);
      Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 
      
      Serial.println(F("Benchmark                Time (microseconds)"));
    
      Serial.print(F("Screen fill              "));
      Serial.println(testFillScreen());
      delay(500);
    
    }
    
    // MAIN LOOP
    
    void loop(void) {
      
      while(MIDI.read() == 0)
       { 
         presetScreen();
         delay(10000);
       }
     
      }
    
    
    // DISPLAY FUNCTIONS
    
    unsigned long testFillScreen() {
      unsigned long start = micros();
      tft.fillScreen(ILI9341_BLACK);
      tft.fillScreen(ILI9341_RED);
      tft.fillScreen(ILI9341_GREEN);
      tft.fillScreen(ILI9341_BLUE);
      tft.fillScreen(ILI9341_BLACK);
      return micros() - start;
    }
    
    unsigned long testText() {
      tft.fillScreen(ILI9341_BLACK);
      unsigned long start = micros();
      tft.setCursor(0, 0);
      tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
      tft.println("Hello World!");
      tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
      tft.println(1234.56);
      tft.setTextColor(ILI9341_RED);    tft.setTextSize(3);
      tft.println(0xDEADBEEF, HEX);
      tft.println();
      tft.setTextColor(ILI9341_GREEN);
      tft.setTextSize(5);
      tft.println("Groop");
      tft.setTextSize(2);
      tft.println("I implore thee,");
      tft.setTextSize(1);
      tft.println("my foonting turlingdromes.");
      tft.println("And hooptiously drangle me");
      tft.println("with crinkly bindlewurdles,");
      tft.println("Or I will rend thee");
      tft.println("in the gobberwarts");
      tft.println("with my blurglecruncheon,");
      tft.println("see if I don't!");
      return micros() - start;
    }
    
    
    unsigned long presetScreen(){
      tft.fillScreen(0xD6EBFF);
      unsigned long start = micros();
      tft.setCursor(20, 25);;
      tft.setRotation(1);
      tft.setTextColor(ILI9341_BLUE);  tft.setTextSize(7);
      tft.println("Preset");
      tft.setCursor(197, 100);
      tft.setTextSize(6);
      tft.println("xx");
    }
    
    
    // MIDI FUNCTIONALITY
    // Program Change Handler
    
    void DealWithProgramChange(byte channel, byte number)
    {
      int ch, bank;
      
      ch = MIDI.getChannel();
      bank = MIDI.getData1();
      
      Serial.println(String("Program change") + bank + "on channel" + ch + "received!");
     
    }
    
    // Control Change Handler
    
    void DealWithControlChange(byte channel, byte number, byte value)
    {
      int ch, param, ccValue;
      
      ch = MIDI.getChannel();
      param = MIDI.getData1();
      ccValue = MIDI.getData2();
      
      Serial.println(String("Control change param of ") + param + "on channel" + ch + "with value of" + ccValue + "received!");
    
    }

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,108
    Instead of refreshing the screen constantly, use a variable to track if anything has changed. Only update the screen if there has been a change.

  3. #3
    What are you drawing to the screen? Simple text and lines are drawn very quickly. Bitmaps can take a little longer. I would remove or reduce the microdelays in adafruits library because they were written for slow Arduino.

    Also remember that USB has buffer space on both ends so you wont be losing data easily.

    Have you built or tested any of this yet? How does it behave?

  4. #4
    Junior Member
    Join Date
    Jan 2015
    Posts
    5
    Success Nantonos, thank you!

    For future reference, I made the following changes to my code:

    Code:
    // defined two global variables that can be modified by any function
    
    byte prevPreset = 0;
    byte curPreset = 0;
    
    // added the following to void setup() to start the screen
    presetScreen(0);
    
    // changed void loop() to the following
    void loop(void) {
      
      MIDI.read();
      
      if(prevPreset != curPreset)
        presetScreen(curPreset);
      else;
      
      prevPreset = curPreset;
    }
    
    // changed the argument for the default preset screen to unsigned int from void
    unsigned long presetScreen(unsigned int preset){
      tft.fillScreen(0xD6EBFF);
      unsigned long start = micros();
      tft.setCursor(20, 25);;
      tft.setRotation(1);
      tft.setTextColor(ILI9341_BLUE);  tft.setTextSize(7);
      tft.println("Preset");
      tft.setCursor(197, 100);
      tft.setTextSize(6);
      tft.println(preset);
    }
    
    // modified my program change handler to modify curPreset when a program change is received
    void DealWithProgramChange(byte channel, byte number)
    {
      int ch, bank;
      
      ch = MIDI.getChannel();
      bank = MIDI.getData1();
      
      Serial.println(String("Program change") + bank + "on channel" + ch + "received!");
     
      curPreset = bank; 
    }
    Until next time,

    Nick

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •