Yet another millis() (and interrupt) question !

First of all I'm a relative newbie who dabbles with Arduino, so be gentle.
Two issues interrupts and millis().
interrupts -
I'm reading serial data from a scale and doing something else in the meantime. I was thinking of trying to interrupt on having a byte ready to read and then run processIncomingByte(). I couldn't find a way to do that and I didn't want to do polling. Seems like using if(Serial1.available() is polling. I ended up using Timer3 and producing an interrupt every 885us which executed the ISR (processIncomingByte()). I keep reading about keeping the ISR short and was wondering if it was too long (maybe affecting millis()). So, I tried just setting a flag in the ISR and testing for that to run what used to be in the ISR. Not sure which way is the best.

millis() -
I'm trying to capture the time to do an operation but the numbers are all wrong. I use millis elsewhere and it seems to work OK but the numbers that come from the variable Time are messed up. Not even close to being right. It was very inconsistent but I was getting 20 or 30 seconds more than what it should have been. Sometimes more, sometimes less.

There is a whole bunch of other code that has absolutely nothing to do with this so I didn't want to clog this up with it.

Anybody have any suggestions?


void PIB_Flag(){
  Flag = 1;
}

/**********
*  setup  *
**********/
void setup() {
   
  Serial.begin(9600);       // when communicating with serial monitor

  Scale = EEPROM.read(ep_start_P + 48);
  if(Scale == 3){
  Serial1.begin(9600, SERIAL_7O1);      // debug for TP153 scale
  //MAX_INPUT = 12;
  }
  else
  {
  Serial1.begin(9600);      // for scale
  //MAX_INPUT = 10;
  }
  mode = EEPROM.read(ep_start_P + 46);
  //Scale = EEPROM.read(ep_start_P + 48);
 
  CurWeight = -1;
  myGLCD.InitLCD(0);    // Portrait
  myGLCD.clrScr();
  stCurrent1[0]="";
  stCurrent1[1]="";
  stCurrent1[2]="";
  myGLCD.setFont(arial_bold);
  myGLCD.print("Target", 25, 5);
  myGLCD.print("______", 25, 37);
  myGLCD.print("Weight", 25, 30);
  myGLCD.print(" gr", 120, 70);
  pinMode(11, OUTPUT);    // Brake control
  pinMode(12, OUTPUT);    // Trickler
  pinMode(13, OUTPUT);    // onboard LED
  Timer3.initialize(885);
//  Timer3.attachInterrupt(processIncomingByte);
  Timer3.attachInterrupt(PIB_Flag);

  TCCR1A = _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);      // phase and frequency correct
  TCCR1B = _BV(WGM13) | _BV(CS12);     //prescaler div 256
  OCR1A = 31250/Freq;     // Frequency
  OCR1B = 0;              // 0% duty cycle

// flushEEPROM();       //Only used for debug
  myTouch.InitTouch(TOUCH_ORIENTATION);
  myTouch.setPrecision(PREC_MEDIUM);
  T_rng = strtod(stCurrent2, &ptr);

 STOP();
}       // end setup

/****************
*   RUN (PWM)   *      PWM mode, STOP displayed
****************/
void RUN_P()    
{  
  if (activ_Pdr < 1 || activ_Pdr > 4){        // If Settings_PWM() has not been run, activ_Pdr might be outside 1-4
    myGLCD.setFont(arial_bold);               // if so, the asterisk '*' will blink until pressed then
    while (true)                              // proceed to Settings_PWM.
    {
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("*", 198, 78);
    delay(500);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("*", 198, 78);
    delay(500);
    myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      if ((x >= 175 && x <= 235) && (y >= 70 && y <= 110)){     // hot box for * (Settings_PWM)
        myGLCD.setColor(255, 255, 255);
        myGLCD.print("*", 198, 78);
        myGLCD.setFont(Arial_round_16x24);
        return(0);
      }
    }
  }
    ss_status = 1;
    myGLCD.setColor(255, 0, 0);
    myGLCD.fillRoundRect (155, 5, 235, 55);
    myGLCD.setColor(255, 224, 0);           // dark yellow
    myGLCD.drawRoundRect (155, 5, 235, 55);
    myGLCD.setBackColor(255, 0, 0);
    myGLCD.setFont(arial_bold);
    myGLCD.print("STOP", 164, 24);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print(" ", 198, 78);     // remove the *
    myGLCD.fillRect(5, 118, 235, 315);
    myGLCD.setColor(255, 255, 0);             
    myGLCD.print("              ", 10, 94);   
    Target = strtod(stCurrent,NULL);
    Diff = (Target - CurWeight);
    oldSpeed = 6;
    RemPan = 0;
    success = 0;
    Start_Time = 0;
    TCCR1A = _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);      // phase and frequency correct
    
//  Load variables from EEPROM for use here
  
    activ_Pdr = EEPROM.read(ep_start_P + 45);
    ea = activ_Pdr * 9 + ep_start_P;
    Freq = EEPROM.read(ea);
    OCR1A = 31250/Freq;
    F_Duty = EEPROM.read(ea+1);
    F_Delta = EEPROM.read(ea+2);
    F_Delta = F_Delta/10;
    M_Duty = EEPROM.read(ea+3);
    M_Delta = EEPROM.read(ea+4);
    M_Delta = M_Delta/10;
    S_Duty = EEPROM.read(ea+5);
    S_Delta = EEPROM.read(ea+6);
    S_Delta = S_Delta/100.0;      // debug
    VS_Duty = EEPROM.read(ea+7);
    VS_Delta = EEPROM.read(ea+8);
    VS_Delta = VS_Delta/100.0;    // debug
    digitalWrite(11, LOW);     // disable brake
    OldWeight = CurWeight;
    i = 0;
//
//  Stay in this code until the STOP button is pushed
//  
    period = EEPROM.read(ep_start_P + 47) * 1000;      // delay time (ms)

    if(Target - T_rng < 0){    //debug
      T_rng = 1;              //debug
      stCurrent2[0] = '1';
    }
    while (true)
    {
      if (Flag == 1)
        processIncomingByte();

      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if (((y>=5) && (y<=55)) && ((x>=155) && (x<=235)))   // RUN / STOP button
      {
 //        STOP Button pushed?
          return(0);
      }
      
        if ((CurWeight >= 0) && (RemPan == 1)) {    // pan has been lifted and replaced
          success = 0;
          RemPan = 0;
          Start_Time = millis();
        }
        Cur_Time = millis();
        if (Cur_Time - Start_Time >= period) {    //pan replace pause  

        if (Trick_start == 0){    // start trickle timing     debug
        Trick_start = 1;
        T_start = millis();
        }

          Diff = (Target - CurWeight);
      
          if((((T_rng == 0) && (CurWeight > -.02) && (CurWeight < Target)) || 
            ((T_rng >= 1 && T_rng <= 9) && (CurWeight >= (Target - T_rng)) &&   // weight in trickle range,
            (CurWeight < Target))) && (RemPan == 0) && (success == 0))          // pan not removed and target not reached
        {                                                               
        if((CurWeight - OldWeight) > -.5)    // pan not removed, current weight must have dropped more than .5 from previous
          {
            if (Diff < VS_Delta){
              temp = (OCR1A * (VS_Duty/100));
              OCR1B = int (temp);
              speed = 5;            // VSlo
          //    digitalWrite(11, HIGH);     // enable brake
              }
          
            if ((Diff >= VS_Delta) && (Diff < S_Delta)){
              temp = (OCR1A * (S_Duty/100));
              OCR1B = int (temp);
              speed = 4;           // Slo
          //    digitalWrite(11, HIGH);     // enable brake
              }
          
            if ((Diff >= S_Delta) && (Diff < M_Delta)){   
              temp = (OCR1A * (M_Duty/100));
              OCR1B = int (temp);
              speed = 3;          // Med
          //    digitalWrite(11, LOW);     // disable brake
              }
          
            if ((Diff >= M_Delta) && (Diff < F_Delta)){
              temp = (OCR1A * (F_Duty/100));
              OCR1B = int (temp);
              speed = 2;          // Fast
          //    digitalWrite(11, LOW);     // disable brake
              }

            if (Diff >= F_Delta){
              OCR1B = OCR1A;
              speed = 1;
          //    digitalWrite(11, LOW);     // disable brake
              }    // full on 100% duty cycle
          }
          else     // current weight < last weight by more than .5 gr  assume pan is being removed
          {
            OCR1B = 0;
            RemPan = 1;
            speed = 0;
          }
        }   // end of weight in trickle range
        else
        speed = 0;
        if(Diff < .01){
          OCR1B = 0;
          success = 1;
          speed = 0;
          Trick_start = 0;    // debug
          T_end = millis();   // debug
        }
        if(CurWeight < 0){
          RemPan = 1;
          OCR1B = 0;
          speed = 0;
        }
        
        if(oldSpeed - speed != 0){
          if(speed == 0)
          {
            myGLCD.print("    ", CENTER, 125);
            myGLCD.printNumI(T_start, CENTER, 150);   // debug
            myGLCD.printNumI(T_end, CENTER, 175);      // debug
            Time = (T_end - T_start)/1000.0;          // debug
            myGLCD.print("       ", CENTER, 200);     // debug
            myGLCD.printNumF(Time, 2, CENTER, 200, '.', 3);   // debug
          }
          if(speed == 1)
            myGLCD.print("FULL", CENTER, 125);
          if(speed == 2)
            myGLCD.print("FAST", CENTER, 125);
          if(speed == 3)
            myGLCD.print("MED ", CENTER, 125);
          if(speed == 4)
            myGLCD.print("SLO ", CENTER, 125);
          if(speed == 5)
            myGLCD.print("VSlo", CENTER, 125);
          if((speed < 0) || (speed > 5))
            myGLCD.print("DFLT", CENTER, 125);

        oldSpeed = speed;
        }
        OldWeight = CurWeight;      // used to determine if pan is being lifted
    }     // end of pan replaced pause time
    }   // end while
 }      // end RUN_P


/************************
 *  processIncomingByte  * 
 *************************/
 void processIncomingByte () {

  byte inByte;
  static unsigned int input_pos = 0;

  if(Serial1.available () > 0){
    inByte = Serial1.read();
  
  switch (inByte)
  {
    case '+':
      strStart = 1;
      input_pos = 0;
      input_line[input_pos++] = inByte;
      break;

    case '-':
      strStart = 1;
      input_pos = 0;
      input_line[input_pos++] = inByte;
      break;
    
    default:         // keep adding if not full ... allow for terminating null byte
      if ((input_pos <= MAX_INPUT) && (strStart == 1) && (inByte >= 43) && (inByte <= 57) || (inByte == 32)){
        if (inByte == 32)     // debug TP153
          inByte = '0';       // debug TP153
      
        input_line[input_pos++] = inByte;
      if(input_pos > MAX_INPUT)
        input_pos = MAX_INPUT;
      }
      else
      {
      input_line[input_pos] = NULL;
      if(strStart == 1){
        CurWeight = strtod(input_line, &X);
      }
      strStart = 0;
      input_pos = 0;      // reset buffer for next time
      }
      break;
  }   // end of switch
  
  OldWeight = CurWeight;
  Flag = 0;
 }
 }    // end of processIncomingByte

i guess the answer depends on what the other "whole bunch" of code is doing and why simply using Serial.availeble() is inadequate and why you think an interrupt is needed.

bear in mind, up to 64 bytes of serial data gets queued in a buffer to be read when time is available.

Receiving from a hardware uart invokes interrupts itself.
This means whatever else your code is doing outside of interrupts
will be interrupted by the serial received data to make sure that all bits are received.

As long as you are executing code in another interrupt no UART-interrupts are invoked.

I assume Serial.availble() returns the number of bytes that have been received and added to the serial receivebuffer. Which means Serial.available() is "polling" very very short by just reading and returning a single byte which represents the number of bytes ready to read out from the serial inputbuffer. This needs only a few CPU-clockcycles.

Any other solution will be slower.
So only in case you are calling serial.available() in too big intervalls you will miss bytes.

It is as so very often: Wrong assumptions lead to wrong solutions and the problem is in 95% of all cases outside the code-snippet that was posted.

The rest of your code has to be non-blocking to make sure that checking and processing for received bytes is done often enough.

You can increase the size of serial inputbuffer to win time until the buffer is full for the cost of RAM. If you are using an Arduino Uno which has only 2 kB of RAM this might be a problem. Then you should change to a different microcontroller that has more RAM and has a higher CPU-clock frequency.

At 9600 baud, serial data is sent at a maximum of 960 characters/second (1 start bit, 8 data bits, no parity, 1 stop bit). SERIAL_7O1 is the same, just replacing a data bit with a parity bit. The default 64-byte receive buffer can hold a maximum of 63 characters, which will take 65.625mS to fill, so as long as you poll Serial.available() at shorter intervals there should not be a problem.

Setting a flag in an interrupt, then polling the interrupt flag, does not seem to have any advantage over directly polling Serial.available.

Your code needs variable declarations.

As originally mentioned, I dabble in this so, obviously, I'm not an "expert" or even well versed. At 78 I don't expect to become one anytime soon. I do this for "fun" and to keep whatever brain cells I have left firing.

