I'm dumbfounded. It's a software bug thats outsmarting me!

I'm working on a project using a MEGA 2560. This isn't my first and it shouldn't be very difficult, but this one got me. In short, I'm trying to write to an LCD. It's a 40x4 and it is writing ok everywhere as I ran several tests filling the screen with characters. The software's start up screen does that now, including a test of all 8 custom characters loaded into the LCD. The LCD is 40X4 and it appears as two LCD controllers, one for the top 2 lines and a second for the bottom 2 lines.

Let me add that I've done this all before so I am not a noob. I've nearly filled the MEGA with complex code and this is not that - I've just started on this one. I've checked the power supply, I'm giving the board about 9 volts on Vin and the whole project draws about 1/2 amp, 80% of that is the LCD backlight. The bench supply can handle 3 amps. So I'm confident the power is ok, I've seen it clean on a scope. I am not using any interrupts so that isn't the issue either. I am not messing with a watchdog timer or hardware either.

Details: I'm writing 4 variable values to the bottom line. Writing multiple values to the first three lines is working solidly. The fourth line causes the MEGA to reset itself and I get a new startup screen. Looking to narrow down the problem further, I broke the code that writes the 4th line into four sections, one for each variable to be written. I call them A,B,C,D (very imaginative I know). By itself, A works fine. B works fine. C works fine. D works fine. However any combination of two or more than two of those write routines and it restarts the code.

The A routine writes at cursor position 0, B writes at 10, C at 21, and D at 31. None of those writes overlap and they all print 9 characters each. I tried every (all 16) combination of code chunks A, B, C, D and interestingly, when A, B, or C combine with D it doesn't restart immediately, but only after a button press is done. Any other group of two or more cause an immediate crash.

I looked for an array being used out of bounds, but there are none. I use an array elsewhere, but that's for LEDs and not altered in the LCD write routines. The array is way oversized anyways, using only the first 23 elements of a size [40] array. Since any of those four (A,B,C,D) code sections work fine and show the variables I want by themselves, I don't think there is an obvious problem with the logic - they all compile with no errors or warnings.

Memory? I'm only using 3% of the code space according to the compiler/loader. I am not addressing a huge amount of variables either. These particular variables are defined bytes and a few integers holding small values. In fact, and there is only about 38 of them in total. My print commands to the LCD appear as these:
lcdbot.print(" ON ");
lcdbot.print(SysUnitID);
either a small integer value or quoted characters. Like I said there are no interrupts I added to muck things up, I don't find any syntax or logic problems. It's all straightforward "if xxxx then print yyy" stuff, with some of them being in a switch/case statement. Either way each individual code section that writes to the LCD compiles and runs, but not together.

Also, I looked carefully and appear not to be trying to write beyond the end of the LCD's character memory, but if I did could that crash the Arduino? I would think the LCD controllers would simply ignore it.

As for the buttons and lights in my system, they are "virtual" in that all buttons are received as a serial message on Serial2. All LEDs are controlled by sending a command to Serial2. (That is a PIC processor I use to simplify projects such as these and I've used that on many projects for years bug-free.) The LCD and three pots are the only other hardware being used.

So like my title says I am stumped. I'm not really a noob as I have done many bigger MEGA projects before, and I studied everything I could think of and searched these forums. Still, I can't seem to come up with any reasonable answer as to what could be causing the restart. Am I missing something obvious? Any ideas why code A and code B work fine independently but when put together I get a reset? And what could be unique about code section D that only restarts after a button push message is received? (Most likely it's because that button causes a re-draw of the screen, but so do A, B, and C!)

Help with suggestions if you could please, I am out of ideas. Befuddled & dumbfounded.

Post the code, using code tags.

400mA seems like an awful lot to drive the backlight…?

So many words, so little code...
Is it confidential?

1 Like

Put your scope on the reset line and see if it pulled low. Make it trigger, and make it one shot so you get to see it. Also put another probe on the power supply pin. I don't see how lcd writes and cause the processor to reset. What is the current draw for the back light, that should be published 400 ma is a lot and doesnt seem right. That's why we love microcontrolller design because when it works its all worth it. : )

If... it's drawing 400mA, then the 5volt regulator would have to dissipate (9-5)*0.4= 1.6watt.
That will periodically cycle the 5volt supply (restart the Mega), because the 5volt regulator would be overheating (try to put your finger on it).
A 5volt cellphone charger, connected to the USB socket, would be more sensible.
Leo..

1 Like

Really, really need to see the actual code, but with problems like this where the problematic parts of the code do not have any apparent problems, I would be looking at the remainder of the code for errors such as writing outside the bounds of an array, passing an invalid pointer (which causes a subsequent write to an invalid location), functions that return pointers to local variables, etc.

Hi,
A circuit diagram would be helpful.
What is the application.
What hardware do you have using the 5V pin of the Mega.

As has been mentioned in earlier posts on this thread, just because your 9V supply can output the current, it does not mean the on board 5V regulator on the Mega can.
You would be better to supply 5V to the 5V pin and leave the regulator alone.

Have you done some calculations and worked out how much power is dissipated as heat in the Mega 5V regulator.
So before getting into software, you need to check your hardware supply sysrem.

Thanks.. Tom... :grinning: :+1: :coffee: :australia:
PS. Your web site http://www.angeliselectronics.com/ is not responding!

Yes it may seem that way, but electronics doesn't function on peoples hunches, it's entirely based upon reality. That is the spec and it is a BIG display. Since that 400mA is not related to the problem, I really don't care about that number.

Why look at a power supply that I already verified was working fine? Where's the gain? Again, the backlight and it's current draw matches the spec and is fine. I really don't care about the backlight, and the power is going to the backlight. When I disconnect it, the power drops dramatically.

Again the power is fine. Yes it is drawing about 400mA and that is the spec. Let's forget about the @#$% backlight. The Arduino isn't drawing 400mA, and it isn't supplying 5 volts at 400mA. The 12 volt power source is going into a power converter designed specifically to power Arduino projects. It produces a 5V output and a 8.5 volt output. The 5 volt supply goes to whatever you need to be powered with 5 volts, and the 8.5 volts goes into Vin for the Arduino regulator. That uses only around 100mA and that's with the not-warm-at-all regulator on the MEGA dissipating some of that power.

To all:
Please, please, please, let's ignore the power supply because that is not a problem. It won't be a problem. The problem is that there is something in the checked-and-compiled Arduino code resetting the MEGA and it's not an array out of bounds, or interrupts, or all the things I mentioned.

I'm sure it is something but I am only asking for some ideas on what I may not have looked at. I mention these things to assure you those possible causes are for the most part eliminated.

I am not using any pointers (except for the ones built-in of course). As for the arrays, I am not using them for any function related to the LCD writes. That was the first thing I went to look for, and as I explained there is nothing there. I remove any reference to the arrays and the problem is still there.

Nothing connected to the 5V pin on the MEGA beyond a 10K pot for an analog input. The power supplied to this is perfectly fine. 1mA is not going to overheat and shut down the regulator at the exact, repeatable point in the software, and certainly not at an asynchronous time based upon when I press a button.

The code that, after 13 posts, you STILL have not provided?? How in the world do you expect anyone to help??

1 Like

Maybe spend a little time creating a minimal, complete and verifiable example (mcve)
How to create a Minimal, Reproducible Example - Help Center - Stack Overflow

1 Like

it's not an array out of bounds, or interrupts, or all the things I mentioned.

No one will believe you until the code has been posted and verified. You have already admitted you have been outsmarted.

1 Like

attempt 3 at getting formatted, color-coded code:

[code]
/*
MIDI Programmer early version of software from R004-->TEST
 by rich deangelis 2021 
 */
#include <LiquidCrystal.h>

// pins, top row     RS  R/W ENt d0  d1  d2  d3  d4  d5  d6  d7
LiquidCrystal lcdtop(49, 46, 47, 44, 45, 42, 43, 40, 41, 38, 39);

// pins, botm row    RS  R/W ENt d0  d1  d2  d3  d4  d5  d6  d7
LiquidCrystal lcdbot(49, 46, 51, 44, 45, 42, 43, 40, 41, 38, 39);

// ************************************************************* Define custom characters
//character 0
byte Separator[8] = {
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
};
//character 1
byte ArrowUp[8] = {
  B00100,
  B01110,
  B01110,
  B11111,
  B00100,
  B00100,
  B00100,
  B00100,
};
//character 2
byte ArrowDown[8] = {
  B00100,
  B00100,
  B00100,
  B00100,
  B11111,
  B01110,
  B01110,
  B00100,
};
//character 3
byte BigDown[8] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B01110,
  B01110,
  B00100,
  B00100,
};
//character 4
byte Note[8] = {
  B00010,
  B00010,
  B00010,
  B00010,
  B01110,
  B11110,
  B01100,
  B00000,
};
//character 5
byte Anti1[8] = {
  B11111,
  B11011,
  B10011,
  B11011,
  B11011,
  B11011,
  B10001,
  B11111,
};
//character 6
byte Anti2[8] = {
  B11111,
  B10001,
  B01110,
  B11101,
  B11011,
  B10111,
  B00000,
  B11111,
};
//character 7
byte Hbar[8] = {
  B01010,
  B10101,
  B01010,
  B00100,
  B00100,
  B01010,
  B10101,
  B01010,
};

