Playing around with yet another version of ILI9341_t3 library (ILI9341_t3n)

I would start by removing the pinMode and digitalWrite lines. Those are setting up pin 13, however, the tft.begin() is coming along a few microseconds later and switching pin 13 to be the SPI clock signal. Perhaps at certain optimization levels the compiler is getting confused about what to do with the SPI clock line and the tft startup code is getting stuck in the startup routines because SPI transactions never finish.
 
Hi,

Thanks for the help.

I only put that led bit in after It was already going wrong to see if it started up. Didn't notice the shared pin!

I just removed it to test, same problem. I don't think we even get to setup().

Cheers

Andy
 
Things I would probably do, would be to turn on the debug kernel stuff.
Go into teesns4\debug\printf.h
and uncomment the line: //#define PRINT_DEBUG_STUFF

Then debug stuff will be printed out on Serial4, by default I believe at 115200. so hook up something to the Serial4 pins. Could be another teensy running the USBSerial sketch or could be something like an FTDI cable. And see what prints out.

You can also add in your own debug outputs when necessary using the printf_debug(...) calls
 
I just tested using the Arduino IDE, building with optimise=debug I also have the same thing there so it is not PlatformIO related.
 
You might also want to put it on it's own thread as probably not related to the ILI9341 display
 
Yep, I have seen other people having the same issues with other libs like the audio one.

I will get the debug output tomorrow and create a new thread...
 
I have problems with Midi In and ILI9341_t3n frameBuffer. Midi dropouts keep occurring. Watch my short video.
What is the reason?


C:
//********************************************************************
// Sammy   Polyhonic DIY Sampler (Degnerator 2)
// (c) Rolf Degen 11.2024 Version 1.00-01
// Teensy 4.1 600MHz
//********************************************************************

#include <Arduino.h>
#include "Audio.h"
#include <MIDI.h>
#include <SD.h>
#include <Wire.h>
#include <avr/interrupt.h>
#include "SPI.h"
#include "TeensyVariablePlayback.h"
#include "flashloader.h"
#include "ILI9341_t3n.h"
// #include <ILI9341_t4.h>
#include "Font/font_DroidSans.h"
#include "Adafruit_FT6206.h"
#include "touch_button.h"
#include "config.h"
#include "screensaver.h"
#include "GUI.h"
#include "filemanager.h"
#include "audioPatching.h"
#include "ILI9341_t3_PrintScreen.h"
#include "Font/font_LiberationSans.h"

extern "C" uint8_t external_psram_size;
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
const int Midi_channel = 1;

// Initialize tft display
DMAMEM uint16_t screenBuffer[320 * 240];
ILI9341_t3n tft(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);


// The FT6206 (touch pannel) uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ts = Adafruit_FT6206();

// Rotary encoder
#define encoder1_addr 48
#define encoder2_addr 49
#define encoder3_addr 50
#define encoder4_addr 51
#define encoder5_addr 52
#define encoder6_addr 53
#define PIN_ENC_INT 25

// Menu pages
#define Program_Menu 0
#define Osc_Menu 1
#define Filter_Menu 2
#define Envelope_menu 3

int16_t value;
boolean pressed, lastpressed;
int encoder_addr = 48; // First encoder adrdress
boolean enc_action;

int encoder_last_value[6][6] = {
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0}};

int ampEnvValue[6] = {0, 0, 0, 0, 127, 40};

// Envelope Times
const uint32_t ENVTIMES[128] PROGMEM =
    {0, 1, 2, 3, 4, 6, 10, 16, 33, 41, 49,
     58, 67, 78, 89, 99, 111, 124, 136, 150, 164, 178, 192, 209, 224, 241,
     258, 276, 295, 314, 333, 353, 374, 395, 418, 440, 464, 489, 513, 539,
     565, 592, 621, 650, 680, 710, 742, 774, 808, 843, 878, 915, 952, 991,
     1031, 1073, 1114, 1158, 1202, 1250, 1297, 1346, 1396, 1448, 1502, 1558,
     1614, 1676, 1735, 1794, 1864, 1923, 1994, 2065, 2136, 2207, 2289, 2360,
     2443, 2525, 2620, 2702, 2797, 2891, 2985, 3092, 3186, 3292, 3410, 3516,
     3634, 3752, 3882, 4012, 4142, 4272, 4413, 4567, 4708, 4862, 5027, 5180,
     5357, 5522, 5699, 5888, 6077, 6278, 6478, 6691, 6903, 7127, 7351, 7587,
     7835, 8083, 8343, 8614, 8885, 9169, 9464, 9770, 10077, 10408, 10738,
     11080, 11434, 11880};