I don't know how to calculate execution time for C statements, so that doesn't help.
I don't recall why I thought using an interrupt to trigger processIncomingByte() (hereafter referred to pIB) was necessary. I guess I was hoping to ensure I was grabbing a byte when it became available.

For those that wanted to see all the code, I'll post it below. It is the version where pIB is the ISR. I'm using the Mega 2560. This code appeared to be working OK, I was just wondering what might be better.

The millis question is something else. I use it elsewhere and it appears to work OK but in RUN_P near the bottom, Time doesn't produce numbers that are legitimate. I don't know why.

There is probably a bucket load of things that could be done better with this code. I'm not asking for a total overhaul, just the pIB and millis issues would help for now.

Tried posting but my character count exceeded the max. I'll remove some of the functions that deal with the display.

Edit: I inserted the code between the code marks, don't know why it didn't come out in color.

#include <UTFT.h>
#include <URTouch.h>
#include <URTouchCD.h>
#include <EEPROM.h>
#include <TimerThree.h>

#define TOUCH_ORIENTATION PORTRAIT

// Initialize display
UTFT myGLCD(CTE32_R2, 38, 39, 40, 41);

// Initialize touchscreen
URTouch  myTouch( 6, 5, 4, 3, 2);
// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t Retro8x16[];
extern uint8_t Arial_round_16x24[];
extern uint8_t arial_bold[];

int x, y, ss_status, RemPan;      // coordinates, start/stop status, pan removed
int strStart, Ret;                // valid start of string
int Scale;
int ex, ea, ev, Spd, T_Sel=0;
int ev1, ex1;
int8_t Freq = 20;             
int8_t F_Delta;
int16_t F_ON, F_OFF, M_ON, M_OFF, S_ON, S_OFF, VS_ON, VS_OFF;
float M_Delta, S_Delta, VS_Delta, temp, F_Duty, M_Duty, S_Duty, VS_Duty;
float T_rng;    // weight range shy of target where trickling happens if that option is selected
float T_start, T_end, Time;   // time to finish trickling
int Trick_start = 0;

char* end;
char* X;
char* ptr;
//
//  ep_start_P allows for EEPROM wear leveling for PWM mode. It defines the start address for the
//  first EEPROM address to be used (actually it will be ep_start_P + 9). It is suggested
//  that the blocks be increased by 40 each time it gets reassigned. EEPROM should
//  be good for 100,000 writes (so a block should be good for a long time).
//  Example: blocks should start at address: 0, 40, 80, 120, 160..... etc.
//
//  ep_start_M allows for EEPROM wear leveling for Manual mode.  These blocks will start at the other 
//  end of EEPROM and work backwards.  These will be in groups of 100 so the first group will be
//  3900 to 4000.
//  Formula for Low Byte address ea = (ep_start_M - 100) + ((activ_Pdr - 1) * 24) + ((activ_Set * 2) - 2)
//
int ep_start_P = 0;           // EEPROM start address for PWM mode
int ep_start_M = 4000;        // EEPROM start address for Manual mode

char test[10];
char stCurrent[20] = "";
char stCurrent1[5] = ""; 
char stCurrent2[2] = "0";    // used for trickle trigger - amount from target weight trickling will begin
int stCount = 0;
int stCount1 = 0;           // used in the settings_PWM screen
int stCount2 = 0;           // used for trickle trigger
float Delta;
double Target, Diff;
volatile double CurWeight, OldWeight;       // debug volatile added
int success = 0, i;      // target weight reached = 1
int activ_Pdr;           // Powder type box highlighted (1 - 4)
int activ_Set = 0;       // Settings box highlighted (1 - 12)
int Test_Mode = 0;       // Flag to determine whether to enter Dandy trickle test
int IPF;                 // Input Full flag
int mode;                // 0 for PWM, 1 for Manual
int firstPress = 0;      // flag for clicking on settings hot spot ( * )
int firstPress_M = 0;    // flag for clicking on settings hot spot ( * ) for manual mode
//const unsigned int MAX_INPUT = 11;  FX
const unsigned int MAX_INPUT = 12;   // debug was 10
int inByte, I_Dly;
int speed, Fu, Fa, M, S, Vs, done;    // Used in RUN()
static char input_line [MAX_INPUT];
unsigned long Start_Time;
unsigned long Start_ON_Time;
unsigned long Start_OFF_Time;
unsigned long Cur_Time;
unsigned long period;
unsigned long Pause_Start_Time;
unsigned long O_period, F_period;
int OnTimeDone, OffTimeDone;
int ON_tim, OFF_tim;
int oldSpeed;
int init_ON, init_OFF, ON_Comp, OFF_Comp;
unsigned long Start_Loop_Time;
unsigned long Loop_Time;
int T_T = 0;  // trickle trigger


 /************************
 *  processIncomingByte  * 
 *************************/
 void processIncomingByte () {

  byte inByte;
  static unsigned int input_pos = 0;

  if(Serial1.available () > 0){
    inByte = Serial1.read();
  
  switch (inByte)
  {
    case '+':
      strStart = 1;
      input_pos = 0;
      input_line[input_pos++] = inByte;
      break;

    case '-':
      strStart = 1;
      input_pos = 0;
      input_line[input_pos++] = inByte;
      break;
    
    default:         // keep adding if not full ... allow for terminating null byte
      if ((input_pos <= MAX_INPUT) && (strStart == 1) && (inByte >= 43) && (inByte <= 57) || (inByte == 32)){
        if (inByte == 32)     // debug TP153
          inByte = '0';       // debug TP153
      
        input_line[input_pos++] = inByte;
      if(input_pos > MAX_INPUT)
        input_pos = MAX_INPUT;
      }
      else
      {
      input_line[input_pos] = NULL;
      if(strStart == 1){
        CurWeight = strtod(input_line, &X);
      }
      strStart = 0;
      input_pos = 0;      // reset buffer for next time
      }
      break;
  }   // end of switch
  
  OldWeight = CurWeight;
 }
 }    // end of processIncomingByte


/*************************
**  Required functions  **
*************************/
/************************************************************************************************************
*   PWM info - formula for frequency is 16,000,000/2*N*TOP - where 16,000,000 is the clock frequency,       *
*   N is the prescaler divider which is 256 in this case and TOP is the OCR1A value.  Since freq is         *
*   entered on the settings_PWM page, OCR1A is the value needed.  OCR1A = 31,250/freq.  Duty cycle (OCR1B)  *
*   = OCR1A * the value entered on the settings_PWM page / 100.  This needs to be rounded to the nearest    *
*   integer.                                                                                                *
************************************************************************************************************/

/**********
*  setup  *
**********/
void setup() {
   
  Serial.begin(9600);       // when communicating with serial monitor

  Scale = EEPROM.read(ep_start_P + 48);
  if(Scale == 3){
  Serial1.begin(9600, SERIAL_7O1);      // debug for TP153 scale
  //MAX_INPUT = 12;
  }
  else
  {
  Serial1.begin(9600);      // for scale
  //MAX_INPUT = 10;
  }
  mode = EEPROM.read(ep_start_P + 46);
 
  CurWeight = -1;
  myGLCD.InitLCD(0);    // Portrait
  myGLCD.clrScr();
  stCurrent1[0]="";
  stCurrent1[1]="";
  stCurrent1[2]="";
  myGLCD.setFont(arial_bold);
  myGLCD.print("Target", 25, 5);
  myGLCD.print("______", 25, 37);
  myGLCD.print("Weight", 25, 30);
  myGLCD.print(" gr", 120, 70);
  pinMode(11, OUTPUT);    // Brake control
  pinMode(12, OUTPUT);    // Trickler
  pinMode(13, OUTPUT);    // onboard LED
  Timer3.initialize(885);
  Timer3.attachInterrupt(processIncomingByte);

  TCCR1A = _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);      // phase and frequency correct
  TCCR1B = _BV(WGM13) | _BV(CS12);     //prescaler div 256
  OCR1A = 31250/Freq;     // Frequency
  OCR1B = 0;              // 0% duty cycle