// ************************************************************* System Variables
int x = 0;  //for whatev.
boolean Redraw = true;  //when true, an LED redraw is done at the start of loop. Initial run will draw it.
boolean Shift = false;  //set true when shift button (#0)is held down
boolean EncLeft = false;  //For LEFT Encoder: set true to enable 2nd parameter, default 0 is 1st parameter 
boolean EncRight = false;  //For RIGHT Encoder: set true to enable 4th parameter, default 0 is 3rd parameter 
byte byteRead = 0; //something to put in characters read from serial inputs
byte byteAgentFirst = 0;  //holds 1st byte from an agent transmission
byte byteAgentSecond = 0;  //holds 2nd byte from an agent transmission
int NewUserInput = 0;     //bit flags for Agent Reception, bit 0 set when 1st byte received, bit 1 set when 2nd byte received
byte LEDS[40];  //holds the image of all LEDs on the various panels. 0=off, 1=on 3=slow flash, 5=fast flash
byte Ones = '0';
byte Tens = '0';
int Page = 0;   //Page numbers 0...n determine the LCD screen shown and the parameters it shows
                //Page 0 SYSTEM, has synth select, unit select, channel select (for any synth)
                //for DW 6000:
                //Page 1 OSC screen 1 has octave1,2, waveform1,2
                //Page 2 OSC screen 2 has level1,2, interval, and detune
                //Page 3 VCF screen 1 has cutoff, VCF env.int., resonance, tracking
                //Page 4 VCF screen 2 has attack, decay, slope, release
                //Page 5 VCF screen 3 has breakpoint, sustain, VCF env.polarity
                //Page 6 AMP screen 1 has attack, decay, slope, release
                //Page 7 AMP screen 2 has breakpoint, sustain
                //Page 8 MOD screen 1 has MG frequency, MG delay, MG to OSC, MG to VCF
                //Page 9 MOD screen 2 has bend to pitch, bend to filter
                //Page 10 EFX screen 1 has noise, Chorus, portamento
                //for DW 8000:
                //Page 11 OSC screen 1 has octave1,2, waveform1,2
                //Page 12 OSC screen 2 has level1,2, interval, and detune
                //Page 13 OSC screen 3 has autobend intensity, OSC1/2 select, time, direction(mode)
                //Page 14 VCF screen 1 has cutoff, VCF env.int., resonance, tracking
                //Page 15 VCF screen 2 has attack, decay, slope, release
                //Page 16 VCF screen 3 has breakpoint, sustain, VCF env.polarity, velocity sensitivity
                //Page 17 AMP screen 1 has attack, decay, slope, release
                //Page 18 AMP screen 2 has breakpoint, sustain, velocity sensitivity
                //Page 19 MOD screen 1 has LFO frequency, LFO delay, LFO to OSC, LFO to VCF
                //Page 20 MOD screen 2 has LFO waveform, touch to pitch, touch to filter, touch to VCA
                //Page 21 EFX screen 1 has delay time, delay fine, feedback, FX level
                //Page 22 EFX screen 2 has fx mod frequency, fx mod intensity
                //Page 23 EFX screen 3 has bend to OSC, Bend to VCF, portamento time, noise level
                //Page 24 GLO screen 1 has nothing (yet)
//int MaxPage = 24; //this should match that up there ^

//  ************************************************************ System Parameters to be saved in NV memory
int SysUnitID = 0;       //default Synth Unit #
int SysSynthName = 1;   //Identifies the synth, 1 = "Korg DW-6000"
                        //                      2 = "Korg DW-8000"
                        //                      3 = "Korg Poly800"
int SysMIDIChannel = 0;  //default MIDI channel for TX and RX. User sees 1-16 but it's 0-15.