// Linear Original
const float LINEAR[128] PROGMEM =
    {0, 0.008, 0.016, 0.024, 0.031, 0.039,
     0.047, 0.055, 0.063, 0.071, 0.079, 0.087, 0.094, 0.102, 0.11, 0.118,
     0.126, 0.134, 0.142, 0.15, 0.157, 0.165, 0.173, 0.181, 0.189, 0.197,
     0.205, 0.213, 0.22, 0.228, 0.236, 0.244, 0.252, 0.26, 0.268, 0.276,
     0.283, 0.291, 0.299, 0.307, 0.315, 0.323, 0.331, 0.339, 0.346, 0.354,
     0.362, 0.37, 0.378, 0.386, 0.394, 0.402, 0.409, 0.417, 0.425, 0.433,
     0.441, 0.449, 0.457, 0.465, 0.472, 0.48, 0.488, 0.496, 0.504, 0.512,
     0.52, 0.528, 0.535, 0.543, 0.551, 0.559, 0.567, 0.575, 0.583, 0.591,
     0.598, 0.606, 0.614, 0.622, 0.63, 0.638, 0.646, 0.654, 0.661, 0.669,
     0.677, 0.685, 0.693, 0.701, 0.709, 0.717, 0.724, 0.732, 0.74, 0.748,
     0.756, 0.764, 0.772, 0.78, 0.787, 0.795, 0.803, 0.811, 0.819, 0.827,
     0.835, 0.843, 0.85, 0.858, 0.866, 0.874, 0.882, 0.89, 0.898, 0.906,
     0.913, 0.921, 0.929, 0.937, 0.945, 0.953, 0.961, 0.969, 0.976, 0.984,
     0.992, 1.00};

unsigned long lastSamplePlayed = 0;
uint8_t channels = 2;
newdigate::audiosample *Sample;
boolean sample_busy_flag;

elapsedMillis screensaverTimer = 0;
elapsedMillis touchReadTimer = 0;
elapsedMillis screensaverResetTimer = 0;
elapsedMillis rotaryEncoder0_Timer = 0;
elapsedMillis rotaryEncoder1_Timer = 0;
elapsedMillis rotaryEncoder2_Timer = 0;
elapsedMillis rotaryEncoder3_Timer = 0;
elapsedMillis rotaryEncoder4_Timer = 0;
elapsedMillis rotaryEncoder5_Timer = 0;
elapsedMillis Task_Timer = 0;

elapsedMillis midiSymbolTimer = 0;

boolean screensaver_Active = false;
uint8_t touch_index = 0;
int pageNo = 0;
int old_pageNo = 0;
extern boolean TK_state_List_P1[6];
uint16_t loopCount = 0;
uint8_t midiSymbol_status = false;
uint8_t voiceMode = 0; // 0=poly mode 1= unsison

// Voice
struct VoiceAndNote
{
    int note;
    long timeOn;
    int voiceOn;
};
struct VoiceAndNote voices[NO_OF_VOICES] = {{-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}};
int voiceToReturn = -1;
long earliestTime = millis(); // For voice allocation - initialise to now

// Set encoder wheel parameters
void encoder_set(uint8_t encoder_addr, int16_t rmin, int16_t rmax, int16_t rstep, int16_t rval, uint8_t rloop)
{
    Wire1.beginTransmission(encoder_addr);
    Wire1.write((uint8_t)(rval & 0xff));
    Wire1.write((uint8_t)(rval >> 8));
    Wire1.write(0);
    Wire1.write(rloop);
    Wire1.write((uint8_t)(rmin & 0xff));
    Wire1.write((uint8_t)(rmin >> 8));
    Wire1.write((uint8_t)(rmax & 0xff));
    Wire1.write((uint8_t)(rmax >> 8));
    Wire1.write((uint8_t)(rstep & 0xff));
    Wire1.write((uint8_t)(rstep >> 8));
    Wire1.endTransmission();
}