// flushEEPROM();       //Only used for debug
  myTouch.InitTouch(TOUCH_ORIENTATION);
  myTouch.setPrecision(PREC_MEDIUM);
  T_rng = strtod(stCurrent2, &ptr);

 STOP();
}       // end setup
/*********
*  loop  *
*********/
void loop() {
  // Digit coordinates - 1xx.xx (25,65), x1x.xx (41,65), xx1.xx (57,65), decimal point (74,65), xxx.1x (88,65), xxx.x1 (106,65)
  // 
  // User input string sits in a 7 byte buffer and the data is entered from right to left (reverse of "normal")
  // the data in the stCurrent buffer is in "AB.CD<null>" format where A is in stCurrent[0] and <null> is in
  // stCurrent[5] to mark the end of the string. stCount is the pointer into the stCurrent array which when starting
  // to fill the buffer initall point to the 5th byte (the "D" in the above example) This is subscript #4.
  //
  //  Output is an ASCII string which will be converted to a internal floating point number when RUN is pressed (eventually)
  //
  //  Initalize the 7 byte array
  //                                             
  firstPress = 0;
while (true) {

    myGLCD.setFont(Arial_round_16x24);
    if (myTouch.dataAvailable())
    {
      myTouch.read();
      delay(100);
      x=myTouch.getX();
      y=myTouch.getY();
      myGLCD.setBackColor(0, 0, 0);      
//
//    DECODE BUTON PRESS IN THE 1 2 3 ROW
//
   if ((stCount < 7 ) || (stCount2 < 2))
   {
      if ((y>=145) && (y<=175))  // 1-3 row
      {
        if ((x>=10) && (x<=70))  // Button 1
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '1';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(10, 145, 70, 175);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '1';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
        if ((x>=90) && (x<=150))  // Button 2
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '2';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(90, 145, 150, 175);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '2';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
        if ((x>=170) && (x<=230))  // Button 3
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '3';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(170, 145, 230, 175);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '3';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
      }
   }  
//
//    DECODE BUTON PRESS IN THE 4 5 6 ROW
// 
     if ((stCount < 7 ) || (stCount2 < 2))
     {              
        if ((y>=190) && (y<=220))  // 4-6 row
      {
        if ((x>=10) && (x<=70))  // Button 4
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '4';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(10, 190, 70, 220);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '4';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
          if ((x>=90) && (x<=150))  // Button 5
            if (T_T == 1){
              if(stCount2 < 1){
                stCurrent2[stCount2] = '5';
                myGLCD.print(stCurrent2, 68, 15);
                stCount2++;
            }
          }
          else
        {
          waitForIt(90, 190, 150, 220);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '5';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
          if ((x>=170) && (x<=230))  // Button 6
            if (T_T == 1){
              if(stCount2 < 1){
                stCurrent2[stCount2] = '6';
                myGLCD.print(stCurrent2, 68, 15);
                stCount2++;
            }
          }
          else
        {
          waitForIt(170, 190, 230, 220);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '6';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
      }
     }   
//
//    DECODE BUTON PRESS IN THE 7 8 9 ROW
//
     if (stCount < 7 )
     {        
        if ((y>=235) && (y<=265))  // 7-9 row 
      {
        if ((x>=10) && (x<=70))  // Button 7
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '7';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(10, 235, 70, 265);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '7';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
        if ((x>=90) && (x<=150))  // Button 8
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '8';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(90, 235, 150, 265);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '8';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
        if ((x>=170) && (x<=230))  // Button 9
          if (T_T == 1){
            if(stCount2 < 1){
              stCurrent2[stCount2] = '9';
              myGLCD.print(stCurrent2, 68, 15);
              stCount2++;
            }
          }
          else
        {
          waitForIt(170, 235, 230, 265);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '9';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
      }
     }    
//
//    DECODE BUTON PRESS IN THE . 0 <x ROW
// 
        if ((y>=280) && (y<=310))  // ., 0, <x row
      {
        if (stCount < 7 )
        {
        if ((x>=10) && (x<=70))  // Button '.'
        {
          waitForIt(10, 280, 70, 310);
          TestInputFull ();
          if (stCount < 6)
          {
          if (stCount == 2){                  // This adds a leading space if there are
            stCurrent[3] = '.';               // only 2 numbers before the decimal point
            stCurrent[2] = stCurrent[1];
            stCurrent[1] = stCurrent[0];
            stCurrent[0] = ' ';
            stCount = 4;
          }
          if (stCount == 1){                  // This adds 2 leading spaces if there is
            stCurrent[3] = '.';               // only 1 number before the decimal point
            stCurrent[2] = stCurrent[0];
            stCurrent[1] = ' ';
            stCurrent[0] = ' ';
            stCount = 4;
          }
          else{
          if (stCount == 3){
          stCurrent[stCount] = '.';
          stCount++;
          }
          }
          myGLCD.print(stCurrent, 25, 65); 
          }
        }
        }
          if ((x>=90) && (x<=150))  // Button 0
            if (T_T == 1){
              if(stCount2 < 1){
                stCurrent2[stCount2] = '0';
                myGLCD.print(stCurrent2, 68, 15);
                stCount2++;
            }
          }
          else
        {
          if (stCount < 7 )
          {
          waitForIt(90, 280, 150, 310);
          TestInputFull ();
          if (stCount < 6)
          {
          stCurrent[stCount] = '0';
          myGLCD.print(stCurrent, 25, 65);
          stCount++;
          }
        }
        }
      
        if ((x>=170) && (x<=230))  // Button <x (backspace)
        {
          waitForIt(170, 280, 230, 310);
          BS ();
          if(T_T == 1)
            myGLCD.print(stCurrent2, 68, 15);
          myGLCD.print(stCurrent, 25, 65);
          
        }
      }
      if ((x >= 175 && x <= 235) && (y >= 70 && y <= 110))    // hot box for * (Settings)
      {
        if(firstPress == 0){
          Start_Time = millis();
          firstPress = 1;
        }
    
        Cur_Time = millis();
          if(Cur_Time - Start_Time > 1000){
      
          if (mode == 0)
            Settings_PWM();
          else
            Settings_Man();
      }
                                    
      }   // end of if * hot box

      if((x >= 26 && x <= 120) && (y >= 1 && y<= 45))     // Select trickle trigger range
      {
        if(T_T == 0){
          T_T = 1;
          myGLCD.setColor(0, 0, 0);
          myGLCD.fillRoundRect (26, 1, 119, 44);
          myGLCD.setFont(Arial_round_16x24);
          myGLCD.setColor(255, 255, 255);
          myGLCD.print(stCurrent2, 68, 15);
        }
        else
        {
          T_T = 0;
          myGLCD.setFont(arial_bold);
          myGLCD.setColor(0, 0, 0);
          myGLCD.fillRoundRect (26, 1, 119, 44);
          myGLCD.setColor(255, 255, 255);
          myGLCD.print("Target", 25, 5);
          myGLCD.print("______", 25, 37);
          myGLCD.print("Weight", 25, 30);
          myGLCD.setColor(0, 0, 0);
          myGLCD.drawRoundRect (25, 0, 120, 45);
          T_rng = strtod(stCurrent2, &ptr);
        }
      }
      if ((x >= 20) && (x <= 214) && (y>= 118) && (y <= 134))   // go to instructions
        Instr();

      if ((y >= 5) && (y <= 55) && (x >= 155) && (x <= 235))    // RUN / STOP Button
      {
        if (ss_status == 0){
          EEPROM.update((ep_start_P + 46), mode);
            if (mode == 0)
            RUN_P();
            else
            RUN_M();
            }
          else
            STOP();
      }
     }    // end of if myTouch.dataAvailable
     else
     {
      x = 0;
      y = 0;
      Cur_Time = millis();
      if((Cur_Time - Start_Time) < 5) {
        if (mode == 0)
          mode = 1;
        else
          mode = 0;
    
        myGLCD.setFont(arial_bold);
         if (mode == 0){
          myGLCD.setColor(255, 255, 255);
          myGLCD.print("*", 198, 78); }
        else {
          myGLCD.setColor(255, 170, 0);
          myGLCD.print("*", 198, 78);
          myGLCD.setColor(255, 255, 255);
         }
      }
      firstPress = 0;

     }
        /********************************************
        *  This section of code is for the FX-120i  *
        *  since it doesn't accept odd numbers in   *
        *  the second decimal place.                *
        *  The TRX scale doesn't need this.         *
        ********************************************/
      if((Scale == 1) || (Scale == 3)){         // FX or TP scale
      int r = stCurrent[5] - '0';               // Limit 2nd decimal place to even number
      if ((stCurrent[5]) >= 48 && (stCurrent[5]) <= 57){      
        if ((r % 2) != 0){
          r = r - 1;
          stCurrent[5] = r + 48;
          myGLCD.print(stCurrent, 25, 65); 
        }
      }
      } // end of if(scale)
   }    // end of while(true)
 }      // end loop

/***********
*   STOP   *      RUN displayed
************/
void STOP()
{
    ss_status = 0;
    RemPan = 0;
    success = 0;
    if (mode == 0)
      OCR1B = 0;              // 0% duty cycle
    else                
    digitalWrite(12, HIGH);  // manual mode stop
    digitalWrite(11, LOW);    // disable brake
    myGLCD.setColor(0, 255, 0);
    myGLCD.fillRoundRect (155, 5, 235, 55);
    myGLCD.setColor(0x001F);                // what's this?  Virtually black
    myGLCD.drawRoundRect (155, 5, 235, 55);
    myGLCD.setBackColor(0, 255, 0);
    myGLCD.setFont(arial_bold);
    myGLCD.print("RUN", 172, 24);
    delay(100);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.print("      ", 5, 90);
    drawButtons();
    myGLCD.setColor(255, 255, 255);
    myGLCD.setBackColor(0, 0, 0);
    //myGLCD.print("*", 198, 78);     // replace *
    myGLCD.setFont(Arial_round_16x24);
    myGLCD.print(stCurrent, 25, 65); 
}      // end of STOP

/****************
*   RUN (PWM)   *      PWM mode, STOP displayed
****************/
void RUN_P()    
{  
  if (activ_Pdr < 1 || activ_Pdr > 4){        // If Settings_PWM() has not been run, activ_Pdr might be outside 1-4
    myGLCD.setFont(arial_bold);               // if so, the asterisk '*' will blink until pressed then
    while (true)                              // proceed to Settings_PWM.
    {
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("*", 198, 78);
    delay(500);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("*", 198, 78);
    delay(500);
    myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      if ((x >= 175 && x <= 235) && (y >= 70 && y <= 110)){     // hot box for * (Settings_PWM)
        myGLCD.setColor(255, 255, 255);
        myGLCD.print("*", 198, 78);
        myGLCD.setFont(Arial_round_16x24);
        return(0);
      }
    }
  }
    ss_status = 1;
    myGLCD.setColor(255, 0, 0);
    myGLCD.fillRoundRect (155, 5, 235, 55);
    myGLCD.setColor(255, 224, 0);           // dark yellow
    myGLCD.drawRoundRect (155, 5, 235, 55);
    myGLCD.setBackColor(255, 0, 0);
    myGLCD.setFont(arial_bold);
    myGLCD.print("STOP", 164, 24);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print(" ", 198, 78);     // remove the *
    myGLCD.fillRect(5, 118, 235, 315);
    myGLCD.setColor(255, 255, 0);             
    myGLCD.print("              ", 10, 94);   
    Target = strtod(stCurrent,NULL);
    Diff = (Target - CurWeight);
    oldSpeed = 6;
    RemPan = 0;
    success = 0;
    Start_Time = 0;
    TCCR1A = _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);      // phase and frequency correct
    
//  Load variables from EEPROM for use here
  
    activ_Pdr = EEPROM.read(ep_start_P + 45);
    ea = activ_Pdr * 9 + ep_start_P;
    Freq = EEPROM.read(ea);
    OCR1A = 31250/Freq;
    F_Duty = EEPROM.read(ea+1);
    F_Delta = EEPROM.read(ea+2);
    F_Delta = F_Delta/10;
    M_Duty = EEPROM.read(ea+3);
    M_Delta = EEPROM.read(ea+4);
    M_Delta = M_Delta/10;
    S_Duty = EEPROM.read(ea+5);
    S_Delta = EEPROM.read(ea+6);
    S_Delta = S_Delta/100.0;      // debug
    VS_Duty = EEPROM.read(ea+7);
    VS_Delta = EEPROM.read(ea+8);
    VS_Delta = VS_Delta/100.0;    // debug
    digitalWrite(11, LOW);     // disable brake
    OldWeight = CurWeight;
    i = 0;
//
//  Stay in this code until the STOP button is pushed
//  
    period = EEPROM.read(ep_start_P + 47) * 1000;      // delay time (ms)

    if(Target - T_rng < 0){    //debug
      T_rng = 1;              //debug
      stCurrent2[0] = '1';
    }
    while (true)
    {
      //processIncomingByte();

      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();
      
      if (((y>=5) && (y<=55)) && ((x>=155) && (x<=235)))   // RUN / STOP button
      {
 //        STOP Button pushed?
          return(0);
      }
      
        if ((CurWeight >= 0) && (RemPan == 1)) {    // pan has been lifted and replaced
          success = 0;
          RemPan = 0;
          Start_Time = millis();
        }
        Cur_Time = millis();
        if (Cur_Time - Start_Time >= period) {    //pan replace pause  

        if (Trick_start == 0){    // start trickle timing     debug
        Trick_start = 1;
        T_start = millis();
        }

          Diff = (Target - CurWeight);
      
          if((((T_rng == 0) && (CurWeight > -.02) && (CurWeight < Target)) || 
            ((T_rng >= 1 && T_rng <= 9) && (CurWeight >= (Target - T_rng)) &&   // weight in trickle range,
            (CurWeight < Target))) && (RemPan == 0) && (success == 0))          // pan not removed and target not reached
        {                                                               
        if((CurWeight - OldWeight) > -.5)    // pan not removed, current weight must have dropped more than .5 from previous
          {
            if (Diff < VS_Delta){
              temp = (OCR1A * (VS_Duty/100));
              OCR1B = int (temp);
              speed = 5;            // VSlo
          //    digitalWrite(11, HIGH);     // enable brake
              }
          
            if ((Diff >= VS_Delta) && (Diff < S_Delta)){
              temp = (OCR1A * (S_Duty/100));
              OCR1B = int (temp);
              speed = 4;           // Slo
          //    digitalWrite(11, HIGH);     // enable brake
              }
          
            if ((Diff >= S_Delta) && (Diff < M_Delta)){   
              temp = (OCR1A * (M_Duty/100));
              OCR1B = int (temp);
              speed = 3;          // Med
          //    digitalWrite(11, LOW);     // disable brake
              }
          
            if ((Diff >= M_Delta) && (Diff < F_Delta)){
              temp = (OCR1A * (F_Duty/100));
              OCR1B = int (temp);
              speed = 2;          // Fast
          //    digitalWrite(11, LOW);     // disable brake
              }

            if (Diff >= F_Delta){
              OCR1B = OCR1A;
              speed = 1;
          //    digitalWrite(11, LOW);     // disable brake
              }    // full on 100% duty cycle
          }
          else     // current weight < last weight by more than .5 gr  assume pan is being removed
          {
            OCR1B = 0;
            RemPan = 1;
            speed = 0;
          }
        }   // end of weight in trickle range
        else
        speed = 0;
        if(Diff < .01){
          OCR1B = 0;
          success = 1;
          speed = 0;
          Trick_start = 0;    // debug
          T_end = millis();   // debug
        }
        if(CurWeight < 0){
          RemPan = 1;
          OCR1B = 0;
          speed = 0;
        }
        
        if(oldSpeed - speed != 0){
          if(speed == 0)
          {
            myGLCD.print("    ", CENTER, 125);
            myGLCD.printNumI(T_start, CENTER, 150);   // debug
            myGLCD.printNumI(T_end, CENTER, 175);      // debug
            Time = (T_end - T_start)/1000.0;          // debug
            myGLCD.print("       ", CENTER, 200);     // debug
            myGLCD.printNumF(Time, 2, CENTER, 200, '.', 3);   // debug
          }
          if(speed == 1)
            myGLCD.print("FULL", CENTER, 125);
          if(speed == 2)
            myGLCD.print("FAST", CENTER, 125);
          if(speed == 3)
            myGLCD.print("MED ", CENTER, 125);
          if(speed == 4)
            myGLCD.print("SLO ", CENTER, 125);
          if(speed == 5)
            myGLCD.print("VSlo", CENTER, 125);
          if((speed < 0) || (speed > 5))
            myGLCD.print("DFLT", CENTER, 125);

        oldSpeed = speed;
        }
        OldWeight = CurWeight;      // used to determine if pan is being lifted
    }     // end of pan replaced pause time
    }   // end while
 }      // end RUN_P

/******************
*   RUN (manual)  *
******************/
void RUN_M()
{
ss_status = 1;
    myGLCD.setColor(255, 0, 0);
    myGLCD.fillRoundRect (155, 5, 235, 55);
    myGLCD.setColor(255, 224, 0);           // dark yellow
    myGLCD.drawRoundRect (155, 5, 235, 55);
    myGLCD.setBackColor(255, 0, 0);
    myGLCD.setFont(arial_bold);
    myGLCD.print("STOP", 164, 24);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print(" ", 198, 78);     // remove the *
    myGLCD.fillRect(5, 118, 235, 315);
    myGLCD.setColor(255, 255, 0);             
    myGLCD.print("              ", 10, 94);   
    Target = strtod(stCurrent, &X);
    Diff = (Target - CurWeight);
    OnTimeDone = 0;   // initialize
    OffTimeDone = 0;  // the ON / OFF loop
    O_period = 0;
    F_period = 0;
    oldSpeed = 6;
    RemPan = 0;
    success = 0;
    init_ON = 0;
    init_OFF = 0;
    ON_Comp = 0;
    OFF_Comp = 0;
    OldWeight = CurWeight;
    i = 0;
    Pause_Start_Time = 0;
    TCCR1A = 0;     // set PWM pin (12) to normal output
    //
    GetEE_data_M ();
      
    period = EEPROM.read(ep_start_P + 47) * 1000;      // delay time (ms)

    if(Target - T_rng < 0){    //debug
      T_rng = 1;              //debug
      stCurrent2[0] = '1';
    }
    //
    //  Stay in this code until the STOP button is pushed
    //
    while (true)
    {
    //  processIncomingByte();

      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();
      
      if (((y>=5) && (y<=55)) && ((x>=155) && (x<=235)))   // RUN / STOP button
      {
      //        STOP Button pushed?
          digitalWrite(12, HIGH);   // output off
          return(0);
      }
      if ((CurWeight >= 0) && (RemPan == 1)) {    // pan has been lifted and replaced
          success = 0;
          RemPan = 0;
          //myGLCD.print("      ", CENTER, 150);    debug
          Pause_Start_Time = millis();
        }
      Cur_Time = millis();
     // T_start = Cur_Time;     debug
      if (Cur_Time - Pause_Start_Time >= period) {   // pan replaced pause time

    //  if (Trick_start == 0){    // start trickle timing
    //  Trick_start = 1;
    //  T_start = millis();
    //  }

      Diff = (Target - CurWeight);
    
      if((((T_rng == 0) && (CurWeight > -.02) && (CurWeight < Target)) || 
        ((T_rng >= 1 && T_rng <= 9) && (CurWeight >= (Target - T_rng)) &&   // weight in trickle range,
        (CurWeight < Target))) && (RemPan == 0) && (success == 0))          // pan not removed and target not reached
      { 
        if((CurWeight - OldWeight) > -.5){    // pan not removed
          // Determine speed
          if (Diff < VS_Delta){
              ON_tim = VS_ON;
              OFF_tim = VS_OFF;
              speed = 5;    // VSlo
              digitalWrite(11, HIGH);     // enable brake
              }
          
            if ((Diff >= VS_Delta) && (Diff < S_Delta)){
              ON_tim = S_ON;
              OFF_tim = S_OFF;
              speed = 4;    // Slo
              digitalWrite(11, HIGH);     // enable brake
              }
          
            if ((Diff >= S_Delta) && (Diff < M_Delta)){   
              ON_tim = M_ON;
              OFF_tim = M_OFF;
              speed = 3;    // Med
              digitalWrite(11, LOW);     // disable brake
              }
          
            if ((Diff >= M_Delta) && (Diff < F_Delta)){
              ON_tim = F_ON;
              OFF_tim = F_OFF;
              speed = 2;    // Fast
              digitalWrite(11, LOW);     // disable brake
              }

            if (Diff >= F_Delta){
              digitalWrite(12, LOW);   // output on
              OFF_tim = 0;
              speed = 1;    // full on
              digitalWrite(11, LOW);     // disable brake
              }    
  //
  //  Pulse output
  //
      if (OFF_tim != 0){    // skip pulsing if OFF_tim is set to 0
      if(init_ON == 0)  // 
        {   // init ON cycle
        Start_ON_Time = millis();
        digitalWrite(12, LOW);    // output on
        init_ON = 1;
        }
      else if((ON_Comp == 0) && (init_ON == 1))
        {
        Cur_Time = millis();
        O_period = Cur_Time - Start_ON_Time;
          if (O_period >= ON_tim){
            Start_OFF_Time = millis();  // init OFF time
            digitalWrite(12, HIGH);   // output off
            init_OFF = 1;
            ON_Comp = 1;
            OFF_Comp = 0;
          }
        }
      else if((OFF_Comp == 0) && (init_OFF == 1))
        { 
        Cur_Time = millis();
        F_period = Cur_Time - Start_OFF_Time;
          if (F_period >= OFF_tim){
            init_OFF = 0;
            init_ON = 0;
            ON_Comp = 0;
            OFF_Comp = 1;
          }
        }
        }   // end of skip pulsing
        }   // end of pan not removed
        else    // current weight < last weight by more than .5 gr  assume pan is being removed
        {
          digitalWrite(12, HIGH);   // output off
          RemPan = 1;
          speed = 0;
        }
      }   // end of 'if weight in trickle range'
      else
      speed = 0;
         if (Diff < .01) {
            digitalWrite(12, HIGH);   // output off
             success = 1;
             O_period = ON_tim;
             F_period = OFF_tim;
        //     Trick_start = 0;
        //     T_end = millis();
            speed = 0;
         }
          if (CurWeight < 0) {
            RemPan = 1;
            digitalWrite(12, HIGH);   // output off
            speed = 0;
          }
        if((oldSpeed - speed) != 0){  
          if(speed == 0){
            myGLCD.print("    ", CENTER, 125);
      //      myGLCD.printNumI(T_start, CENTER, 150);
       //     myGLCD.printNumI(T_end, CENTER, 175);
       //     T_end = (T_end - T_start)/1000.0;
       //     myGLCD.print("       ", CENTER, 200);
      //      myGLCD.printNumF((T_end-T_start)/1000.0, 2, CENTER, 200, '.', 3);
          }
          if(speed == 1)
            myGLCD.print("FULL", CENTER, 125);
          if(speed == 2)
            myGLCD.print("FAST", CENTER, 125);
          if(speed == 3)
            myGLCD.print("MED ", CENTER, 125);
          if(speed == 4)
            myGLCD.print("SLO ", CENTER, 125);
          if(speed == 5)
            myGLCD.print("VSlo", CENTER, 125);
          if((speed < 0) || (speed > 5))
            myGLCD.print("DFLT", CENTER, 125);

          oldSpeed = speed;
          }
        OldWeight = CurWeight;    // used to determine if pan is being lifted
    //    myGLCD.print(input_line, 15, 160);                // debug
    //    myGLCD.printNumF(CurWeight, 2, 50, 190, '.', 5);  // debug
    //    myGLCD.printNumF(Diff, 2, 50, 200, '.', 5);  // debug
    //    myGLCD.printNumI(F_Delta, 50, 220);  // debug
    //    myGLCD.printNumI(M_Delta, 50, 240);  // debug
    //    myGLCD.printNumF(S_Delta, 2, 50, 260,  '.', 2);  // debug
    //    myGLCD.printNumF(VS_Delta, 2, 50, 280,  '.', 2);  // debug
      } // end of pan replaced pause time
    }   // end while (true)
}       // end RUN_M

/*****************
*  Settings_PWM  *    screen to change PWM settings
*****************/
void Settings_PWM()
{
TCCR1A = _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);      // phase and frequency correct
mode = 0;                // PWM mode
myGLCD.InitLCD();        // Landscape
myGLCD.clrScr();
myTouch.InitTouch(LANDSCAPE);
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(255, 255, 255);
myGLCD.setFont(SmallFont);
myGLCD.print("Powder   Freq          Duty            ", 5, 3);
myGLCD.print(" Type     Hz            %              ", 6, 15);
myGLCD.print("Delta", 255, 10);
myGLCD.print("Speed", 128, 10);
myGLCD.setFont(Retro8x16);
// Powder types
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 40, 50, 65);
myGLCD.setColor(0, 0, 0);
myGLCD.print("Ball", 11, 46);
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 70, 50, 95);
myGLCD.setColor(0, 0, 0);
myGLCD.print("Flake", 6, 76);
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 100, 50, 125);
myGLCD.setColor(0, 0, 0);
myGLCD.print("S_Stk", 6, 106);
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 130, 50, 155);
myGLCD.setColor(0, 0, 0);
myGLCD.print("L_Stk", 6, 136);
// Freq boxes
myGLCD.setColor(255, 255, 255);
myGLCD.drawRoundRect (70, 40, 110, 65);
myGLCD.drawRoundRect (70, 70, 110, 95);
myGLCD.drawRoundRect (70, 100, 110, 125);
myGLCD.drawRoundRect (70, 130, 110, 155);
// Duty
myGLCD.drawRoundRect (182, 40, 222, 65);
myGLCD.drawRoundRect (182, 70, 222, 95);
myGLCD.drawRoundRect (182, 100, 222, 125);
myGLCD.drawRoundRect (182, 130, 222, 155);
// Delta
myGLCD.drawRoundRect (272, 40, 295, 65);
myGLCD.drawRoundRect (262, 70, 295, 95);
myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
// Speeds
myGLCD.setBackColor(0, 0, 0);
myGLCD.setColor(255, 255, 255);
myGLCD.print("Fast", 130, 45);
myGLCD.print("Med", 134, 75);
myGLCD.print("Slo", 134, 105);
myGLCD.print("VSlo", 130, 135);