// ************************************************************* Synth Parameters to be Tx/Rx for Korg DW6000
byte PDW6_Assign = 0;  //Assign Mode [0-2] bits 5-4 of param 0
byte PDW6_BendOsc = 2;  //Bend Osc [0-12] bits 3-0 of param 0
byte PDW6_PortTime = 15;  //Portamento Time [0-31] param 1
byte PDW6_Osc1Level = 21;  //Osc 1 Level [0-31] param 2
byte PDW6_Osc2Level = 22;  //Osc 2 Level [0-31] param 3
byte PDW6_NoiseLevel = 1;  //Noise Level [0-31] param 4
byte PDW6_Cutoff = 33;  //Cutoff [0-63] param 5
byte PDW6_Resonance = 6;  //Resonance [0-31] param 6
byte PDW6_VCFEGIntensity = 16;  //VCF EG Intensity [0-31] param 7
byte PDW6_FAttack = 0;  //VCF EG Attack [0-31] param 8
byte PDW6_FDecay = 10;  //VCF EG Decay [0-31] param 9
byte PDW6_FBreakpoint = 15;  //VCF EG Breakpoint [0-31] param 10
byte PDW6_FSlope = 10;  //VCF EG Slope [0-31] param 11
byte PDW6_FSustain = 29;  //VCF EG Sustain [0-31] param 12
byte PDW6_FRelease = 9;  //VCF EG Release [0-31] param 13
byte PDW6_AAtack = 0;  //VCA EG Attack [0-31] param 14
byte PDW6_ADecay = 3;  //VCA EG Decay [0-31] param 15
byte PDW6_ABreakpoint = 25;  //VCA EG Breakpoint [0-31] param 16
byte PDW6_ASlope = 17;  //VCA EG Slope [0-31] param 17
byte PDW6_BendVCF = 0;  //Bend VCF [0,1] bit 5 of param 18
byte PDW6_ASustain = 28;  //VCA EG Sustain [0-31] bits 4-0 of param 18
byte PDW6_Osc1Octave = 0;  //Osc 1 Octave [0-2] bits 6-5 of param 19
byte PDW6_ARelease = 5;  //VCA EG Release [0-31] bits 4-0 of param 19
byte PDW6_Osc2Octave = 1;  //Osc 2 Octave [0-2] bits 6-5 of param 20
byte PDW6_MGFrequency = 12;  //MG Frequency [0-31] bits 4-0 of param 20
byte PDW6_KeyTracking = 1;  //Keyboard Tracking [0-2] bits 6-5 of param 21
byte PDW6_MGDelay = 11;  //MG Delay [0-31] bits 4-0 of param 21
byte PDW6_Polarity = 0;  //Polarity [0,1] bit 5 of param 22
byte PDW6_MG2Osc = 3;  //MG to Osc [0-31] bits 4-0 of param 22
byte PDW6_Chorus = 1;  //Chorus [0,1] bit 5 of param 23
byte PDW6_MG2VCF = 0;  //MG to VCF [0-31] bits 4-0 of param 24
byte PDW6_Osc1Waveform = 2;  //Osc 1 Waveform [0-7] 5-3 of param 24
byte PDW6_Osc2Waveform = 1;  //Osc 2 Waveform [0-7] 2-0 of param 24
byte PDW6_Interval = 0;  //Osc 2 Interval [0-4] bits 5-3 of param 25
byte PDW6_Detune = 2;  //Osc 2 Detune [0-6] bits 2-0 of param 25


//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
//                                      SETUP FUNCTIONS
//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
void setup() {
  //Serial0: not used
  //Serial1: The Primary MIDI In/Out
  Serial1.begin(31250);  //MIDI rate
  //Serial2: Agent Button/LED processor
  Serial2.begin(38400);  //agent set rate
  //Serial3: Secondary MIDI In/Out
  Serial3.begin(31250);  //MIDI rate
  
  // Initialize Agent processors
  Serial2.write(0xFE);  //reset Agents
  delay(500);  //was 3000 with only 4 processors, works with 7000 and 16 agents.
  Serial2.write(0xAE);  //enumerate Agents
  Serial2.write(0xAF);
  //read and toss out agent responses  
  while (Serial2.available()) {
    byteRead = Serial2.read();
    delay(10);
  }

  //************************************************************** Initial LCD Screen
  // set up the number two LCD controllers
  lcdtop.begin(40, 2);
  lcdtop.clear();
  lcdtop.noCursor();
  lcdtop.noBlink();
  lcdtop.noAutoscroll();
  lcdtop.leftToRight();

  lcdbot.begin(40, 2);
  lcdbot.clear();
  lcdbot.noCursor();
  lcdbot.noBlink();
  lcdbot.noAutoscroll();
  lcdbot.leftToRight();
  
  // Print a message to the LCD first row.
  lcdtop.print("Angelis Electronics Presents            ");
  // Print a message to the LCD 2nd row.
  lcdtop.setCursor(0, 1);
  lcdtop.print("  A New Technology in                   ");

  // Print a message to the LCD 3rd row.
  lcdbot.print("    Vintage Synth Programming           ");
  // Print a message to the LCD 4th row.
  lcdbot.setCursor(0, 1);
  lcdbot.print("        <applause and cheers>   ");
  lcdbot.write(byte(0));    //custom character 0
  lcdbot.write(byte(1));    //custom character 1
  lcdbot.write(byte(2));    //custom character 2
  lcdbot.write(byte(3));    //custom character 3
  lcdbot.write(byte(4));    //custom character 4
  lcdbot.write(byte(5));    //custom character 5
  lcdbot.write(byte(6));    //custom character 6
  lcdbot.write(byte(7));    //custom character 7

  //load up custom characters
  lcdtop.createChar(0,Separator);
  lcdbot.createChar(0,Separator);
  lcdtop.createChar(1,ArrowUp);
  lcdbot.createChar(1,ArrowUp);
  lcdtop.createChar(2,ArrowDown);
  lcdbot.createChar(2,ArrowDown);
  lcdtop.createChar(3,BigDown);
  lcdbot.createChar(3,BigDown);
  lcdtop.createChar(4,Note);
  lcdbot.createChar(4,Note);
  lcdtop.createChar(5,Anti1);
  lcdbot.createChar(5,Anti1);
  lcdtop.createChar(6,Anti2);
  lcdbot.createChar(6,Anti2);
  lcdtop.createChar(7,Hbar);
  lcdbot.createChar(7,Hbar);

  delay(1000);  //give human beings time to see this intro screen

  // **************************************************************** Initialize our LED array
  for (x = 0 ; x < 40 ; x++ ) {
    LEDS[x] = 0;  //assign all leds as off in our array
  }
  //LED cycle test
  for ( x = 0 ; x < 24 ; x++ ) {
    SetLED(x+40);   //turn on an LED
    delay(32);     //hold LED state for 1/32 second
    SetLED(x);      //turn it off again
  }
  } //end of setup chunk



// LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
//                                       MAIN LOOP
// LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
void loop() {
  // ********************************************************************************************** Print the LCD
  if (Redraw) {
    RedrawScreen(); //clear and redraw all basic characters, variable fields are filled with _
    FillLCDRow1();  //fills in variable data for top row with current values
    FillLCDRow2();  //fills in variable data for second row with current values
    FillLCDRow3();  //fills in variable data for third row with current values

//got it upt to screen 5 and 1/2 of 6 without blowing up, try ? ...
    FillLCDRow4a();  //fills in variable data for bottom row with what's current values
    FillLCDRow4b();  //fills in variable data for bottom row with what's current values
    FillLCDRow4c();  //fills in variable data for bottom row with what's current values
    FillLCDRow4d();  //fills in variable data for bottom row with what's current values
    
    UpdateAllLEDS();  //send complete LED array to Agent
    Redraw = false;   //done,so don't do it until necessary.
  }

  // *********************************************************************************************** READ AGENT, RESPOND TO BUTTONS
  //read serial data from Agent processor, store into AgentByteFirst & AgentByteSecond and set flags.
  if (Serial2.available()) {
    // read the most recent byte from Agent
    byteRead = Serial2.read();
      if (byteRead == 0xE0) {  // first message byte is always E0 from board #0
      byteAgentFirst = byteRead;
      NewUserInput = 0b01;  //set 1st bit to flag byte 1 arrived but not 2nd.
      //after first byte, do nothing until 2nd byte arrives.
    }
    if (byteRead <= 0x5F) {// second message byte is switch or encoder event
      byteAgentSecond = byteRead;
      NewUserInput = (0b10 | NewUserInput);  //sets 2nd bit to flag 2nd byte arrived.
    }
  }
  if (NewUserInput == 0b11) {
    //we have a button event!
    //ClickAgents();
    DoButtonPress(byteAgentSecond);   //call to handle button & encoder events
    NewUserInput = 0;               //clears flags to indicate no button events
    Redraw = true;                  //possible changes requires a screen update
  }

  delay(25);  //just 1/40 second delay
} //end of loop chunk



// SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
//                                                           subroutines!
// SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

//convert input to Ones and Tens for LCD *************************************************************** ConvertToChars()
// this is to see if the problem is displaying an int value directly to the LCD
void ConvertToChars(int input) {
  int little = 0;
  int big = 0;

  little = input;
  if (little > 9) {
      little = little - 10;
      big = big + 1;
  }
  if (little > 9) {
      little = little - 10;
      big = big + 1;
  }
  if (little > 9) {
      little = little - 10;
      big = big + 1;
  }
  if (little > 9) {
      little = little - 10;
      big = big + 1;
  }
  if (little > 9) {
      little = little - 10;
      big = big + 1;
  }
  if (little > 9) {
      little = little - 10;
      big = big + 1;
  }
        switch (big) {
        case 0:
            Tens = ' ';
        break;
        case 1:
            Tens = '1';
        break;
        case 2:
            Tens = '2';
        break;
        case 3:
            Tens = '3';
        break;
        case 4:
            Tens = '4';
        break;
        case 5:
            Tens = '5';
        break;
        case 6:
            Tens = '6';
        break;
        }
        switch (little) {
        case 0:
            Ones = ' ';
        break;
        case 1:
            Ones = '1';
        break;
        case 2:
            Ones = '2';
        break;
        case 3:
            Ones = '3';
        break;
        case 4:
            Ones = '4';
        break;
        case 5:
            Ones = '5';
        break;
        case 6:
            Ones = '6';
        break;
        case 7:
            Ones = '7';
        break;
        case 8:
            Ones = '8';
        break;
        case 9:
            Ones = '9';
        break;
        }
}

// ************************************************************************************************************* ButtonPress()
void DoButtonPress(byte RxByte) {
  // ******************************************************************************* Encoder routines
  if (RxByte == 64) {                 //encoder 1 left turn event
      x=0;
  }
  if (RxByte == 65) {                 //encoder 2 left turn event
      x=0;
  }
  if (RxByte == 80) {                 //encoder 1 right turn event
      x=0;
  }
  if (RxByte == 81) {                 //encoder 2 right turn event
      x=0;
  }
  // ******************************************************************************* Pilot Button routines
  if (RxByte == 0) {                  //button 0 press  SHIFT BUTTON
      Shift = true;
      LEDS[0] = 1;  //turn on red led
  }
  if (RxByte == 1) {                  //button 1 press  SYS BUTTON
      if (Shift==false) {
          Page = 0;
          PageLEDSDark();
          LEDS[1] = 1;  //turn on red led
      }
  }
  if (RxByte == 2) {                  //button 2 press  OSC BUTTON
      if (Shift==false) {
            if (Page == 1) {
                Page = 2;
                PageLEDSDark();
                LEDS[10] = 1;  //turn on green led
            }
            else {
                Page = 1;
                PageLEDSDark();
                LEDS[2] = 1;  //turn on red led
            }
      }
  }
  if (RxByte == 3) {                  //button 3 press  FIL BUTTON
      if (Shift==false) {
          switch (Page) {
              case 3:
                  Page = 4;
                  PageLEDSDark();
                  LEDS[11] = 1;  //turn on green led
              break;
              case 4:
                  Page = 5;
                  PageLEDSDark();
                  LEDS[3] = 1;  //turn on red led
                  LEDS[11] = 1; //turn on green led
              break;
              default:
                  Page = 3;
                  PageLEDSDark();
                  LEDS[3] = 1;  //turn on red led
          }
      }
  }
  if (RxByte == 4) {                  //button 4 press  AMP BUTTON
      if (Shift==false) {
          if (Page == 6) {
              Page = 7;
              PageLEDSDark();
              LEDS[12] = 1;  //turn on green led
          }
          else {
              Page = 6;
              PageLEDSDark();
              LEDS[4] = 1;  //turn on red led
          }
      }
  }
  if (RxByte == 5) {                  //button 5 press  MOD BUTTON
      if (Shift==false) {
          if (Page == 8) {
              Page = 9;
              PageLEDSDark();
              LEDS[13] = 1;  //turn on green led
          }
          else {
              Page = 8;
              PageLEDSDark();
              LEDS[5] = 1;  //turn on red led
          }
      }
  }
  if (RxByte == 6) {                  //button 6 press  BUS+FX BUTTON
      if (Shift==false) {
            Page = 10;
            PageLEDSDark();
            LEDS[6] = 1;  //turn on red led
      }
  }
  if (RxByte == 7) {                  //button 7 press  GLOBAL BUTTON
      if (Shift==false) {
            Page =24;
            PageLEDSDark();
            LEDS[7] = 1;  //turn on red led
      }
  }
  // ******************************************************************************* Enigma Button routines
  if (RxByte == 8) {                  //button 8 (left encoder) press
      if (EncLeft) {              //toggle state of left encoder cursor
          EncLeft=false;
          LEDS[17] = 0;  //turn off green led
          LEDS[16] = 1;  //turn on green led
      }
      else {
          EncLeft=true;
          LEDS[16] = 0;  //turn off green led
          LEDS[17] = 1;  //turn on green led
      }
  }
  if (RxByte == 9) {                  //button 9 (right encoder) press
      if (EncRight) {             //toggle state of right encoder cursor
          EncRight=false;
          LEDS[22] = 0;  //turn off green led
          LEDS[21] = 1;  //turn on green led
      }
      else {
          EncRight=true;
          LEDS[21] = 0;  //turn off green led
          LEDS[22] = 1;  //turn on green led
      }
  }
  if (RxByte == 10) {                  //button 10 press  ENC LEFT MINIMIZE
      x=0;
  }
  if (RxByte == 11) {                  //button 11 press  ENC LEFT MAXIMIZE
      x=0;
  }
  if (RxByte == 12) {                  //button 12 press      <<unused>>
      x=0;
  }
  if (RxByte == 13) {                  //button 13 press      <<unused>>
      x=0;
  }
  if (RxByte == 14) {                  //button 14 press  ENC RIGHT MINIMIZE
      x=0;
  }
  if (RxByte == 15) {                  //button 15 press  ENC RIGHT MAXIMIZE
      x=0;
  }
  // ************************************************************************ Pilot release buttons
  if (RxByte == 32) {                  //RELEASE SHIFT (button 0)
      Shift = false;
      LEDS[0] = 0;  //turn off red led
   }
  if (RxByte == 33) {                  //RELEASE 1
  }
  if (RxByte == 34) {                  //RELEASE 2
  }
  if (RxByte == 35) {                  //RELEASE 3
  }
  if (RxByte == 36) {                  //RELEASE 4
  }
  if (RxByte == 37) {                  //RELEASE 5
  }
  if (RxByte == 38) {                  //RELEASE 6
  }
  if (RxByte == 39) {                  //RELEASE 7
  }
  // ************************************************************************ Enigma release buttons
  if (RxByte == 40) {                  //RELEASE 8 (encoder left)
  }
  if (RxByte == 41) {                  //RELEASE 9 (encoder right)
  }
  if (RxByte == 42) {                  //RELEASE 10
  }
  if (RxByte == 43) {                  //RELEASE 11
  }
  if (RxByte == 44) {                  //RELEASE 12
  }
  if (RxByte == 45) {                  //RELEASE 13
  }
  if (RxByte == 46) {                  //RELEASE 14
  }
  if (RxByte == 47) {                  //RELEASE 15
  }
}