// Set encoder wheel value
void encoder_setValue(uint8_t encoder_addr, int16_t rval)
{
    Wire1.beginTransmission(encoder_addr);
    Wire1.write((uint8_t)(rval & 0xff));
    Wire1.write((uint8_t)(rval >> 8));
    Wire1.endTransmission();
}

// Read encoder wheel value
int16_t encoder_getValue(int encoder_addr)
{
    Wire1.requestFrom(encoder_addr, 2);
    return ((uint16_t)Wire1.read() | ((uint16_t)Wire1.read() << 8));
}

void Encoders_Interrupt()
{
    enc_action = true;
}

// update Audio ---------------------------------------------------------
void updateAmpEnvSustain(int value)
{
    float decValue = LINEAR[value];
    ampEnv[0].sustain(decValue);
    ampEnv[1].sustain(decValue);
    ampEnv[2].sustain(decValue);
    ampEnv[3].sustain(decValue);
    ampEnv[4].sustain(decValue);
    ampEnv[5].sustain(decValue);
    ampEnv[6].sustain(decValue);
    ampEnv[7].sustain(decValue);
}

// Press virtuel key and play sample from psram -------------------------
void play_sample(int16_t note)
{
    note += 48; // sample note C4 440Hz
    Serial.print("virtual Note : ");
    Serial.println(note);
    float rate = ((float)pow(2, (note - 60) / 12.00));
    float rate2 = ((float)pow(2, (note - 60) / 12.00));
    sampleOsc[0].setPlaybackRate(rate);
    sampleOsc[0].playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
    sampleOsc[1].setPlaybackRate(rate2);
    sampleOsc[1].playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
}

// draw bargraph ------------------------------------------------
void draw_bargraph(uint16_t xpos, uint8_t ypos, uint16_t bar_length, uint8_t bar_hight, uint16_t bar_color)
{
    tft.fillRect(xpos, ypos, bar_length, bar_hight, ILI9341_BLACK);
    tft.drawRect(xpos, ypos, bar_length, bar_hight, bar_color);

    tft.fillRect(xpos + 53, ypos - 11, 30, 10, ILI9341_BLACK);
    tft.setCursor(xpos + 54, ypos - 11);
    tft.setTextSize(1);
    tft.setFont(DroidSans_10);
    tft.setTextColor(ILI9341_WHITE);
    tft.print(0);
    tft.print("%");
}

// draw fill_bargraph -------------------------------------------
void draw_fill_bargraph(uint16_t xpos, uint8_t ypos, uint16_t bar_length, uint8_t bar_hight, uint8_t percent, uint16_t bar_color)
{
    xpos++;
    ypos++;
    bar_length -= 1;
    bar_hight -= 2;
    for (size_t i = 0; i < bar_hight; i++)
    {
        tft.drawFastHLine(xpos, ypos + i, bar_length, bar_color);
    }

    tft.fillRect(xpos + 52, ypos - 12, 20, 8, ILI9341_BLACK);
    tft.setCursor(xpos + 52, ypos - 12);
    tft.setTextSize(1);
    tft.setTextColor(ILI9341_WHITE);
    tft.print(percent);
    tft.print("%");
}

// print file info ----------------------------------------------
void print_file_info(const char *str, uint16_t file_size)
{
    tft.fillRect(180, 40, 100, 60, ILI9341_BLACK);
    tft.setCursor(180, 40);
    tft.setTextSize(1);
    tft.setTextColor(ILI9341_WHITE);
    tft.print(str);
    tft.setCursor(180, 55);
    tft.print(file_size);
    tft.print(" KB");
}

// press patch list on page1 -----------------------------------
void press_patch_list_page1()
{
    uint8_t new_index = 0;
    static uint8_t old_index = 0;
    static uint8_t old_key_index = 1;

    new_index = touch_patch_list();
    if (new_index != old_index)
    {
        old_index = new_index;

        if (new_index >= 1 && new_index <= 6)
        {
            if (new_index != old_key_index)
            {
                draw_patch_list(new_index - 1, old_key_index - 1);
                old_key_index = new_index;
            }
        }
        else if (new_index == 0)
        {
            for (size_t i = 0; i < 6; i++)
            {
                TK_state_List_P1[i] = false; // clear touch state
            }
        }
    }

    if (new_index >= 1)
    {
        Reset_screensaver();
    }
}