// Keypad
// Draw the top row of keypad 1 - 6
    for (x=0; x<6; x++)
  {
    myGLCD.setColor(255, 255, 255);
    myGLCD.fillRoundRect (5+(50*x), 175, 45+(50*x), 200);
    myGLCD.setColor(0, 0, 0);
    myGLCD.setBackColor(255, 255, 255);
    myGLCD.printNumI(x+1, 20+(50*x), 182);
  }
// Next row for 7, 8 & 9
    for (x=0; x<3; x++)
  {
    myGLCD.setColor(255, 255, 255);
    myGLCD.fillRoundRect (5+(50*x), 210, 45+(50*x), 235);
    myGLCD.setColor(0, 0, 0);
    myGLCD.printNumI(x+7, 20+(50*x), 217);
  }
// For 0, . & SAVE
    for (x=3; x<6; x++)
    {
    myGLCD.setColor(255, 255, 255);
    myGLCD.fillRoundRect (5+(50*x), 210, 45+(50*x), 235);
    }
    myGLCD.setColor(0, 0, 0);
    myGLCD.printNumI(0, 171, 217);
    myGLCD.print(".", 221, 216);
    myGLCD.print("SAVE", 260, 217);
//
//    Load activ_Pdr from EEPROM
//
  
   activ_Pdr = EEPROM.read(ep_start_P + 45);
   if ((activ_Pdr < 1) || (activ_Pdr > 4))     // in case there's garbage in this memory location
    activ_Pdr = 0;                             // Set to 0 to indicate Settings required
   show_values_P();

//      Change backcolor of powder type when selected
//
  while(true) {
  if (myTouch.dataAvailable())
    {
      myTouch.read();
      delay(150);
      x = myTouch.getX();
      y = myTouch.getY();
    //
    // Fill the boxes based on the powder type
    //  
    if(Test_Mode == 0)
      {
    if ((x >= 2) && (x <= 50)) {      // Powder column
      if ((y >= 40) && (y <= 65)) {   // Ball
      activ_Pdr = 1;
      show_values_P();
      }

      if ((y >= 70 && y <= 95)) {     // Flake
        activ_Pdr = 2;
       show_values_P();
      }
      
      if ((y >= 100 && y <= 125)) {   // S_Stk
         activ_Pdr = 3;
        show_values_P();
      }

      if ((y >= 130 && y <= 155)) {   // L_Stk
         activ_Pdr = 4;
        show_values_P();       
      }
      EEPROM.write((ep_start_P + 45), activ_Pdr);
    }
//      activ_Pdr = The powder type
//      activ_set = The box (Freq, duty cycle, or weight within the powder type set
//      Select the frequency box for the powder type
//                                            
    if ((x >= 70) && (x <= 110)) { 
        if ((y >= 40) && (y <= 65) && (activ_Pdr == 1)) {    // Ball Freq
        myGLCD.setColor(255, 255, 0);           // yellow
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 41, 109, 64);
        activ_Set = 1; 
    }
      if ((y >= 70) && (y <= 95) && (activ_Pdr == 2)) {      // Flake Freq
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 71, 109, 94);
        activ_Set = 2;
    }
      if ((y >= 100) && (y <= 125) && (activ_Pdr == 3)) {    // S_Stk Freq
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 101, 109, 124);
        activ_Set = 3;
    }
    if ((y >= 130) && (y <= 155) && (activ_Pdr == 4)) {       // L_Stk Freq
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 131, 109, 154);
        activ_Set = 4;
    }
    RsetDutyBox();
    RsetDBox(); 
    }
//                                        Change Duty box color
     if ((x >= 182) && (x <= 222)) {
      if ((y >= 40) && (y <= 65)) {                          // Fast Duty
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 41, 221, 64);
        activ_Set = 5; 
    }
      if ((y >= 70) && (y <= 95)) {                          // Med Duty
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 71, 221, 94);
        activ_Set = 7;
    }
      if ((y >= 100) && (y <= 125)) {                        // Slo Duty
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 101, 221, 124);
        activ_Set = 9;
    }
    if ((y >= 130) && (y <= 155)) {                          // VSlo Duty
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 131, 221, 154);
        activ_Set = 11;
    }
    RsetFBox();
    RsetDBox(); 
    }