// **************************************************************************************************************** UpdateAllLEDS()
//This writes our array to the Agent
void UpdateAllLEDS() {
    int y = 0;
    y = (LEDS[0]&1) + ((LEDS[1]&1)*2) + ((LEDS[2]&1)*4) + ((LEDS[3]&1)*8) + ((LEDS[4]&1)*16) + ((LEDS[5]&1)*32) + ((LEDS[6]&1)*64) + ((LEDS[7]&1)*128);
    Serial2.write(176);   //command for board #0
    Serial2.write(208+0); //LED group 0 command
    Serial2.write(byte(y));     //assembled bits for Red LEDs on Pilot board

    y = (LEDS[8]&1) + ((LEDS[9]&1)*2) + ((LEDS[10]&1)*4) + ((LEDS[11]&1)*8) + ((LEDS[12]&1)*16) + ((LEDS[13]&1)*32) + ((LEDS[14]&1)*64) + ((LEDS[15]&1)*128);
    Serial2.write(176);   //command for board #0
    Serial2.write(208+1); //LED group 1 command
    Serial2.write(byte(y));     //assembled bits for Green LEDs on Pilot board

    y = (LEDS[16]&1) + ((LEDS[17]&1)*2) + ((LEDS[18]&1)*4) + ((LEDS[20]&1)*16) + ((LEDS[21]&1)*32) + ((LEDS[22]&1)*64);
    Serial2.write(176);   //command for board #0
    Serial2.write(208+2); //LED group 2 command
    Serial2.write(byte(y));     //assembled bits for Green LEDs on Enigma board
}

//  ********************************************************************************************************************* PageLEDSDark()
// the pilot page LEDs are all red & green LEDs except for #0,8 over the shift button which are not used.
// This turns them off in our LED array.
void PageLEDSDark() {       // turn off all the pilot page LEDs
    //notice led 0 is left out
    LEDS[1] = 0;   //red...
    LEDS[2] = 0;
    LEDS[3] = 0;
    LEDS[4] = 0;
    LEDS[5] = 0;
    LEDS[6] = 0;
    LEDS[7] = 0;
    //notice led 8 is left out
    LEDS[9] = 0;    //green ...
    LEDS[10] = 0;
    LEDS[11] = 0;
    LEDS[12] = 0;
    LEDS[13] = 0;
    LEDS[14] = 0;
    LEDS[15] = 0;
 }
 
// ******************************************************************************************************************* SetLED()
//This directly controls the Agent, does not alter our LED array.
void SetLED(int number) {
    Serial2.write(176);     //command for one LED on board #0
    Serial2.write(number);  //command to address the particular LED by number
}

// ******************************************************************************************************************** LEDSDark()
//This directly controls the Agent, does not alter our LED array.
void LEDSDark() {
    Serial2.write(176);   //command for board #0
    Serial2.write(192);   //command to turn off every LED
}

// ************************************************************************************************************* ClickAgents()
void ClickAgents() {
    Serial2.write(0xCC);
}
// ************************************************************************************************************ RedrawScreen()
void RedrawScreen() {
  //makes the basic user screen with empty fields to be written in.
  // Print a message to the LCD first row.
  lcdtop.clear();
  lcdtop.print("Unit__ ");   //has variable fields a2,b12,c2 for unit#,synth name,channel
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(4));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.print(" ____________ ");
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(4));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.write(byte(7));    //custom horiz-bar character
  lcdtop.print(" Chan__");
  // Print a message to the LCD 2nd row.
  lcdtop.setCursor(0, 1);
  lcdtop.print("_________"); //has variable fields d9,e9,f9,g9 for parameter labels (4 of them)
  lcdtop.write(byte(0));    //custom separator character
  lcdtop.print("_________");
  lcdtop.write(byte(0));    //custom separator character
  lcdtop.write(byte(0));    //custom separator character
  lcdtop.print("_________");
  lcdtop.write(byte(0));    //custom separator character
  lcdtop.print("_________");
  // Print a message to the LCD 3rd row.
  lcdbot.clear();
  lcdbot.print("    _    "); //has variable fields h1,i1.j1,k1 for cursor characters (on or off)
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.print("    _    ");
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.print("    _    ");
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.print("    _    ");
  // Print a message to the LCD 4th row.
  lcdbot.setCursor(0, 1);
  lcdbot.print("_________"); //has variable fields L9,m9,n9,o9 for parameter values (4 of them)
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.print("_________");
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.print("_________");
  lcdbot.write(byte(0));    //custom separator character
  lcdbot.print("_________");
}