// Touchscreen query -------------------------------------------
void readTouchscreen()
{
    if (touchReadTimer >= TouchRead_interval)
    {
        touchReadTimer = 0;
        read_touch_buttons();
    }
}

// Screensaver interval ----------------------------------------
void checkScreensaver()
{
    if (screensaverTimer >= Screensaver_interval)
    {
        screensaverTimer = 0;

        if (screensaver_Active == false)
        {
            if (screensaverResetTimer >= Screensaver_stay)
            {
                screensaverResetTimer = 0;
                screensaver_Active = true;
                tft.fillScreen(ILI9341_BLACK);
            }
        }
        else
        {
            screensaver();
        }
    }
}

// read Midi ---------------------------------------------------
void readMidi()
{
    MIDI.read(Midi_channel);
}

// get VoiceNo ------------------------------------------------
int getVoiceNo(int note)
{

    voiceToReturn = -1;      // Initialise
    earliestTime = millis(); // Initialise to now
    if (note == -1)
    {
        // NoteOn() - Get the oldest free voice (recent voices may be still on release stage)
        for (int i = 0; i < NO_OF_VOICES; i++)
        {
            if (voices[i].voiceOn == 0)
            {
                if (voices[i].timeOn < earliestTime)
                {
                    earliestTime = voices[i].timeOn;
                    voiceToReturn = i;
                }
            }
        }
        if (voiceToReturn == -1)
        {
            // No free voices, need to steal oldest sounding voice
            earliestTime = millis(); // Reinitialise
            for (int i = 0; i < NO_OF_VOICES; i++)
            {
                if (voices[i].timeOn < earliestTime)
                {
                    earliestTime = voices[i].timeOn;
                    voiceToReturn = i;
                }
            }
        }
        return voiceToReturn + 1;
    }
    else
    {
        // NoteOff() - Get voice number from note
        for (int i = 0; i < NO_OF_VOICES; i++)
        {
            if (voices[i].note == note && voices[i].voiceOn == 1)
            {
                return i + 1; // voice number
            }
        }
        // Unison - Note on without previous note off?
        return voiceToReturn;
    }
    // Shouldn't get here, return voice 1
    return 1;
}

// Press midi key and play sample from psram -------------------
void playSample(int Voice, uint8_t note)
{
    float rate = ((float)pow(2, (note - 72) / 12.00)); // sample note C4 440Hz
    int channels = 2;
    uint16_t envTime = ENVTIMES[ampEnvValue[0]];
    ampEnv[Voice].delay(envTime);
    envTime = ENVTIMES[ampEnvValue[1]];
    ampEnv[Voice].attack(envTime);
    ampEnv[Voice].hold(0);
    envTime = ENVTIMES[ampEnvValue[3]];
    ampEnv[Voice].decay(envTime);
    float decValue = LINEAR[ampEnvValue[4]];
    ampEnv[Voice].sustain(decValue);
    envTime = ENVTIMES[ampEnvValue[5]];
    ampEnv[Voice].release(envTime);
    ampEnv[Voice].noteOn();
    sampleOsc[Voice].setPlaybackRate(rate);
    sampleOsc[Voice].playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
}

// Press midi key and play sample from psram -------------------
void play_midi_sample(uint8_t note)
{
    /*
    // Drum[slot]->setPlaybackRate(  (float)pow (2, (inNumber - 72) / 12.00) * drum_config[activesample].p_offset   );
    // const uint8_t offset = (note > 209) ? 210 : 18;
    // note -= offset;
    float rate = ((float)pow(2, (note - 72) / 12.00)); // sample note C4 440Hz
    float rate2 = ((float)pow(2, (note - 67) / 12.00)); // sample note C4 440Hz
    //Serial.print("Midi Note : ");
    //Serial.println(note);
    playSample1.setPlaybackRate(rate);
    playSample2.setPlaybackRate(rate2);
    channels = 2;
    playSample1.playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
    playSample2.playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
    */
}