//                                              Change Delta box color
    if ((x >= 255) && (x <= 295)) {
      if ((y >= 40) && (y <= 65)) {                          // Fast Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (273, 41, 294, 64);
        activ_Set = 6; 
    }
      if ((y >= 70) && (y <= 95)) {                          // Med Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (263, 71, 294, 94);
        activ_Set = 8;
    }
      if ((y >= 100) && (y <= 125)) {                        // Slow Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (252, 100, 295, 125);          // debug
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (253, 101, 294, 124);            // debug
        activ_Set = 10;
    }
    if ((y >= 130) && (y <= 155)) {                          // V_Slow Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (252, 130, 295, 155);          // debug
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (253, 131, 294, 154);        // debug
        activ_Set = 12;
    }
    RsetFBox();
    RsetDutyBox(); 
    }
    if (stCount1 < 3)
    stCurrent1[stCount1+1] = 0;
    delay(200);
    {  myGLCD.setBackColor(0, 0, 0);
      if ((y >= 175) && (y <= 200))      // Top row
      {
        if((x >= 5) && (x <= 45)){       // button 1
          stCurrent1[stCount1++] = '1';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
         }
        if((x >= 55) && (x <= 95)){      // button 2
          stCurrent1[stCount1++] = '2';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        if((x >= 105) && (x <= 145)){    // button 3
          stCurrent1[stCount1++] = '3';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        if((x >= 155) && (x <= 195)){    // button 4
          stCurrent1[stCount1++] = '4';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        if((x >= 205) && (x <= 245)){    // button 5
          stCurrent1[stCount1++] = '5';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        if((x >= 255) && (x <= 295)){    // button 6
          stCurrent1[stCount1++] = '6';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }                              
      }
      if ((y >= 210) && (y <= 235))      // Bottom row
      {
        if((x >= 5) && (x <= 45)){       // button 7
          stCurrent1[stCount1++] = '7';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
         }
        if((x >= 55) && (x <= 95)){      // button 8
          stCurrent1[stCount1++] = '8';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        if((x >= 105) && (x <= 145)){    // button 9
          stCurrent1[stCount1++] = '9';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        if((x >= 155) && (x <= 195)){    // button 0
          stCurrent1[stCount1++] = '0';
          stCurrent1[stCount1] = 0;
          Set_switch_P();
        }
        //
        // Only accept a decimal point for activ_Set 8, 10 or 12 (Med, Slow or VSlo weight)
        //
        if((x >= 205) && (x <= 245)){    // button .
        if((activ_Set == 8) || (activ_Set == 10) || (activ_Set == 12)){
          stCurrent1[stCount1++] = '.';
          stCurrent1[stCount1] = 0;
          Set_switch_P();}
        }
        // If the SAVE button is pressed the input value is saved in EEPROM.
        // We only allow certain values to be saved. If anyting is out of an
        // aceptable range, it is modified here before it is stored.
        //  
        if((x >= 255) && (x <= 295)){       // SAVE button was pressed
          SetSpdColor();
  //
  //  ex is set to the EEPROM offset address where the value is to be saved
  //
          if(activ_Set != 0) {
          if (activ_Set <= 4) ex = 0;                 // Freq boxes
          if (activ_Set >= 5) ex = activ_Set - 4;     // Duty & Delta boxes
          }
        /*     
        activ_Set
              1       5     6
              2       7     8
              3       9     10
              4       11    12      

        ex
              0       1     2
              0       3     4
              0       5     6
              0       7     8

         We only allow certain values to be saved. If anyting is out of an
         aceptable range for the selected box (cell), it is modified here before it is stored.
        
        If activ_Set equals 8 a conversion to floating point is needed then multiply by 10 and then
         convert to an integer.
         The saved value for cell 8 should not be more than 90.  If it is greater than this - change the
         value to 90 for a stored maximum value of 9.0 grains.
         If activ_Set equals 10 or 12 we need to do a conversion to floating point
         then multiply by 100 and then convert to an integer.
         The saved value for cells 10 or 12 should not be more than 255. If it is
         greater than this - change the value to 255 for a stored maximum value of 2.55 grains. */

          switch (activ_Set)
            {
              case 8:
                temp = (strtod(stCurrent1, &end));               // RICK
                temp = temp * 10.0 + 0.01;                        // RICK
                ev = temp;
                if (ev > 90) ev = 90;
                break; 

              case 10:
              temp = (strtod(stCurrent1, &end));               // RICK
              temp = temp * 100.0 + 0.1;                        // RICK
              ev = temp;
              if (ev > 255) ev = 255;
              break;  

              case 12:
              temp = (strtod(stCurrent1, &end));               // RICK
              temp = temp * 100.0 + 0.1;                        // RICK
              ev = temp;
              if (ev > 255) ev = 255;
              break;  

              default:
              ev = atoi(stCurrent1);
              break;
            }
       /*    if ((activ_Set == 10) || (activ_Set == 12)) {
             temp = (strtod(stCurrent1, &end));       // debug
             temp = temp * 100.0 + .1;
             ev = temp;
             if (ev > 255) ev = 255;}                       // debug
           else {
             ev = atoi(stCurrent1); }     // For any cells other than 10 or 12 do a direct integer coversion */
          /*
           ev now contains an integer value for the selected cell
           Zero is not allowed for a stored value. if ev1 = 0, it is set to 1
          */
          if (ev == 0) {ev = 1;}
          /*
           CHECK THE CELL VALUES BEFORE ACTUALLY STORING THEM SO THEY ARE STORED WITHIN IN A USEFUL RANGE
          
           If this is a duty cycle cell and the value is greater than or equal to 90, change the value
           to 100 and save that value. At this point duty cycle cells are at the following
           values for ex: 1, 3, 5, 7
          */
          if(((ex == 1) || (ex == 3) || (ex == 5) || (ex == 7)) && (ev >= 90))
           {
            ev = 100;
            strcpy (stCurrent1, "100");
           }
          /*
           The weight from target should not be more than 9 grains for cell values of ex = 2 and 4
           Cell values where ex = 6 and 8 were taken care of above. NOTE: the resulting range should
           be 10 to 90 in increments of 10 for cells where ex = 2 or 4.
          */
          if((ex == 2) && (ev > 9)) ev = 9;
          if(ex == 2) ev = ev * 10;
          //if ((ex == 2 || ex == 4) && ev > 9) {ev = 9;}
          //if (ex == 2 || ex == 4) {ev = ev * 10;}   // Multiply ex cell values 2 and 4 by 10 before storing
          /*
           Limit the selected frequency to no greater than 20 Hz.
          */
          if ((ex == 0) && (ev > 20)) {ev = 20;}
          /*
            ea becomes the actual EEPROM address where the data is stored for the slected powder type
          */
          ea = (activ_Pdr * 9) + ex + ep_start_P;     /* ea is the EEPROM address where the data is to be stored
                                                         ev is the EEPROM value to be stored */
       
          EEPROM.update(ea, ev);                      // Save in EEPROM
          /*
           Set_Switch is called to display the entered value in the selected powder color so the user knows
           that the SAVE button was pressed. NOTE: the actual value saved may be different if the user entered
           a value outside of the range acceptable by the program. The user should re-display the values for
           the selected powder type to see the actual values stored.
          */
          Set_switch_P();
          activ_Set = 0;    //reset Activ_Set to zero
        }     // end of if SAVE button    
        }     // end of if bottom row
      }       // end of keypad entry after delay(200)
    }         // end of if(Test_Mode == 0)
    
  if (((x >= 5) && (x <= 317)) && ((y >= 3) && (y <= 28)))    // Top header box
  {
    EEPROM.update((ep_start_P + 46), mode);
    show_values_P();    // update timing variables
    setup();
    return(0);
  }
  
  if (((x >= 125) && (x <= 165)) && ((y >= 37) && (y <= 155)))    //  speed column
   {
    if((Test_Mode == 0) && (myTouch.dataAvailable() == 0))
      Test_Mode = 1;
    if((Test_Mode == 1) && (T_Sel == 1))
      Test_Mode = 0;  
   
    if((Test_Mode == 1) && (myTouch.dataAvailable() == 0)){
      myGLCD.setColor(255, 255, 255);
      if((y >= 37) && (y <= 67) && (T_Sel == 0) && (Test_Mode == 1)){      // Fast speed text block
        Spd = 1;
        T_Sel = 1;        
        myGLCD.print("Test", 130,45);}
      if((y >= 70) && (y <= 95) && (T_Sel == 0) && (Test_Mode == 1)){      // Med speed text block
        Spd = 2;
        T_Sel = 1;       
        myGLCD.print("Test", 130,75);}
      if((y >= 100) && (y <= 125) && (T_Sel == 0) && (Test_Mode == 1)){      // Slo speed text block
        Spd = 3;
        T_Sel = 1;        
        myGLCD.print("Test", 130,105);}
      if((y >= 130) && (y <= 155) && (T_Sel == 0) && (Test_Mode == 1)){      // VSlo speed text block
        Spd = 4;
        T_Sel = 1;        
        myGLCD.print("Test", 130,135);}

      Test_P(Spd);
   }
//    
    if((Test_Mode == 0) && (myTouch.dataAvailable() == 0)){
      SetSpdColor();
      firstPress_M = 0;
      if((y >= 37) && (y <= 67) && (T_Sel == 1) && (Spd == 1) && (Test_Mode == 0)){      // Fast speed text block
        T_Sel = 0;        
        myGLCD.print("Fast", 130, 45);}
      if((y >= 70) && (y <= 95) && (T_Sel == 1) && (Spd == 2) && (Test_Mode == 0)){      // Med speed text block
        T_Sel = 0;       
        myGLCD.print("    ", 130, 75);
        myGLCD.print("Med", 134, 75);}
      if((y >= 100) && (y <= 125) && (T_Sel == 1) && (Spd == 3) && (Test_Mode == 0)){      // Slo speed text block
        T_Sel = 0;        
        myGLCD.print("    ", 130, 105);
        myGLCD.print("Slo", 134, 105);}
      if((y >= 130) && (y <= 155) && (T_Sel == 1) && (Spd == 4) && (Test_Mode == 0)){      // VSlo speed text block
        T_Sel = 0;       
        myGLCD.print("VSlo", 130, 135);}
    }
    }   // end of if press in speed column 

    }    // end of if(mytouchavailable())
    }   // end While (true)
  }     // end Settings_PWM

/*****************
*  Settings_Man  *    screen to change ON/OFF settings
*****************/
void Settings_Man()
{
TCCR1A = 0;     // set PWM pin (12) to normal output
digitalWrite(12, HIGH);   // output off
Test_Mode = 0;
mode = 1;                // Manual mode
myGLCD.InitLCD();        // Landscape
myGLCD.clrScr();
myTouch.InitTouch(LANDSCAPE);
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(255, 170, 0);
myGLCD.setFont(SmallFont);
myGLCD.print("Powder    ON           OFF            ", 5, 3);
myGLCD.print(" Type    Time          Time           ", 6, 15);
myGLCD.print("Delta", 255, 10);
myGLCD.print("Speed", 128, 10);
myGLCD.setFont(Retro8x16);

// Powder types
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 40, 50, 65);
myGLCD.setColor(0, 0, 0);
myGLCD.print("Ball", 11, 46);
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 70, 50, 95);
myGLCD.setColor(0, 0, 0);
myGLCD.print("Flake", 6, 76);
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 100, 50, 125);
myGLCD.setColor(0, 0, 0);
myGLCD.print("S_Stk", 6, 106);
myGLCD.setColor(255, 255, 255);
myGLCD.fillRoundRect (2, 130, 50, 155);
myGLCD.setColor(0, 0, 0);
myGLCD.print("L_Stk", 6, 136);

// ON time boxes
myGLCD.setColor(255, 255, 255);
myGLCD.drawRoundRect (70, 40, 110, 65);
myGLCD.drawRoundRect (70, 70, 110, 95);
myGLCD.drawRoundRect (70, 100, 110, 125);
myGLCD.drawRoundRect (70, 130, 110, 155);

// OFF time boxes
myGLCD.drawRoundRect (182, 40, 222, 65);
myGLCD.drawRoundRect (182, 70, 222, 95);
myGLCD.drawRoundRect (182, 100, 222, 125);
myGLCD.drawRoundRect (182, 130, 222, 155);

// Delta
myGLCD.drawRoundRect (272, 40, 295, 65);
myGLCD.drawRoundRect (262, 70, 295, 95);
myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
myGLCD.drawRoundRect (252, 130, 295, 155);      // debug

// Speeds
myGLCD.setBackColor(0, 0, 0);
myGLCD.setColor(255, 255, 255);
myGLCD.print("Fast", 130, 45);
myGLCD.print("Med", 134, 75);
myGLCD.print("Slo", 134, 105);
myGLCD.print("VSlo", 130, 135);

// Keypad
// Draw the top row of keypad 1 - 6
    for (x=0; x<6; x++)
  {
    myGLCD.setColor(255, 255, 255);
    myGLCD.fillRoundRect (5+(50*x), 175, 45+(50*x), 200);
    myGLCD.setColor(0, 0, 0);
    myGLCD.setBackColor(255, 255, 255);
    myGLCD.printNumI(x+1, 20+(50*x), 182);
  }
// Next row for 7, 8 & 9
    for (x=0; x<3; x++)
  {
    myGLCD.setColor(255, 255, 255);
    myGLCD.fillRoundRect (5+(50*x), 210, 45+(50*x), 235);
    myGLCD.setColor(0, 0, 0);
    myGLCD.printNumI(x+7, 20+(50*x), 217);
  }
// For 0, . & SAVE
    for (x=3; x<6; x++)
    {
    myGLCD.setColor(255, 255, 255);
    myGLCD.fillRoundRect (5+(50*x), 210, 45+(50*x), 235);
    }
    myGLCD.setColor(0, 0, 0);
    myGLCD.printNumI(0, 171, 217);
    myGLCD.print(".", 221, 216);
    myGLCD.print("SAVE", 260, 217);
//
//    Load activ_Pdr from EEPROM
//
   activ_Pdr = EEPROM.read(ep_start_P + 45);
   if ((activ_Pdr < 1) || (activ_Pdr > 4))     // in case there's garbage in this memory location
    activ_Pdr = 0;                             // Set to 0 to indicate Settings required
   show_values_M();