// *************************************************************************************************************** FillLCDRow1()
void FillLCDRow1() {
  lcdtop.setCursor(4,0);  //position for field a2,   a 2 digit unit number 00-99
  if (SysUnitID<10) {
    lcdtop.print(" ");
  }
  lcdtop.print(SysUnitID);
  lcdtop.setCursor(14,0);  //position for field b12, a 12 character name of the synth being programmed
  switch (SysSynthName) {
    case 1:
      lcdtop.print("Korg DW-6000");
      break;
    case 2:
      lcdtop.print("Korg DW-8000");
      break;
    case 3:
      lcdtop.print("Korg Poly800");
      break;
    default:
      lcdtop.print("????????????");
  }
  lcdtop.setCursor(38,0);  //position for field c2,  a 2 digit midi channel number, with no leading zero, shifted from [0-15] to [1-16]
  if (SysMIDIChannel<9) {
    lcdtop.print(" ");
  }
  lcdtop.print(SysMIDIChannel+1);   //we display 0-15  as 1-16
}

// ******************************************************************************************************************* FillLCDRow2()
void FillLCDRow2() {
  lcdtop.setCursor(0,1);  //position for field d9,   a 9 character parameter label (left encoder position 1)
  switch (Page) {
    case 0:
      lcdtop.print(" Unit #  ");    //for system page 0
      break;
    case 1:
      lcdtop.print("Octave-1 ");    //for DW6000
      break;
    case 2:
      lcdtop.print(" Level-1 ");
      break;
    case 3:
      lcdtop.print(" Cutoff  ");
      break;
    case 4:
      lcdtop.print("F-Attack ");
      break;
    case 5:
      lcdtop.print("F-Breakpt");
      break;
    case 6:
      lcdtop.print("A-Attack ");
      break;
    case 7:
      lcdtop.print("A-Breakpt");
      break;
    case 8:
      lcdtop.print("LFO-Freq ");
      break;
    case 9:
      lcdtop.print("Bend->Osc");
      break;
    case 10:
      lcdtop.print("Noise-Lev");
      break;
    case 11:
      lcdtop.print("Octave-1 ");    //for DW8000
      break;
    case 12:
      lcdtop.print(" Level-1 ");
      break;
    case 13:
      lcdtop.print("ABend-Int");
      break;
    case 14:
      lcdtop.print(" Cutoff  ");
      break;
    case 15:
      lcdtop.print("F-Attack ");
      break;
    case 16:
      lcdtop.print("F-Breakpt");
      break;
    case 17:
      lcdtop.print("A-Attack ");
      break;
    case 18:
      lcdtop.print("A-Breakpt");
      break;
    case 19:
      lcdtop.print("LFO-Freq ");
      break;
    case 20:
      lcdtop.print("LFO-Wavfm");
      break;
    case 21:
      lcdtop.print("Dly-Range");
      break;
    case 22:
      lcdtop.print("FXMod-Frq");
      break;
    case 23:
      lcdtop.print("Bend->Osc");
      break;
    default:
      lcdtop.print("_________");
  }
  lcdtop.setCursor(10,1);  //position for field e9,  a 9 character parameter label (left encoder position 2)
  switch (Page) {
    case 0:
      lcdtop.print("SynthType");    //for system page 0
      break;
    case 1:
      lcdtop.print("Waveform1");    //for DW6000
      break;
    case 2:
      lcdtop.print("Interval ");
      break;
    case 3:
      lcdtop.print("Resonance");
      break;
    case 4:
      lcdtop.print(" F-Decay ");
      break;
    case 5:
      lcdtop.print("         ");
      break;
    case 6:
      lcdtop.print(" A-Decay ");
      break;
    case 7:
      lcdtop.print("         ");
      break;
    case 8:
      lcdtop.print("LFO-->OSC");
      break;
    case 9:
      lcdtop.print("         ");
      break;
    case 10:
      lcdtop.print("PortaTime");
      break;
    case 11:
      lcdtop.print("Waveform1");    //for DW8000
      break;
    case 12:
      lcdtop.print("Interval ");
      break;
    case 13:
      lcdtop.print("ABend-1&2");
      break;
    case 14:
      lcdtop.print("Resonance");
      break;
    case 15:
      lcdtop.print(" F-Decay ");
      break;
    case 16:
      lcdtop.print("F-VelSens");
      break;
    case 17:
      lcdtop.print(" A-Decay ");
      break;
    case 18:
      lcdtop.print("A-VelSens");
      break;
    case 19:
      lcdtop.print("LFO-->Osc");
      break;
    case 20:
      lcdtop.print("Pres->VCF");
      break;
    case 21:
      lcdtop.print("Dly-FineT");
      break;
    case 22:
      lcdtop.print("         ");
      break;
    case 23:
      lcdtop.print("Portamnto");
      break;
    default:
      lcdtop.print("_________");
  }
  lcdtop.setCursor(21,1);  //position for field f9,  a 9 character parameter label (right encoder position 1)
  switch (Page) {
    case 0:
      lcdtop.print("MIDI-Chan");    //for system page 0
      break;
    case 1:
      lcdtop.print("Octave-2 ");    //for DW6000
      break;
    case 2:
      lcdtop.print(" Level-2 ");
      break;
    case 3:
      lcdtop.print("Env-->VCF");
      break;
    case 4:
      lcdtop.print(" F-Slope ");
      break;
    case 5:
      lcdtop.print("F-Sustain");
      break;
    case 6:
      lcdtop.print(" A-Slope ");
      break;
    case 7:
      lcdtop.print("A-Sustain");
      break;
    case 8:
      lcdtop.print("LFO-Delay");
      break;
    case 9:
      lcdtop.print("Bend->VCF");
      break;
    case 10:
      lcdtop.print(" Chorus  ");
      break;
    case 11:
      lcdtop.print(" Octave-2");    //for DW8000
      break;
    case 12:
      lcdtop.print(" Level-2 ");
      break;
    case 13:
      lcdtop.print("ABendTime");
      break;
    case 14:
      lcdtop.print("Env-->VCF");
      break;
    case 15:
      lcdtop.print(" F-Slope ");
      break;
    case 16:
      lcdtop.print("F-Sustain");
      break;
    case 17:
      lcdtop.print(" A-Slope ");
      break;
    case 18:
      lcdtop.print("A-Sustain");
      break;
    case 19:
      lcdtop.print("LFO-Delay");
      break;
    case 20:
      lcdtop.print("Pres->Osc");
      break;
    case 21:
      lcdtop.print("Dly-Level");
      break;
    case 22:
      lcdtop.print("Mod-->Dly");
      break;
    case 23:
      lcdtop.print("Bend->VCF");
      break;
    default:
      lcdtop.print("_________");
  }
  lcdtop.setCursor(31,1);  //position for field g9,  a 9 character parameter label (right encoder position 2)
  switch (Page) {
    case 0:
      lcdtop.print("         ");    //for system page 0
      break;
    case 1:
      lcdtop.print("Waveform2");    //for DW6000
      break;
    case 2:
      lcdtop.print(" Detune  ");
      break;
    case 3:
      lcdtop.print("Key-Track");
      break;
    case 4:
      lcdtop.print("F-Release");
      break;
    case 5:
      lcdtop.print("F-Polarty");
      break;
    case 6:
      lcdtop.print("A-Release");
      break;
    case 7:
      lcdtop.print("         ");
      break;
    case 8:
      lcdtop.print("LFO-->VCF");
      break;
    case 9:
      lcdtop.print("         ");
      break;
    case 10:
      lcdtop.print("AsignMode");
      break;
    case 11:
      lcdtop.print("Waveform2");    //for DW8000
      break;
    case 12:
      lcdtop.print(" Detune  ");
      break;
    case 13:
      lcdtop.print("ABend-Dir");
      break;
    case 14:
      lcdtop.print("Key Track");
      break;
    case 15:
      lcdtop.print("F-Release");
      break;
    case 16:
      lcdtop.print("Polarity ");
      break;
    case 17:
      lcdtop.print("A-Release");
      break;
    case 18:
      lcdtop.print("         ");
      break;
    case 19:
      lcdtop.print("LFO-->VCF");
      break;
    case 20:
      lcdtop.print("Pres->VCA");
      break;
    case 21:
      lcdtop.print("DlyFeedbk");
      break;
    case 22:
      lcdtop.print("         ");
      break;
    case 23:
      lcdtop.print("Noise Lvl");
      break;
    default:
      lcdtop.print("_________");
  }
}