// NoteOn from serial Midi -------------------------------------
void myNoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
    Serial.print("note: ");
    Serial.println(note);

    int Voice = getVoiceNo(note);

    if (Voice == -1)
    {
        Voice = (getVoiceNo(-1))-1; // Voice-No: 0 - 7
        voices[Voice].note = note;
        voices[Voice].timeOn = millis();
        voices[Voice].voiceOn = 1;
    }

    playSample(Voice, note);

    // play_midi_sample(note);

    midiSymbol_status = 1;
    Reset_screensaver();
}

// NoteOff from serial Midi ------------------------------------
void myNoteOff(uint8_t channel, uint8_t note, uint8_t velocity)
{
    int Voice = getVoiceNo(note) - 1;

    if (Voice < 0)
    {
        return;
    }

    voices[Voice].voiceOn = 0;
    ampEnv[Voice].noteOff();
}

// check display symbols ---------------------------------------
void check_Symbols()
{
    if (pageNo != 0)
    {
        return;
    }

    if (midiSymbol_status == 1)
    {
        uint16_t x = 230;
        uint16_t y = 10;
        draw_Midi_Symbol(x, y, ILI9341_YELLOW);
        midiSymbol_status = 2;
        midiSymbolTimer = 0;
        // tft.waitUpdateAsyncComplete();
        //tft.updateScreenAsync(false);
        tft.updateScreen();
    }
    else if (midiSymbol_status == 2 && midiSymbolTimer >= 250)
    {
        uint16_t x = 230;
        uint16_t y = 10;
        draw_Midi_Symbol(x, y, ILI9341_DARKERGREY);
        midiSymbol_status = 2;
        midiSymbolTimer = 0;
        midiSymbol_status = 0;
        // tft.waitUpdateAsyncComplete();
        //tft.updateScreenAsync(false);
        tft.updateScreen();
    }
}

// Encoder speed -----------------------------------------------
void encoderSpeed(uint8_t enc_addr, int last_value, uint32_t elapsedtime)
{
    if (elapsedtime < 150)
    {
        encoder_set(enc_addr, 0, 127, 6, last_value, 0);
    }
    else if (elapsedtime >= 150 && elapsedtime < 200)
    {
        encoder_set(enc_addr, 0, 127, 4, last_value, 0);
    }
    else if (elapsedtime >= 200 && elapsedtime < 250)
    {
        encoder_set(enc_addr, 0, 127, 2, last_value, 0);
    }
    else if (elapsedtime >= 250)
    {
        encoder_set(enc_addr, 0, 127, 1, last_value, 0);
    }
}

// int encoder speed -------------------------------------------
void init_Encoder()
{
    // set encoder dynamic
    /*
    encoderSpeed(48, encoder_last_value[pageNo][0], 250);
    encoderSpeed(49, encoder_last_value[pageNo][1], 250);
    encoderSpeed(50, encoder_last_value[pageNo][2], 250);
    encoderSpeed(51, encoder_last_value[pageNo][3], 250);
    encoderSpeed(52, encoder_last_value[pageNo][4], 250);
    encoderSpeed(53, encoder_last_value[pageNo][5], 250);
    */
    encoderSpeed(48, ampEnvValue[0], 250);
    encoderSpeed(49, ampEnvValue[1], 250);
    encoderSpeed(50, ampEnvValue[3], 250);
    encoderSpeed(51, ampEnvValue[4], 250);
    encoderSpeed(52, ampEnvValue[5], 250);
    encoderSpeed(53, encoder_last_value[pageNo][5], 250);
    rotaryEncoder0_Timer = 250;
    rotaryEncoder1_Timer = 250;
    rotaryEncoder2_Timer = 250;
    rotaryEncoder3_Timer = 250;
    rotaryEncoder4_Timer = 250;
    rotaryEncoder5_Timer = 250;
}