//      Change backcolor of powder type when selected
//
  while(true) {
  if (myTouch.dataAvailable())
    {
      myTouch.read();
      delay(150);
      x = myTouch.getX();
      y = myTouch.getY();
    //
    // Fill the boxes based on the powder type
    // 
   if(Test_Mode == 0)
  {
    if ((x >= 2) && (x <= 50)) {      // Powder column
      if ((y >= 40) && (y <= 65)) {   // Ball
      activ_Pdr = 1;
      show_values_M();
      }

      if ((y >= 70 && y <= 95)) {     // Flake
        activ_Pdr = 2;
       show_values_M();
      }
      
      if ((y >= 100 && y <= 125)) {   // S_Stk
         activ_Pdr = 3;
        show_values_M();
      }

      if ((y >= 130 && y <= 155)) {   // L_Stk
         activ_Pdr = 4;
        show_values_M();       
      }
      EEPROM.update((ep_start_P + 45), activ_Pdr);
    }
//
//      activ_Pdr = The powder type
//      activ_set = The box (ON time, OFF time, or Delta within the powder type set
//
    if ((x >= 70) && (x <= 110)) { 

        if ((y >= 40) && (y <= 65)) {    // Fast ON time
        myGLCD.setColor(255, 255, 0);           // yellow
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 41, 109, 64);
        activ_Set = 1; 
    }
        if ((y >= 70) && (y <= 95)) {      // Med ON time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 71, 109, 94);
        activ_Set = 3;
    }
        if ((y >= 100) && (y <= 125)) {    // Slo ON time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 101, 109, 124);
        activ_Set = 5;
    }
        if ((y >= 130) && (y <= 155)) {       // VSlo ON time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (70, 130, 110, 155);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (70, 40, 110, 65);
        myGLCD.drawRoundRect (70, 70, 110, 95);
        myGLCD.drawRoundRect (70, 100, 110, 125);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (71, 131, 109, 154);
        activ_Set = 7;
    }
    RsetDutyBox();
    RsetDBox(); 
    }
//                                        Change Duty box color
     if ((x >= 182) && (x <= 222)) {
      if ((y >= 40) && (y <= 65)) {                          // Fast OFF time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 41, 221, 64);
        activ_Set = 2; 
    }
      if ((y >= 70) && (y <= 95)) {                          // Med OFF time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 71, 221, 94);
        activ_Set = 4;
    }
      if ((y >= 100) && (y <= 125)) {                        // Slo OFF time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 101, 221, 124);
        activ_Set = 6;
    }
    if ((y >= 130) && (y <= 155)) {                          // VSlo OFF time
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (182, 130, 222, 155);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (182, 40, 222, 65);
        myGLCD.drawRoundRect (182, 70, 222, 95);
        myGLCD.drawRoundRect (182, 100, 222, 125);
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (183, 131, 221, 154);
        activ_Set = 8;
    }
    RsetFBox();
    RsetDBox(); 
    }
//                                              Change Delta box color
    if ((x >= 255) && (x <= 295)) {
      if ((y >= 40) && (y <= 65)) {                          // Fast Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (273, 41, 294, 64);
        activ_Set = 9; 
    }
      if ((y >= 70) && (y <= 95)) {                          // Med Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (263, 71, 294, 94);
        activ_Set = 10;
    }
      if ((y >= 100) && (y <= 125)) {                        // Slow Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (253, 101, 294, 124);      // debug
        activ_Set = 11;
    }
    if ((y >= 130) && (y <= 155)) {                          // V_Slow Delta
        myGLCD.setColor(255, 255, 0);
        myGLCD.drawRoundRect (252, 130, 295, 155);      // debug
        myGLCD.setColor(255, 255, 255);
        myGLCD.drawRoundRect (272, 40, 295, 65);
        myGLCD.drawRoundRect (262, 70, 295, 95);
        myGLCD.drawRoundRect (252, 100, 295, 125);      // debug
        stCount1 = 0;
        myGLCD.setColor(0, 0, 0);
        myGLCD.fillRoundRect (253, 131, 294, 154);      // debug
        activ_Set = 12;
    }
    RsetFBox();
    RsetDutyBox(); 
    }
    if(stCount1 > 3)
      stCount1 = 3;
    if (stCount1 < 4)
    stCurrent1[stCount1+1] = 0;
    delay(200);
    {  myGLCD.setBackColor(0, 0, 0);
      if ((y >= 175) && (y <= 200))      // Top row
      {
        if((x >= 5) && (x <= 45)){       // button 1
          stCurrent1[stCount1++] = '1';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
         }
        if((x >= 55) && (x <= 95)){      // button 2
          stCurrent1[stCount1++] = '2';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        if((x >= 105) && (x <= 145)){    // button 3
          stCurrent1[stCount1++] = '3';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        if((x >= 155) && (x <= 195)){    // button 4
          stCurrent1[stCount1++] = '4';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        if((x >= 205) && (x <= 245)){    // button 5
          stCurrent1[stCount1++] = '5';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        if((x >= 255) && (x <= 295)){    // button 6
          stCurrent1[stCount1++] = '6';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }                              
      }
      if ((y >= 210) && (y <= 235))      // Bottom row
      {
        if((x >= 5) && (x <= 45)){       // button 7
          stCurrent1[stCount1++] = '7';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
         }
        if((x >= 55) && (x <= 95)){      // button 8
          stCurrent1[stCount1++] = '8';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        if((x >= 105) && (x <= 145)){    // button 9
          stCurrent1[stCount1++] = '9';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        if((x >= 155) && (x <= 195)){    // button 0
          stCurrent1[stCount1++] = '0';
          stCurrent1[stCount1] = 0;
          Set_switch_M();
        }
        //
        // Only accept a decimal point for activ_Set 10, 11 or 12 (Med, Slow or VSlo Delta)
        //
        if((x >= 205) && (x <= 245)){    // button .
        if((activ_Set == 10) || (activ_Set == 11) || (activ_Set == 12)){
          stCurrent1[stCount1++] = '.';
          stCurrent1[stCount1] = 0;
          Set_switch_M();}
        }
        //
        // If the SAVE button is pressed the input value is saved in EEPROM.
        // We only allow certain values to be saved. If anyting is out of an
        // aceptable range, it is modified here before it is stored.
        //  
        if((x >= 255) && (x <= 295)){       // SAVE button was pressed
          SetSpdColor();
        /*        
         We only allow certain values to be saved. If anyting is out of an
         aceptable range for the selected box (cell), it is modified here before it is stored.
        
         If activ_Set equals 11 or 12 we need to do a conversion to floating point
         then multiply by 10 and then convert to an integer.
         The saved value for cells 11 or 12 should not be more than 15. If it is
         greater than this - change the value to 15 for a stored maximum value of 1.5 grains. */
          switch (activ_Set)
            {
              case 10:
                temp = (strtod(stCurrent1, &end));               // RICK
                temp = temp * 10.0 + 0.01;                        // RICK
                ev = temp;
                if (ev > 90) ev = 90;
                break; 

              case 11:
              temp = (strtod(stCurrent1, &end));               // RICK
              temp = temp * 100.0 + 0.1;                        // RICK
              ev = temp;
              if (ev > 255) ev = 255;
              break;  

              case 12:
              temp = (strtod(stCurrent1, &end));               // RICK
              temp = temp * 100.0 + 0.1;                        // RICK
              ev = temp;
              if (ev > 255) ev = 255;
              break;  

              default:
              ev = atoi(stCurrent1);
              break;
            }
       /*    if ((activ_Set == 11) || (activ_Set == 12)) {
            temp = (strtod(stCurrent1, &end));       // debug
            temp = temp * 100.0 + 0.1;                            // RICK
            ev = temp; 
             if (ev > 255) ev = 255;}                           // debug
           else {
             ev = atoi(stCurrent1); }     // For any cells other than 11 or 12 do a direct integer conversion */
          /*
           ev now contains an integer value for the selected cell
           Zero is not allowed for a stored value. if ev = 0, it is set to 1
          */
          if (ev == 0) {ev=1;}
          /*
           CHECK THE CELL VALUES BEFORE ACTUALLY STORING THEM SO THEY ARE STORED WITHIN IN A USEFUL RANGE

           The weight from target should not be more than 9 grains for activ_Set values of 9 and 10
           Cell values of 11 and 12 were taken care of above.
          */
          if ((activ_Set == 9) && ev > 9) {ev = 9;}
           if(activ_Set == 9) {ev = ev * 10;}   // Multiply cell value by 10 before storing
      //    if ((activ_Set == 9 || activ_Set == 10) && ev > 9) {ev = 9;}
      //    if(activ_Set == 9 || activ_Set == 10) {ev = ev * 10;}   // Multiply cell values by 10 before storing
          
          /*
            ea becomes the actual EEPROM address where the data is stored for the slected powder type
          */

          ea = (ep_start_M - 100) + ((activ_Pdr - 1) * 24) + ((activ_Set * 2) - 2);
          if(ev > 255)
            EEPROM.update((ea + 1), (highByte(ev)));
            else
            EEPROM.update((ea + 1), 0);

            EEPROM.update(ea, lowByte(ev));
         // ea is the EEPROM address where the data is to be stored
         // ev is the EEPROM value to be stored
          /*
           Set_Switch is called to display the entered value in the selected powder color so the user knows
           that the SAVE button was pressed. NOTE: the actual value saved may be different if the user entered
           a value outside of the range acceptable by the program. The user should re-display the values for
           the selected powder type to see the actual values stored.
          */
          Set_switch_M();
          activ_Set = 0;    //reset Activ_Set to zero
        }     // end of if SAVE button    
        }     // end of if bottom row
      }       // end of keypad entry after delay(200)
    }         // end of if Test_Mode == 0
  
  if (((x >= 5) && (x <= 317)) && ((y >= 3) && (y <= 28)))    // Top header box
  {
    EEPROM.update((ep_start_P + 46), mode);
    show_values_M();    // update timing variables
    setup();
    return(0);
  }

  if (((x >= 125) && (x <= 165)) && ((y >= 37) && (y <= 155)))    //  speed column
   {
    if((Test_Mode == 0) && (myTouch.dataAvailable() == 0))
      Test_Mode = 1;
    if((Test_Mode == 1) && (T_Sel == 1))
      Test_Mode = 0;  
   
    if((Test_Mode == 1) && (myTouch.dataAvailable() == 0)){
      myGLCD.setColor(255, 255, 255);
      if((y >= 37) && (y <= 67) && (T_Sel == 0) && (Test_Mode == 1)){      // Fast speed text block
        Spd = 1;
        T_Sel = 1;        
        myGLCD.print("Test", 130,45);}
      if((y >= 70) && (y <= 95) && (T_Sel == 0) && (Test_Mode == 1)){      // Med speed text block
        Spd = 2;
        T_Sel = 1;       
        myGLCD.print("Test", 130,75);}
      if((y >= 100) && (y <= 125) && (T_Sel == 0) && (Test_Mode == 1)){      // Slo speed text block
        Spd = 3;
        T_Sel = 1;        
        myGLCD.print("Test", 130,105);}
      if((y >= 130) && (y <= 155) && (T_Sel == 0) && (Test_Mode == 1)){      // VSlo speed text block
        Spd = 4;
        T_Sel = 1;        
        myGLCD.print("Test", 130,135);}

      Test_M(Spd);
   }
//    
    if((Test_Mode == 0) && (myTouch.dataAvailable() == 0)){
      SetSpdColor();
      firstPress_M = 0;
      if((y >= 37) && (y <= 67) && (T_Sel == 1) && (Spd == 1) && (Test_Mode == 0)){      // Fast speed text block
        T_Sel = 0;        
        myGLCD.print("Fast", 130, 45);}
      if((y >= 70) && (y <= 95) && (T_Sel == 1) && (Spd == 2) && (Test_Mode == 0)){      // Med speed text block
        T_Sel = 0;       
        myGLCD.print("    ", 130, 75);
        myGLCD.print("Med", 134, 75);}
      if((y >= 100) && (y <= 125) && (T_Sel == 1) && (Spd == 3) && (Test_Mode == 0)){      // Slo speed text block
        T_Sel = 0;        
        myGLCD.print("    ", 130, 105);
        myGLCD.print("Slo", 134, 105);}
      if((y >= 130) && (y <= 155) && (T_Sel == 1) && (Spd == 4) && (Test_Mode == 0)){      // VSlo speed text block
        T_Sel = 0;       
        myGLCD.print("VSlo", 130, 135);}
    }
    }   // end of if press in speed column 
    }   // end of if(mytouchavailable())
  }     // end While (true)
}       // end of Settings_M

/***************
*  Test  (PWM) *      Check to see how powder behaves with duty cycle settings
***************/
void Test_P(int Spd) {

activ_Pdr = EEPROM.read(ep_start_P + 45);
ea = activ_Pdr * 9 + ep_start_P;
Freq = EEPROM.read(ea);
OCR1A = 31250/Freq;
F_Duty = EEPROM.read(ea + 1);
M_Duty = EEPROM.read(ea + 3);
S_Duty = EEPROM.read(ea + 5);
VS_Duty = EEPROM.read(ea + 7);
OCR1B = 0;
digitalWrite(11, LOW);     // disable brake
SetSpdColor();
while(Test_Mode) 
{
  switch (Spd)
  {
    case 1:
      temp = (OCR1A * (F_Duty/100));
      OCR1B = int (temp);
  //    digitalWrite(11, LOW);     // disable brake
      break;

    case 2:
      temp = (OCR1A * (M_Duty/100));
      OCR1B = int (temp);
  //    digitalWrite(11, LOW);     // disable brake
      break;

    case 3:
      temp = (OCR1A * (S_Duty/100));
      OCR1B = int (temp);
  //    digitalWrite(11, HIGH);     // enable brake
      break;

    case 4:
      temp = (OCR1A * (VS_Duty/100));
      OCR1B = int (temp);
  //    digitalWrite(11, HIGH);     // enable brake
      break;
  }

  if (myTouch.dataAvailable())
    {
      myTouch.read();
      delay(150);
      x = myTouch.getX();
      y = myTouch.getY();


  if ((x >= 125) && (x <= 165))       // Speed column
  {
    if((y >= 37) && (y <= 67) && (Spd == 1)){       // Fast text box
      myGLCD.print("Fast", 130,45);
      Test_Mode = 0;
    }
    if ((y >= 70) && (y <= 95) && (Spd == 2)){
      myGLCD.print("    ", 130, 75);
      myGLCD.print("Med", 134, 75);
      Test_Mode = 0;
    }
    if ((y >= 100) && (y <= 125) && (Spd == 3)) {
      myGLCD.print("    ", 130, 105);
      myGLCD.print("Slo", 134, 105);
      Test_Mode = 0;
    }
    if ((y >= 130) && (y <= 155) && (Spd == 4)) { 
      myGLCD.print("VSlo", 130, 135);
      Test_Mode = 0;
    }

  if(Test_Mode == 0){
//  digitalWrite(11, LOW);    // disable brake
  OCR1B = 0;
  return;
  }
  }     // end of if Speed column
    }   // end of if(myTouch.dataAvailable)
}       // end of while
}       // end of Test_P()

/***************
*  Test  (Man) *      Check to see how powder behaves with ON/OFF settings
***************/
void Test_M(int Spd) {
digitalWrite(12, HIGH);   // output off
activ_Pdr = EEPROM.read(ep_start_P + 45);
ea = (ep_start_M - 100) + ((activ_Pdr - 1) * 24);
SetSpdColor();
OnTimeDone = 0;     // without these two initializations
OffTimeDone = 0;    // the first pulse was often longer than it was supposed to be.

  switch(Spd)
  {
    case 1:   //  Fast
    ON_tim = EEPROM.read(ea) + (EEPROM.read(ea+1) * 256);
    OFF_tim = EEPROM.read(ea+2) + (EEPROM.read(ea+3) * 256);
    digitalWrite(11, LOW);     // disable brake
    break;

    case 2:   //  Med
    ON_tim = EEPROM.read(ea+4) + (EEPROM.read(ea+5) * 256);
    OFF_tim = EEPROM.read(ea+6) + (EEPROM.read(ea+7) * 256);
    digitalWrite(11, LOW);     // disable brake
    break;

    case 3:   //  Slo
    ON_tim = EEPROM.read(ea+8) + (EEPROM.read(ea+9) * 256);
    OFF_tim = EEPROM.read(ea+10) + (EEPROM.read(ea+11) * 256);
    digitalWrite(11, HIGH);     // enable brake
    break;

    case 4:   //  VSlo
    ON_tim = EEPROM.read(ea+12) + (EEPROM.read(ea+13) * 256);
    OFF_tim = EEPROM.read(ea+14) + (EEPROM.read(ea+15) * 256);
    digitalWrite(11, HIGH);     // enable brake
    break;
  }
  while(Test_Mode) {

  Init_ON_Time:  
    Start_Time = millis();
    digitalWrite(12, LOW);    // output on
  
  ON_Cont:
    Cur_Time = millis();
    O_period = Cur_Time - Start_Time;
    if (O_period >= ON_tim){
      OnTimeDone = 1;
      OffTimeDone = 0;}
    else
      goto bypass;
  Init_OFF_Time:
    Start_Time = millis();
    digitalWrite(12, HIGH);   // output off
  
  OFF_Cont:
    Cur_Time = millis();
    F_period = Cur_Time - Start_Time;
    if (F_period >= OFF_tim){
      OffTimeDone = 1;
      OnTimeDone = 0;
      goto Init_ON_Time;}
  bypass:
  if (myTouch.dataAvailable())
    {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

  if ((x >= 125) && (x <= 165))       // Speed column
  {
    if((y >= 37) && (y <= 67) && (Spd == 1)){       // Fast text box
      myGLCD.print("Fast", 130,45);
      Test_Mode = 0;
    }
    if ((y >= 70) && (y <= 95) && (Spd == 2)){
      myGLCD.print("    ", 130, 75);
      myGLCD.print("Med", 134, 75);
      Test_Mode = 0;
    }
    if ((y >= 100) && (y <= 125) && (Spd == 3)) {
      myGLCD.print("    ", 130, 105);
      myGLCD.print("Slo", 134, 105);
      Test_Mode = 0;
    }
    if ((y >= 130) && (y <= 155) && (Spd == 4)) { 
      myGLCD.print("VSlo", 130, 135);
      Test_Mode = 0;
    }

  if(Test_Mode == 0){
  digitalWrite(11, LOW);    // disable brake
  digitalWrite(12, HIGH);   // output off
  return;
  }
  }     // end of if Speed column
    }   // end of myTouch.dataAvailable
    if(OnTimeDone == 0)
      goto ON_Cont;
    if(OffTimeDone == 0)
      goto OFF_Cont;
  
}       // end of while(Test_Mode)
}       // end of Test_M()

/*********************
*  Set_Switch  (PWM) *    Select correct box to enter data
*********************/
void Set_switch_P ()
{ 
  switch (activ_Set)
  {
    case 1:
      myGLCD.print(stCurrent1, 84, 46);     // Ball Freq
      break;
    case 2:
      myGLCD.print(stCurrent1, 84, 76);     // Flake Freq
      break;
    case 3:
      myGLCD.print(stCurrent1, 84, 106);    // S_Stk Freq
     break;
    case 4:
      myGLCD.print(stCurrent1, 84, 136);    // L_Stk Freq
      break;
    case 5:
      myGLCD.print(stCurrent1, 195, 46);    // Fast Duty
      break;
    case 7:
      myGLCD.print(stCurrent1, 195, 76);    // Med Duty
      break;
    case 9:
      myGLCD.print(stCurrent1, 195, 106);   // Slo Duty
      break;
    case 11:
      myGLCD.print(stCurrent1, 195, 136);   // VSlo Duty
      break;
    case 6:
      myGLCD.print(stCurrent1, 280, 46);    // Fast Delta
      break;
    case 8:
      myGLCD.print(stCurrent1, 266, 76);    // Med Delta
      break;
    case 10:
      myGLCD.print(stCurrent1, 258, 106);   // Slo Delta      // debug
      break;
    case 12:
      myGLCD.print(stCurrent1, 258, 136);   // VSlo Delta     // debug
      break;
  }
}   // end of Set_switch_P
/*********************
*  Set_Switch  (Man) *    Select correct box to enter data
*********************/
void Set_switch_M()
{ 
  switch (activ_Set)
  {
    case 1:
      myGLCD.print(stCurrent1, 77, 46);     // Fast ON time
      break;
    case 2:
      myGLCD.print(stCurrent1, 188, 46);    // Fast OFF time
      break;
    case 9:
      myGLCD.print(stCurrent1, 280, 46);    // Fast Delta
      break;
    case 3:
      myGLCD.print(stCurrent1, 77, 76);     // Med ON time
      break;
    case 4:
      myGLCD.print(stCurrent1, 188, 76);    // Med OFF time
      break;
    case 10:
      myGLCD.print(stCurrent1, 266, 76);    // Med Delta
      break;
    case 5:
      myGLCD.print(stCurrent1, 77, 106);    // Slo ON time
     break;
    case 6:
      myGLCD.print(stCurrent1, 188, 106);   // Slo OFF time
      break;
    case 11:
      myGLCD.print(stCurrent1, 258, 106);   // Slo Delta      // debug
      break;
    case 7:
      myGLCD.print(stCurrent1, 77, 136);    // VSlo ON time
      break;
    case 8:
      myGLCD.print(stCurrent1, 188, 136);   // VSlo OFF time
      break;
    case 12:
      myGLCD.print(stCurrent1, 258, 136);   // VSlo Delta     // debug
      break;
  }
}      // end Set_switch_M

/*********************
*  SHOW_VALUES (PWM) *
*********************/
  void show_values_P (){
//
//  This code displays the parameters from EEPROM into the FREQ/FAST/MED/SLO/VSLO 
//  boxes for the selected powder type
//
//  There are 9 parameters for each powder type:
//     1 for frequency
//     2 each for FAST/MED/SLO/VSLO powder (Duty & Wt from target)
//     this results in 9*4 or 36 EEPROM storage locations in total.
//
//    Code only needs to know the value of activ_Pdr to fill in the boxes
//
    if (activ_Pdr == 1) {             // BALL Powder type - Use GREEN color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 255, 0);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 40, 50, 65);  // Ball
    myGLCD.setBackColor(0, 255, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("Ball", 11, 46);
    
    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 70, 50, 95);    // Flake
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Flake", 6, 76);
    myGLCD.print("S_Stk", 6, 106);
    myGLCD.print("L_Stk", 6, 136);
    myGLCD.setBackColor(0, 0, 0);          // BLACK background
    myGLCD.setColor(255, 255, 255);        // WHITE characters
    myGLCD.print("-- ", 84, 76);
    myGLCD.print("-- ", 84, 106);
    myGLCD.print("-- ", 84, 136);
    ea = activ_Pdr * 9 + ep_start_P;
    ex = EEPROM.read (ea);                 // Read Freq
    if (ex < 100) {
    myGLCD.printNumI(ex, 84, 46, 2); }     // Display BALL frequency
   }

    if (activ_Pdr == 2) {             // FLAKE Powder type - Use CYAN color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 255, 255);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 70, 50, 95);   // FLAKE
    myGLCD.setBackColor(0, 255, 255);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("Flake", 6, 76);

    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 40, 50, 65);    // Ball
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Ball", 11, 46);
    myGLCD.print("S_Stk", 6, 106);
    myGLCD.print("L_Stk", 6, 136);
    myGLCD.setBackColor(0, 0, 0);          // BLACK Background
    myGLCD.setColor(255, 255, 255);        // WHITE characters
    myGLCD.print("-- ", 84, 46);
    myGLCD.print("-- ", 84, 106);
    myGLCD.print("-- ", 84, 136);
    ea = activ_Pdr * 9 + ep_start_P;
    ex = EEPROM.read (ea);                 // Read Freq
    if (ex < 100) {
    myGLCD.printNumI(ex, 84, 76, 2); }     // Display FLAKE frequency
   }

    if (activ_Pdr == 3) {             // S_Stk Powder type - Use YELLOW color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(255, 255, 0);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.setBackColor(255, 255, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("S_Stk", 6, 106);
    
    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 40, 50, 65);    // Ball
    myGLCD.fillRoundRect (2, 70, 50, 95);    // Flake
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Ball", 11, 46);
    myGLCD.print("Flake", 6, 76);
    myGLCD.print("L_Stk", 6, 136);
    myGLCD.setBackColor(0, 0, 0);          // BLACK background
    myGLCD.setColor(255, 255, 255);        // WHITE characters
    myGLCD.print("-- ", 84, 46);
    myGLCD.print("-- ", 84, 76);
    myGLCD.print("-- ", 84, 136);
    ea = activ_Pdr * 9 + ep_start_P;
    ex = EEPROM.read (ea);                 // Read Freq
    if (ex < 100) {
    myGLCD.printNumI(ex, 84, 106, 2); };   // Display S_STK frequency
   }

    if (activ_Pdr == 4) {             // L_Stk Powder type - Use RED color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(255, 51, 51);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 51, 51);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("L_Stk", 6, 136);

    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 40, 50, 65);    // Ball
    myGLCD.fillRoundRect (2, 70, 50, 95);    // Flake
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Ball", 11, 46);
    myGLCD.print("Flake", 6, 76);
    myGLCD.print("S_Stk", 6, 106);
    myGLCD.setColor(255, 255, 255);
    myGLCD.setBackColor(0, 0, 0);          // BLACK background
    myGLCD.setColor(255, 255, 255);        // WHITE characters
    myGLCD.print("-- ", 84, 46);
    myGLCD.print("-- ", 84, 76);
    myGLCD.print("-- ", 84, 106);
    ea = activ_Pdr * 9 + ep_start_P;
    ex = EEPROM.read (ea);                 // Read Freq
    if (ex < 100) {
    myGLCD.printNumI(ex, 84, 136, 2); }    // Display L_STK frequency
   }
   Freq = ex; 
//
// Make all Duty and Weight (Delta) boxes outlined in WHITE
//
RsetDutyBox ();
RsetDBox ();
//
//  The following code reads the stored values from EEPROM for the
//  selected powder type/speed and displays it for the user.
//
        
         ex = EEPROM.read (ea+1);         // FAST(Duty) Address
         F_Duty = ex;  
         myGLCD.printNumI(ex,195,46,3);

         ex = EEPROM.read (ea+2);         // FAST(Wt) Address
         ex = ex/10;
         myGLCD.printNumI(ex, 280, 46, 1);
         
         ex = EEPROM.read (ea+3);         // Med(Duty) Address
         M_Duty = ex;      
         myGLCD.printNumI(ex, 195, 76, 3); 
         
         ex = EEPROM.read (ea+4);         // Med(Wt) Address
         Delta = ex;
         Delta = Delta/10.0;
        myGLCD.printNumF(Delta, 1, 266, 76, '.', 3);
         
         ex = EEPROM.read (ea+5);         // Slo(Duty) Address
         S_Duty = ex;    
         myGLCD.printNumI(ex, 195, 106, 3);
         
         ex = EEPROM.read (ea+6);         // Slo(Wt) Address
         Delta = ex;
         Delta = Delta/100.0;             // debug
         myGLCD.printNumF(Delta, 2, 258, 106, '.', 3);      // debug
         
         ex = EEPROM.read (ea+7);         // VSlo(Duty) Address 
         VS_Duty = ex;   
         myGLCD.printNumI(ex, 195, 136, 3);
         
         ex = EEPROM.read (ea+8);         // VSlo(Wt) Address
         Delta = ex;
         Delta = Delta/100.0;             // debug
         myGLCD.printNumF(Delta, 2, 258, 136, '.', 3);      // debug
  }       // end show_values_P

/*********************
*  SHOW_VALUES (Man) *
*********************/
  void show_values_M (){
//
//  This code displays the parameters from EEPROM into the ON time,OFF time & Delta boxes 
//  for the selected powder type and speed.
//
//  There are 12 parameters for each powder type:
//     3 each for FAST/MED/SLO/VSLO speed (ON time, OFF time & Delta)
//     this results in potentially 20*4 or 80 EEPROM storage locations in total.
//     if numbers are above 255, highbyte storage is necessary.
//     These start at 4000 and go backward.
//
//    Code only needs to know the value of activ_Pdr to fill in the boxes
//
  if(T_Sel == 0){
    if (activ_Pdr == 1) {             // BALL Powder type - Use GREEN color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 255, 0);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 40, 50, 65);  // Ball
    myGLCD.setBackColor(0, 255, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("Ball", 11, 46);
    
    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 70, 50, 95);    // Flake
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Flake", 6, 76);
    myGLCD.print("S_Stk", 6, 106);
    myGLCD.print("L_Stk", 6, 136);
 }
    if (activ_Pdr == 2) {                    // FLAKE Powder type - Use CYAN color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(0, 255, 255);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 70, 50, 95);   // FLAKE
    myGLCD.setBackColor(0, 255, 255);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("Flake", 6, 76);

    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 40, 50, 65);    // Ball
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Ball", 11, 46);
    myGLCD.print("S_Stk", 6, 106);
    myGLCD.print("L_Stk", 6, 136);
 }
    if (activ_Pdr == 3) {                    // S_Stk Powder type - Use YELLOW color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(255, 255, 0);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.setBackColor(255, 255, 0);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("S_Stk", 6, 106);
    
    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 40, 50, 65);    // Ball
    myGLCD.fillRoundRect (2, 70, 50, 95);    // Flake
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Ball", 11, 46);
    myGLCD.print("Flake", 6, 76);
    myGLCD.print("L_Stk", 6, 136);
 }
    if (activ_Pdr == 4) {                    // L_Stk Powder type - Use RED color
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.setColor(255, 51, 51);
    myGLCD.print("Fast", 130, 45);
    myGLCD.print("Med", 134, 75);
    myGLCD.print("Slo", 134, 105);
    myGLCD.print("VSlo", 130, 135);
    myGLCD.fillRoundRect (2, 130, 50, 155);  // L_Stk
    myGLCD.setBackColor(255, 51, 51);
    myGLCD.setColor(0, 0, 0);
    myGLCD.print("L_Stk", 6, 136);

    myGLCD.setColor(255, 255, 255);          // WHITE rectangles for:
    myGLCD.fillRoundRect (2, 40, 50, 65);    // Ball
    myGLCD.fillRoundRect (2, 70, 50, 95);    // Flake
    myGLCD.fillRoundRect (2, 100, 50, 125);  // S_Stk
    myGLCD.setBackColor(255, 255, 255);      // WHITE Background
    myGLCD.setColor(0, 0, 0);                // BLACK Letters
    myGLCD.print("Ball", 11, 46);
    myGLCD.print("Flake", 6, 76);
    myGLCD.print("S_Stk", 6, 106);
 }
    myGLCD.setBackColor(0, 0, 0);            // BLACK background
//
// Make all OFF time and Weight (Delta) boxes outlined in WHITE
//
    RsetDutyBox ();
    RsetDBox ();
//
//  The following code reads the stored values from EEPROM for the
//  selected powder type/speed and displays it for the user.
//
         ea = (ep_start_M - 100) + ((activ_Pdr - 1) * 24);

         ex = EEPROM.read (ea);            // FAST ON time address
         ex1 = EEPROM.read (ea+1);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
         F_ON = ex;
         myGLCD.printNumI(ex, 77, 46, 4);

         ex = EEPROM.read (ea+2);         // FAST OFF time Address
         ex1 = EEPROM.read (ea+3);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
         F_OFF = ex;
         myGLCD.printNumI(ex,188,46,4);
         
         ex = EEPROM.read (ea+16);         // FAST Delta Address
         ex = ex/10;
         F_Delta = ex;
         myGLCD.printNumI(ex, 280, 46, 1);

         ex = EEPROM.read (ea+4);         // Med ON time Address
         ex1 = EEPROM.read (ea+5);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
          M_ON = ex;
         myGLCD.printNumI(ex, 77, 76, 4);

         ex = EEPROM.read (ea+6);         // Med OFF time Address
         ex1 = EEPROM.read (ea+7);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
          M_OFF = ex;
         myGLCD.printNumI(ex, 188, 76, 4); 
         
         ex = EEPROM.read (ea+18);         // Med Delta Address
         Delta = ex;
         Delta = Delta/10.0;
         M_Delta = Delta;
         myGLCD.printNumF(Delta, 1, 266, 76, '.', 3);      // debug
    //     ex =ex/10;
    //     M_Delta = ex;
     //    myGLCD.printNumI(ex, 267, 76, 2);
         
         ex = EEPROM.read (ea+8);         // Slo ON time Address
         ex1 = EEPROM.read (ea+9);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
          S_ON = ex;
         myGLCD.printNumI(ex, 77, 106, 4);

         ex = EEPROM.read (ea+10);         // Slo OFF time Address
         ex1 = EEPROM.read (ea+11);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
          S_OFF = ex;
         myGLCD.printNumI(ex, 188, 106, 4);

         ex = EEPROM.read (ea+20);         // Slo Delta Address
         Delta = ex;
         Delta = Delta/100.0;             // debug
         S_Delta = Delta;
         myGLCD.printNumF(Delta, 2, 258, 106, '.', 3);      // debug
         
         ex = EEPROM.read (ea+12);         // VSlo ON time Address
         ex1 = EEPROM.read (ea+13);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
          VS_ON = ex;
         myGLCD.printNumI(ex, 77, 136, 4);

         ex = EEPROM.read (ea+14);         // VSlo OFF time Address
         ex1 = EEPROM.read (ea+15);
          if(ex1 > 0)
            ex = (ex1 * 256) + ex;
          VS_OFF = ex;
         myGLCD.printNumI(ex, 188, 136, 4);
         
         ex = EEPROM.read (ea+22);         // VSlo Delta Address
         Delta = ex;
         Delta = Delta/100.0;             // debug
         VS_Delta = Delta;
         myGLCD.printNumF(Delta, 2, 258, 136, '.', 3);      // debug
  }
}     // end show_values_M