// ********************************************************************************************************************* FillLCDRow3()
void FillLCDRow3() {
  lcdbot.setCursor(4,0);  //position for field h1,   a single character blank or big down arrow
  if (EncLeft) {
      lcdbot.write(byte(32));  //That's an empty space
  }
  else {
      lcdbot.write(byte(3));    //That's the custom BigDown Arrow
  }
  lcdbot.setCursor(14,0);  //position for field i1,  a single character blank or big down arrow
  if (EncLeft) {
      lcdbot.write(byte(3));    //That's the custom BigDown Arrow
  }
  else {
      lcdbot.write(byte(32));  //That's an empty space
  }
  lcdbot.setCursor(25,0);  //position for field j1,  a single character blank or big down arrow
  if (EncRight) {
      lcdbot.write(byte(32));  //That's an empty space
  }
  else {
      lcdbot.write(byte(3));    //That's the custom BigDown Arrow
  }
  lcdbot.setCursor(35,0);  //position for field k1,  a single character blank or big down arrow
  if (EncRight) {
      lcdbot.write(byte(3));    //That's the custom BigDown Arrow
  }
  else {
      lcdbot.write(byte(32));  //That's an empty space
  }
}


// ******************************************************************************************************************* FillLCDRow4()a
void FillLCDRow4a() {
  lcdbot.setCursor(0,1);  //position for field L9,   a 9 character value specific for each synth parameter
    if (SysSynthName==1) {    //for the DW-6000
       switch (Page) {
          case 0:
              if (SysUnitID<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(SysUnitID);    //SysUnitID
              lcdbot.print("    ");
          break;
          case 1:
              if (PDW6_Osc1Octave==0) {
                lcdbot.print("   16'   ");
              }
              if (PDW6_Osc1Octave==1) {
                lcdbot.print("   8'    ");
              }
              if (PDW6_Osc1Octave==2) {
                lcdbot.print("   4'    ");
              }
          break;
          case 2:
              if (PDW6_Osc1Level<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_Osc1Level);    //PDW6_Osc1Level
              lcdbot.print("    ");
          break;
          case 3:
              if (PDW6_Cutoff<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_Cutoff);    //PDW6_Cutoff
              lcdbot.print("    ");
          break;
          case 4:
              if (PDW6_FAttack<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_FAttack);    //PDW6_FAttack
              lcdbot.print("    ");
          break;
          case 5:
              if (PDW6_FBreakpoint<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_FBreakpoint);    //PDW6_FBreakpoint
              lcdbot.print("    ");
          break;
          case 6:
              if (PDW6_AAtack<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_AAtack);    //PDW6_AAtack
              lcdbot.print("    ");
          break;
/*
          case 7:
              if (PDW6_ABreakpoint<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_ABreakpoint);    //PDW6_ABreakpoint
              lcdbot.print("    ");
          break;
          case 8:
              if (PDW6_MGFrequency<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_MGFrequency);    //PDW6_MGFrequency
              lcdbot.print("    ");
          break;
          case 9:
              if (PDW6_BendOsc<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_BendOsc);    //PDW6_BendOsc
              lcdbot.print("    ");
          break;
          case 10:
              if (PDW6_NoiseLevel<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_NoiseLevel);   //PDW6_NoiseLevel
              lcdbot.print("    ");
          break;
*/
          default:
              lcdbot.print("         ");
       }
    }
    if (SysSynthName==2) {    //for the DW-8000
    }
    if (SysSynthName==3) {    //for the EX-800
    }
}


// ******************************************************************************************************************* FillLCDRow4()b
void FillLCDRow4b() {
  lcdbot.setCursor(10,1);  //position for field m9,  a 9 character value specific for each synth parameter
    if (SysSynthName==1) {    //for the DW-6000
         switch (Page) {
          case 0:
            if (SysSynthName==1) {
                lcdbot.print(" DW-6000 ");
            }
            if (SysSynthName==2) {
                lcdbot.print(" DW-8000 ");
            }
            if (SysSynthName==3) {
                lcdbot.print(" EX-800  ");
            }
          break;
          case 1:
              if (PDW6_Osc1Waveform==0) {
                lcdbot.print("Bras&Strg");
              }
              if (PDW6_Osc1Waveform==1) {
                lcdbot.print(" Violin  ");
              }
              if (PDW6_Osc1Waveform==2) {
                lcdbot.print("Aco.Piano");
              }
              if (PDW6_Osc1Waveform==3) {
                lcdbot.print(" E.Piano ");
              }
              if (PDW6_Osc1Waveform==4) {
                lcdbot.print("Syn-Bass ");
              }
              if (PDW6_Osc1Waveform==5) {
                lcdbot.print("Saxophone");
              }
              if (PDW6_Osc1Waveform==6) {
                lcdbot.print("  Clavi  ");
              }
              if (PDW6_Osc1Waveform==7) {
                lcdbot.print("  Bell   ");
              }
          break;
          case 2:
              if (PDW6_Interval==0) {
                  lcdbot.print(" Unison  ");
              }
              if (PDW6_Interval==1) {
                  lcdbot.print("Minor 3rd");
              }
              if (PDW6_Interval==2) {
                  lcdbot.print("Major 3rd");
              }
              if (PDW6_Interval==3) {
                  lcdbot.print("   4th   ");
              }
              if (PDW6_Interval==4) {
                  lcdbot.print("   5th   ");
              }
          break;
          case 3:
              if (PDW6_Resonance<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_Resonance);    //PDW6_Resonance
              lcdbot.print("    ");
          break;
          case 4:
              if (PDW6_FDecay<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_FDecay);    //PDW6_FDecay
              lcdbot.print("    ");
          break;
          case 5:
              lcdbot.print("         ");
          break;
          case 6:
              if (PDW6_ADecay<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_ADecay);    //PDW6_ADecay
              lcdbot.print("    ");
          break;
/*
          case 7:
              lcdbot.print("         ");
          break;
          case 8:
              if (PDW6_MG2Osc<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print(PDW6_MG2Osc);    //PDW6_MG2Osc
              lcdbot.print("    ");
          break;
          case 9:
              lcdbot.print("         ");
          break;
          case 10:
              if (PDW6_PortTime<10) {
                  lcdbot.print(" ");
              }
              lcdbot.print("   ");
              lcdbot.print("10");   //PDW6_PortTime
              lcdbot.print("    ");
          break;
*/
          default:
              lcdbot.print("         ");
         }
    }
    if (SysSynthName==2) {    //for the DW-8000
    }
    if (SysSynthName==3) {    //for the EX-800
    }
}


// ********************************************************************************************************************** FillLCDRow4()c
void FillLCDRow4c() {
  lcdbot.setCursor(21,1);  //position for field n9,  a 9 character value specific for each synth parameter
    if (SysSynthName==1) {    //for the DW-6000
       switch (Page) {
        case 0:
            if (SysMIDIChannel<9) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
                lcdbot.print(SysMIDIChannel+1);
            lcdbot.print("    ");
        break;
        case 1:
            if (PDW6_Osc2Octave==0) {
              lcdbot.print("   16'   ");
            }
            if (PDW6_Osc2Octave==1) {
              lcdbot.print("    8'   ");
            }
            if (PDW6_Osc2Octave==2) {
              lcdbot.print("    4'   ");
            }
        break;
        case 2:
            if (PDW6_Osc2Level<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_Osc2Level);
            lcdbot.print("    ");
        break;
        case 3:
            if (PDW6_VCFEGIntensity<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_VCFEGIntensity);
            lcdbot.print("    ");
        break;
        case 4:
            if (PDW6_FSlope<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_FSlope);
            lcdbot.print("    ");
        break;
        case 5:
            if (PDW6_FSustain<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_FSustain);
            lcdbot.print("    ");
        break;
/*
        case 6:
            if (PDW6_ASlope<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_ASlope);
            lcdbot.print("    ");
        break;
        case 7:
            if (PDW6_ASustain<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_ASustain);
            lcdbot.print("    ");
        break;
        case 8:
            if (PDW6_MGDelay<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print(PDW6_MGDelay);
            lcdbot.print("    ");
        break;
        case 9:
            if (PDW6_BendVCF==0) {
                lcdbot.print("   Off   ");
            }
            if (PDW6_BendVCF==1) {
                lcdbot.print("   On    ");
            }
        break;
        case 10:
            if (PDW6_Chorus==0) {
                lcdbot.print("   Off   ");
            }
            if (PDW6_Chorus==1) {
                lcdbot.print("   On    ");
            }
        break;
*/
        default:
            lcdbot.print("         ");
       }
    }
    if (SysSynthName==2) {    //for the DW-8000
    }
    if (SysSynthName==3) {    //for the EX-800
    }
}


// ******************************************************************************************************************* FillLCDRow4()d
void FillLCDRow4d() {
  lcdbot.setCursor(31,1);  //position for field o9,  a 9 character value specific for each synth parameter
    if (SysSynthName==1) {    //for the DW-6000
       switch (Page) {
        case 0:
              lcdbot.print("         ");
        break;
        case 1:
            if (PDW6_Osc2Waveform==0) {
              lcdbot.print("Bras&Strg");
            }
            if (PDW6_Osc2Waveform==1) {
              lcdbot.print(" Violin  ");
            }
            if (PDW6_Osc2Waveform==2) {
              lcdbot.print("Aco.Piano");
            }
            if (PDW6_Osc2Waveform==3) {
              lcdbot.print("Elc.Piano");
            }
            if (PDW6_Osc2Waveform==4) {
              lcdbot.print("Syn-Bass ");
            }
            if (PDW6_Osc2Waveform==5) {
              lcdbot.print("Saxophone");
            }
            if (PDW6_Osc2Waveform==6) {
              lcdbot.print("  Clavi  ");
            }
            if (PDW6_Osc2Waveform==7) {
              lcdbot.print("  Bell   ");
            }
        break;
        case 2:
            lcdbot.print("    ");
            lcdbot.print("2");    //PDW6_Detune
            lcdbot.print("    ");
        break;
        case 3:
          if (PDW6_KeyTracking==0) {
              lcdbot.print("   Off   ");
          }
          if (PDW6_KeyTracking==1) {
              lcdbot.print("  Half   ");
          }
          if (PDW6_KeyTracking==2) {
              lcdbot.print("  Full   ");
          }
        break;
        case 4:
            if (PDW6_FRelease<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print("4");    //PDW6_FRelease
            lcdbot.print("    ");
        break;
        case 5:
          if (PDW6_Polarity==0) {
              lcdbot.print("normal UP");
          }
          if (PDW6_Polarity==1) {
              lcdbot.print("invt DOWN");
          }
        break;
/*
        case 6:
            ConvertToChars(PDW6_ARelease);
            lcdbot.print("   ");
            lcdbot.print(Tens);    //PDW6_ARelease
            lcdbot.print(Ones);    //PDW6_ARelease
            lcdbot.print("    ");
        break;
        case 7:
            lcdbot.print("         ");
        break;
        case 8:
            if (PDW6_MG2VCF<10) {
                lcdbot.print(" ");
            }
            lcdbot.print("   ");
            lcdbot.print("8");    //PDW6_MG2VCF
            lcdbot.print("    ");
        break;
        case 9:
            lcdbot.print("         ");
        break;
        case 10:
          if (PDW6_Assign==0) {
            lcdbot.print("P1-Seqnce");
          }
          if (PDW6_Assign==1) {
            lcdbot.print("P2-Fixed ");
          }
          if (PDW6_Assign==3) {
            lcdbot.print(" Unison  ");
          }
        break;
*/
        default:
            lcdbot.print("         ");
       }
    }
    if (SysSynthName==2) {    //for the DW-8000
    }
    if (SysSynthName==3) {    //for the EX-800
    }
}


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//                              MIDI Subroutines
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
/*
void MIDITx(int Note, int vel) {
    //transmit a midi note on then a note off
    Serial1.write(0x90+(MIDIChannel));  //note on
    Serial1.write(Note);  //note #
    Serial1.write(vel);  //velocity
 //   delay(1);
    Serial1.write(0x80+(MIDIChannel));  //note off
    Serial1.write(Note);  //note #
    Serial1.write(0x00);  //velocity of 0
}
*/

//this is the end my friend. the end.
[/code]

Are getting paid by the LOC?

I'd say you need to use the F() macro a lot more.

Yes, all those character string constants go in RAM, so you may be running out of RAM.

Consider using standard functions like itoa() to convert binary to ASCII characters.

The code is using 1576 bytes out of the 8K on a Mega, and no use of String, so I don't think ram is the problem.