// Read Rotary encoder -----------------------------------------
void readEncoder(void)
{
    if (enc_action == true) // change encoder value ?
    {
        enc_action = false;
        uint8_t count = 6; // numbers of encoders
        boolean break_flag = false;
        int oldEnvValue[6];
        oldEnvValue[0] = encoder_last_value[pageNo][0];
        oldEnvValue[1] = encoder_last_value[pageNo][1];
        oldEnvValue[2] = encoder_last_value[pageNo][2];
        oldEnvValue[3] = encoder_last_value[pageNo][3];
        oldEnvValue[4] = encoder_last_value[pageNo][4];
        oldEnvValue[5] = encoder_last_value[pageNo][5];

        for (uint8_t i = 0; i < count; i++)
        {
            value = encoder_getValue(encoder_addr + i);
            if (value != encoder_last_value[pageNo][i])
            {
                encoder_last_value[pageNo][i] = value;
                break_flag = true;
            }
            if (break_flag == true)
            {
                if (pageNo == Envelope_menu)
                {
                    tft.setFont(LiberationSans_10);
                    tft.setTextColor(ILI9341_BLACK);

                    if (encoder_addr + i == encoder1_addr)
                    {
                        tft.fillRoundRect(11, 176, 58, 17, 2, ILI9341_DARKERGREY);
                        tft.setCursor(13, 180);
                        tft.print("Del: ");
                        tft.setCursor(42, 180);
                        tft.print(encoder_last_value[pageNo][i]);
                        ampEnvValue[0] = encoder_last_value[pageNo][i];
                        // Encoder speed
                        encoderSpeed(encoder1_addr, encoder_last_value[pageNo][0], rotaryEncoder0_Timer);
                        rotaryEncoder0_Timer = 0;
                    }
                    else if (encoder_addr + i == encoder2_addr)
                    {
                        tft.fillRoundRect(71, 176, 58, 17, 2, ILI9341_DARKERGREY);
                        tft.setCursor(73, 180);
                        tft.print("Atk: ");
                        tft.setCursor(102, 180);
                        tft.print(encoder_last_value[pageNo][i]);
                        ampEnvValue[1] = encoder_last_value[pageNo][i];
                        // Encoder speed
                        encoderSpeed(encoder2_addr, encoder_last_value[pageNo][1], rotaryEncoder1_Timer);
                        rotaryEncoder1_Timer = 0;
                    }
                    else if (encoder_addr + i == encoder3_addr)
                    {
                        tft.fillRoundRect(131, 176, 58, 17, 2, ILI9341_DARKERGREY);
                        tft.setCursor(133, 180);
                        tft.print("Dec: ");
                        tft.setCursor(162, 180);
                        tft.print(encoder_last_value[pageNo][i]);
                        ampEnvValue[3] = encoder_last_value[pageNo][i];
                        // Encoder speed
                        encoderSpeed(encoder3_addr, encoder_last_value[pageNo][2], rotaryEncoder2_Timer);
                        rotaryEncoder2_Timer = 0;
                    }
                    else if (encoder_addr + i == encoder4_addr)
                    {
                        tft.fillRoundRect(191, 176, 58, 17, 2, ILI9341_DARKERGREY);
                        tft.setCursor(193, 180);
                        tft.print("Sus: ");
                        tft.setCursor(222, 180);
                        tft.print(encoder_last_value[pageNo][i]);
                        ampEnvValue[4] = encoder_last_value[pageNo][i];
                        updateAmpEnvSustain(ampEnvValue[4]);
                        // Encoder speed
                        encoderSpeed(encoder4_addr, encoder_last_value[pageNo][3], rotaryEncoder3_Timer);
                        rotaryEncoder3_Timer = 0;
                    }
                    else if (encoder_addr + i == encoder5_addr)
                    {
                        tft.fillRoundRect(251, 176, 58, 17, 2, ILI9341_DARKERGREY);
                        tft.setCursor(253, 180);
                        tft.print("Rel: ");
                        tft.setCursor(282, 180);
                        tft.print(encoder_last_value[pageNo][i]);
                        ampEnvValue[5] = encoder_last_value[pageNo][i];
                        // Encoder speed
                        encoderSpeed(encoder5_addr, encoder_last_value[pageNo][4], rotaryEncoder4_Timer);
                        rotaryEncoder4_Timer = 0;
                    }
                    else if (encoder_addr + i == encoder6_addr)
                    {
                        // Encoder speed
                        encoderSpeed(encoder6_addr, encoder_last_value[pageNo][5], rotaryEncoder5_Timer);
                        rotaryEncoder5_Timer = 0;
                    }
                    // clear old envelope line
                    draw_envelope(oldEnvValue[0], oldEnvValue[1], oldEnvValue[2], oldEnvValue[3],
                                  oldEnvValue[4], ILI9341_BLACK);
                    draw_env_grid();
                    // draw new envelope line
                    draw_envelope(encoder_last_value[pageNo][0], encoder_last_value[pageNo][1], encoder_last_value[pageNo][2],
                                  encoder_last_value[pageNo][3], encoder_last_value[pageNo][4], ILI9341_DARKGREEN);

                    //tft.updateScreenAsync(false);
                    tft.updateScreen();
                }
                break;
            }
        }
    }
}