/*****************
*  GetEE_data_M  *
*****************/
void GetEE_data_M ()
{
  ea = (ep_start_M - 100) + ((activ_Pdr - 1) * 24);

  ex = EEPROM.read (ea);            // FAST ON time address
  ex1 = EEPROM.read (ea+1);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  F_ON = ex;

  ex = EEPROM.read (ea+2);         // FAST OFF time Address
  ex1 = EEPROM.read (ea+3);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  F_OFF = ex;
         
  ex = EEPROM.read (ea+16);         // FAST Delta Address
  ex = ex/10;
  F_Delta = ex;
  
  ex = EEPROM.read (ea+4);         // Med ON time Address
  ex1 = EEPROM.read (ea+5);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  M_ON = ex;

  ex = EEPROM.read (ea+6);         // Med OFF time Address
  ex1 = EEPROM.read (ea+7);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  M_OFF = ex;
         
  ex = EEPROM.read (ea+18);         // Med Delta Address
  Delta = ex;
  Delta = Delta/10.0;
  M_Delta = Delta;
 // ex =ex/10;
//  M_Delta = ex;
         
  ex = EEPROM.read (ea+8);         // Slo ON time Address
  ex1 = EEPROM.read (ea+9);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  S_ON = ex;
 
  ex = EEPROM.read (ea+10);         // Slo OFF time Address
  ex1 = EEPROM.read (ea+11);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  S_OFF = ex;
  
  ex = EEPROM.read (ea+20);         // Slo Delta Address
  Delta = ex;
  Delta = Delta/100.0;              // debug
  S_Delta = Delta;
         
  ex = EEPROM.read (ea+12);         // VSlo ON time Address
  ex1 = EEPROM.read (ea+13);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  VS_ON = ex;
  
  ex = EEPROM.read (ea+14);         // VSlo OFF time Address
  ex1 = EEPROM.read (ea+15);
    if(ex1 > 0)
      ex = (ex1 * 256) + ex;
  VS_OFF = ex;
         
  ex = EEPROM.read (ea+22);         // VSlo Delta Address
  Delta = ex;
  Delta = Delta/100.0;              // debug
  VS_Delta = Delta;
}
  // end of GetEE_data_M