// Display trade -----------------------------------------------
void DisplayThreade(void)
{
    /*
    if (Display_Timer >= 27)
    {
        Display_Timer = 0;
        // tft.waitUpdateAsyncComplete();
        // tft.updateScreenAsync(false);
        // tft.updateChangedAreasOnly(true);
        // tft.waitUpdateAsyncComplete();
        // tft.updateScreen();

        if (!tft.asyncUpdateActive())
        {
            // tft.updateScreenAsync();
            tft.updateScreen();
        }
    }
    */
}

// Setup -------------------------------------------------------
void setup()
{
    // init Serial for debug
    Serial.begin(9600);
    SPI.begin();
    // init Display
    tft.begin();
    tft.setFrameBuffer(screenBuffer); // Initialize Frame Buffer
    tft.useFrameBuffer(true);            // Use Frame Buffer
    tft.updateChangedAreasOnly(true);
    tft.invertDisplay(1);
    tft.setRotation(3);
    // init TouchScreen
    ts.begin(10);
    // init Midi
    MIDI.begin();
    MIDI.setHandleNoteOn(myNoteOn);
    MIDI.setHandleNoteOff(myNoteOff);
    // init Wire1 for Encoders
    Wire1.begin();
    Wire1.setClock(400000UL); // I2C speed 400KHz
    encoder_set(encoder_addr + 0, 0, 127, 1, 0, 0);
    encoder_set(encoder_addr + 1, 0, 127, 1, 0, 0);
    encoder_set(encoder_addr + 2, 0, 127, 1, 0, 0);
    encoder_set(encoder_addr + 3, 0, 127, 1, 0, 0);
    encoder_set(encoder_addr + 4, 0, 127, 1, 0, 0);
    encoder_set(encoder_addr + 5, 0, 127, 1, 0, 0);
    attachInterrupt(digitalPinToInterrupt(PIN_ENC_INT), Encoders_Interrupt, RISING);

    // init SDCARD
    Serial.print("Initializing SD card...");
    while (!SD.begin(BUILTIN_SDCARD))
    {
        Serial.println("initialization failed!");
        delay(1000);
    }
    Serial.println("SD card ok");

    // init Audio
    AudioMemory(128);
    // Audio Patching
    outMixer1.gain(0, 0.5);
    outMixer1.gain(1, 0.5);
    outMixer1.gain(2, 0.5);
    outMixer1.gain(3, 0.5);
    outMixer2.gain(0, 0.5);
    outMixer2.gain(1, 0.5);
    outMixer2.gain(2, 0.5);
    outMixer2.gain(3, 0.5);
    outMixer3.gain(0, 0.5);
    outMixer3.gain(1, 0.5);
    outMixer3.gain(2, 0.5);
    outMixer3.gain(3, 0.5);
    outMixer4.gain(0, 0.5);
    outMixer4.gain(1, 0.5);
    outMixer4.gain(2, 0.5);
    outMixer4.gain(3, 0.5);
    MainOutMixerL.gain(0, 0.5f);
    MainOutMixerL.gain(1, 0.5f);
    MainOutMixerR.gain(0, 0.5f);
    MainOutMixerR.gain(1, 0.5f);

    // init AmpEnvelope
    const int8_t envelopeType = -4; // 0 linear, -8 fast exponential, -8 slow exponential
    ampEnv[0].setEnvType(envelopeType);
    ampEnv[1].setEnvType(envelopeType);
    ampEnv[2].setEnvType(envelopeType);
    ampEnv[3].setEnvType(envelopeType);
    ampEnv[4].setEnvType(envelopeType);
    ampEnv[5].setEnvType(envelopeType);
    ampEnv[6].setEnvType(envelopeType);
    ampEnv[7].setEnvType(envelopeType);
    ampEnv[0].delay(ampEnvValue[0]);
    ampEnv[1].delay(ampEnvValue[0]);
    ampEnv[2].delay(ampEnvValue[0]);
    ampEnv[3].delay(ampEnvValue[0]);
    ampEnv[4].delay(ampEnvValue[0]);
    ampEnv[5].delay(ampEnvValue[0]);
    ampEnv[6].delay(ampEnvValue[0]);
    ampEnv[7].delay(ampEnvValue[0]);
    ampEnv[0].attack(ampEnvValue[1]);
    ampEnv[1].attack(ampEnvValue[1]);
    ampEnv[2].attack(ampEnvValue[1]);
    ampEnv[3].attack(ampEnvValue[1]);
    ampEnv[4].attack(ampEnvValue[1]);
    ampEnv[5].attack(ampEnvValue[1]);
    ampEnv[6].attack(ampEnvValue[1]);
    ampEnv[7].attack(ampEnvValue[1]);
    ampEnv[0].hold(ampEnvValue[2]);
    ampEnv[1].hold(ampEnvValue[2]);
    ampEnv[2].hold(ampEnvValue[2]);
    ampEnv[3].hold(ampEnvValue[2]);
    ampEnv[4].hold(ampEnvValue[2]);
    ampEnv[5].hold(ampEnvValue[2]);
    ampEnv[6].hold(ampEnvValue[2]);
    ampEnv[7].hold(ampEnvValue[2]);
    ampEnv[0].decay(ampEnvValue[3]);
    ampEnv[1].decay(ampEnvValue[3]);
    ampEnv[2].decay(ampEnvValue[3]);
    ampEnv[3].decay(ampEnvValue[3]);
    ampEnv[4].decay(ampEnvValue[3]);
    ampEnv[5].decay(ampEnvValue[3]);
    ampEnv[6].decay(ampEnvValue[3]);
    ampEnv[7].decay(ampEnvValue[3]);
    ampEnv[0].sustain(ampEnvValue[4]);
    ampEnv[1].sustain(ampEnvValue[4]);
    ampEnv[2].sustain(ampEnvValue[4]);
    ampEnv[3].sustain(ampEnvValue[4]);
    ampEnv[4].sustain(ampEnvValue[4]);
    ampEnv[5].sustain(ampEnvValue[4]);
    ampEnv[6].sustain(ampEnvValue[4]);
    ampEnv[7].sustain(ampEnvValue[4]);
    ampEnv[0].release(ampEnvValue[5]);
    ampEnv[1].release(ampEnvValue[5]);
    ampEnv[2].release(ampEnvValue[5]);
    ampEnv[3].release(ampEnvValue[5]);
    ampEnv[4].release(ampEnvValue[5]);
    ampEnv[5].release(ampEnvValue[5]);
    ampEnv[6].release(ampEnvValue[5]);
    ampEnv[7].release(ampEnvValue[5]);
    sampleOsc[0].enableInterpolation(true);
    sampleOsc[1].enableInterpolation(true);
    sampleOsc[2].enableInterpolation(true);
    sampleOsc[3].enableInterpolation(true);
    sampleOsc[4].enableInterpolation(true);
    sampleOsc[5].enableInterpolation(true);
    sampleOsc[6].enableInterpolation(true);
    sampleOsc[7].enableInterpolation(true);
    // Load Sample
    newdigate::flashloader loader;
    File root;
    root = SD.open("/Samples");
    const char *_filename = "/Samples/SAMPLE12.WAV"; // Sine 440Hz
    Sample = loader.sampleOsc(_filename);
    sample_busy_flag = true;
    // draw Main page
    pageNo = 0;
    draw_menu_page(pageNo);
    init_Encoder();
}


// Loop ---------------------------------------------------
void loop()
{
    readMidi();
    draw_Peak();

    if (Task_Timer >= 15)
    {
        readEncoder();
        readTouchscreen();  // call with interval timer
        checkScreensaver(); // call with interval timer
        check_Symbols();
        //draw_real_envelope();
        Task_Timer = 0;
    }
  
}
 
Back
Top