S'lotta code there.

You shoukd for yourself as well as for presentation learn how to bake away the elements of the issue and write an MRE.

In this context a "minimal repeatable example" that would be a very short yet complete sketch that illustrates the problem. Something about time and millis() not working somewhere near the bottom of 4042 lines of code is easier to talk about when it's a 40 line program doing or not doing the same thing.

I find many times that in trying to create an MRE to show the heavies here, I come across the dumb mistake(s) I made, often with herrings of the reddest kind showing themsleves.

a7

You could probably shorten this by 2000 lines (from 2800) with the use of functions for redundant code and arrays for changing values. I bet you could write this with under 500 lines.

Do you intend "+" and "-" to go in the same direction? I would consider them opposite.

      case '+':
        strStart = 1;
        input_pos = 0;
        input_line[input_pos++] = inByte;
        break;

      case '-':
        strStart = 1;
        input_pos = 0;
        input_line[input_pos++] = inByte;
        break;

We all started as newbies. For many of us that was long ago.

Reading serial without blocking other execution, complete tutorial including use of a state machine.

How to not wait for serial to arrive.

Nick's tutorial on non-blocking code, the Intro Lesson on How to do multiple things at once.

I was using the + and - to trigger the start of building the measurement string. I add numbers and a decimal point and ignore everything else since they are not needed.

Any suggestions/comments about my millis problem?

Suggest that you see how it's done and then decide if that's not fast enough. Lesson links in post #9.

Consider that a non-blocking coded loop() will run many times before 1 char ( start bit + 8 data bits + stop bit = 10 bits transmitted) gets transferred and Arduino catches that, even at 115200 baud that is slow if your code doesn't block execution. You really do not need to add interrupts to keep up with Serial even while doing other (reasonable) processing.
Using non-blocking code you can cleanly run multiple tasks effectively at the same time (interleaved 10's of times per millisecond) on a single thread. Those two lessons show how and tell why but you got to run the code to see it.

You coded them the same. You can't differentiate them.

I Guess I meant + or -. Either one will start building the string.

@ard_nov

Do you understand the issue in your code I note?

I guess I don’t.

I'm not sure what xfpd is getting at, but an issue that I see in that part of the code is that the following statements (in the default case) can be executed when input_pos == MAX_INPUT:

          input_line[input_pos++] = inByte;
          input_line[input_pos] = NULL;

Since the array declaration is

static char input_line[MAX_INPUT];

it seems to me that you may be writing out-of-bounds, which may be the source of your other issues.

Edited to delete:

Also, you seem to be resetting the array (strStart = 0) after processing each character, which doesn't make sense, unless you're always reading only a single significant digit.

If you want them to do the same exact thing in both cases, you could simplify it for both understanding and writing like:

      case '+':
      case '-':
        strStart = 1;
        input_pos = 0;
        input_line[input_pos++] = inByte;
        break;

I'm wondering if xfpd meant doing this instead

case ('+' | '-'):

Edit: Don't know why 'case' is red here, it's not in the .ino.

strStart = 0 is within the else condition when there are no more characters needed/wanted.

You can't put expressions in the case statement.

However Gnu gcc has a non-standard extension that lets you specifiy a range of consecutive series: case 7 ... 10: