Remote inc coolant nozzle control program

Dependencies:   mbed reScale USBDevice

Dependents:   Nozzle_inputs Nozzle_display

main.cpp

Committer:
BETZtechnik
Date:
2019-10-06
Revision:
17:83cb3b5c69de
Parent:
16:1e974964272e

File content as of revision 17:83cb3b5c69de:

#include "mbed.h"
#include "Adafruit_ST7735.h"
#include "RPG.h"
#include "reScale.h"
#include "Ee24xx08.h"
#include "mRotaryEncoder.h"


// DISPLAY INIT:

#define BLACK    0x0000
#define BLUE     0x001F
#define RED      0xF800
#define GREEN    0x07E0
#define CYAN     0x07FF
#define MAGENTA  0xF81F
#define YELLOW   0xFFE0
#define WHITE    0xFFFF

/* EEPROM Memory map:

1 - 50: N1 angles
51 - 100: Settings
101- 150: N2 angles
151- 200: Twitch settings
200- 250: unused
*/

#define currentToolAddress 51
#define numToolsAddress 52
#define numNozAddress 53
#define versionAddress 54 // 0= basic, 1=pro
#define syncAddress 55
#define n1DirAddress 56
#define n2DirAddress 57
#define autoModeAddress 58   // 
#define aux2ModeAddress 59


//DigitalOut myled(P1_13);


I2C iic(P0_5, P0_4);


DigitalOut dir(P0_21);


Ee24xx08 eeprom(&iic);

Adafruit_ST7735 tft(P0_9, P0_8, P0_6, P0_2, P0_22, P0_7); // MOSI, MISO, SCLK, SSEL, TFT_DC, TFT_RST

int maxServo = 2500;
int minServo = 500;
reScale servo1Scale(-90,90,minServo,maxServo); //

PwmOut myServo(P1_13); //display board
//PwmOut myServo(D4);

//DigitalIn tUpButton(P2_11);
//DigitalIn tDownButton(P2_12);
DigitalIn encoderFalseButton(P0_23); // FALSE!!! push button of knob
DigitalIn encoderButton(P0_20); // push button of knob
DigitalIn backButton(P0_15); // back button
DigitalIn aButton(P0_1); // ISP and A button

Timer t;
Timer tw;
int lastBackButton;
int lastDownButton;
int lastEncoderButton;
int encoderPressed =0; // flag for state
int encoderPressedTime= 0;

int encoderMove = 0;

int dirt = 0;

int main()
{

// ************************************** SCREEN INIT *************************************************

    tft.initR(INITR_GREENTAB);   // initialize a ST7735S chip, black tab

    tft.setRotation(3);
    tft.fillScreen(BLACK);
    tft.setCursor(30,120);
    tft.setTextColor(BLUE);
    tft.setTextWrap(false);
    tft.printf("AccuBlast v1.4");

    tft.setCursor(4, 4);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.printf("N1");

    tft.setCursor(80, 4);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.printf("N2");

    tft.setCursor(4, 28);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.printf("T");

    tft.setCursor(4, 50);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("Twitch:");

    tft.setCursor(4, 65);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("Sync:");

    tft.setCursor(4, 80);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("AUTO:");

    tft.setCursor(4, 95);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("IN2mode:");

    tft.setCursor(4, 110);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("AUX 3:");

    tft.setCursor(75, 95);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("Num Tls");

    tft.setCursor(75, 110);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("Num Noz");

    tft.setCursor(75, 50);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("N1 dir:");

    tft.setCursor(75, 65);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("N2 dir:");

    tft.setCursor(75, 80);
    tft.setTextColor(WHITE);
    tft.setTextSize(1);
    tft.printf("version:");

// **************************************************************************************************************
    int version = 0; // 0= basic, 1=pro
    int lastVersion = 99;

    int sync = 0;  // sync setting for N1 and N1
    int lastSync = 99;
    int syncSpread = 0;
    int syncFlag =0; ///// for count/ sync = 2 issue. 2019-09-11

    int n1Dir = 0; // direction of knob for N1
    int lastN1Dir = 99;

    int n2Dir = 0;  // direction of knob for N2
    int lastN2Dir = 99;
    
    int autoMode = 0;
    int lastAutoMode = 99;
    
        int aux2Mode = 0;
    int lastAux2Mode = 99;

    int index = 0;

    int count = 0;
    int maxCount = 12; //max number of menu items
    int lastCount = 99;

    int twitch = 0;
    int lastTwitch = 300;
    int lastTwitchMove = 0;
    int twitchStart = 0; // has twitching begun?
    int twitchDirection = 0; // 0 is up, 1 is down.
    int maxTwitch = 0;
    int minTwitch = 0;
    int twitchHold = 0; //marker for hold message recieved from Inputs board.

    int tw1 = 5; // stages of servo write to control speed of sweep. 11.11 Ms = 1 degree
    int tw2 = 10;
    int tw3 = 15;

    int twReadMs = 100; // interval of twitch changes us.

    //************* Pull previous setting from eeprom *******************

    char tempToolNo = 0;                  // last tool in spindle
    eeprom.read(currentToolAddress, &tempToolNo);
    int currentToolNo = (int)tempToolNo;

    char tempNumTools = 0;                  // number of tools in ATC
    eeprom.read(numToolsAddress, &tempNumTools);
    int numTools = (int)tempNumTools;

    char tempNumNoz = 0;                  // number of nozzles installed
    eeprom.read(numNozAddress, &tempNumNoz);
    int numNoz = (int)tempNumNoz;

    char tempLastAngle = 0;                  // last angle of last tool in spindle N1
    eeprom.read(currentToolNo, &tempLastAngle);
    int lastAngle = (int)tempLastAngle;
    lastAngle = lastAngle - 90;              // Not storing signed int, so signed value is 45 less than what was stored to memory.

    char tempLastAngleN2 = 0;                  // last angle of last tool in spindle
    eeprom.read(currentToolNo+100, &tempLastAngleN2);
    int lastAngleN2 = (int)tempLastAngleN2;
    lastAngleN2 = lastAngleN2 - 90;              // Not storing signed int, so signed value is 45 less than what was stored to memory.

    char tempLastTwitch = 0;                  // last Twitch setting for the current tool in spindle
    eeprom.read(currentToolNo + 150, &tempLastTwitch);
    twitch = (int)tempLastTwitch;     // should be 1, 2 or 3.

    char tempLastVersion = 0;   // version of system. 0=basic, 1=pro
    eeprom.read(versionAddress, &tempLastVersion);
    version = (int)tempLastVersion;

    char tempLastSync = 0;   // previous sync setting
    eeprom.read(syncAddress, &tempLastSync);
    sync = (int)tempLastSync;

    char tempLastN1Dir = 0;   // previous N1 knob direction setting
    eeprom.read(n1DirAddress, &tempLastN1Dir);
    n1Dir = (int)tempLastN1Dir;

    char tempLastN2Dir = 0;   // previous N2 knob direction setting
    eeprom.read(n2DirAddress, &tempLastN2Dir);
    n2Dir = (int)tempLastN2Dir;

    char tempLastAuto = 0;   // previous N2 knob direction setting
    eeprom.read(autoModeAddress, &tempLastAuto);
    autoMode = (int)tempLastAuto;
    
        char tempLastAux2 = 0;   // previous N2 knob direction setting
    eeprom.read(aux2ModeAddress, &tempLastAux2);
    aux2Mode = (int)tempLastAux2;


    /*EEprom test over 2 digits:
    int test1 = 150;
    eeprom.write(199, test1);
    wait(1);
    char tempN2char = 0;
    eeprom.read(199, &tempN2char);
    int tempN2 = (int)tempN2char;
          tft.setCursor(130,120);
          tft.setTextColor(RED);
          tft.setTextSize(1);
          tft.printf("%d", tempN2);
    */


    //******************** Button debounce *********************************



    backButton.mode(PullUp);     // button pull up
//tDownButton.mode(PullUp);     // button pull up
    encoderButton.mode(PullUp);
    encoderFalseButton.mode(PullUp);
    aButton.mode(PullUp);

    t.start();                   // starts timer
    lastBackButton = t.read_ms();
    lastDownButton = t.read_ms();
    lastEncoderButton =  t.read_ms();
    encoderPressedTime= t.read_ms();

//****************************************************************************

    int lastToolNo = 99;
    int lastNumTools = -1; // trigger to write eeprom value for number of tools

    int lastNumNoz = 0; //trigger display for number of nozzles after startup

    int n1Pos = lastAngle;                 //Set servo to last known postition prior to power off
    int lastN1Pos = 150;

    int n2Pos = lastAngleN2;
    int lastN2Pos = 150;

    int servo1Pos = 0;


//  RPG rpg1(P2_2,P1_20,P0_23);  //  RPG (PinName pA, PinName pB, PinName pPB)P0_23 is unconnected!! ;
//mRotaryEncoder Enc(P2_2,P1_20,P0_23, PullUp, 500);
    mRotaryEncoder Enc(P1_20,P2_2,P0_23, PullUp, 1000);

    myServo.period_ms(20);

    /*
          char t1Ang = 200;
          char t1Read = 0;

          eeprom.write(1, t1Ang);
          wait(1);
          eeprom.read(1, &t1Read);


      tft.setCursor(30,110);
      tft.setTextColor(WHITE);
      tft.setTextWrap(true);
      // tft.printf("%s\r\n",t1Read);
              tft.printf("%d", currentTool);
        */

    uint8_t c = 0; // for 485 link


    int serialToolNumber = 0;
    int stage = 0;   // for serial parsing
    int Tens = 0;
    int Ones = 0;

    dir = 0;

    wait(2);
    Serial device(P0_14, P0_13, 19200);  // RS 485  TX RX?

    while(1) {



        /*
        while (device.readable())
             {
                c = device.getc();


                if (c == '+'){
                 currentToolNo = currentToolNo +1;
                  if (currentToolNo > numTools){
                      currentToolNo = 1;
                      }
                      }

                      else if (c == '-'){
                          currentToolNo = currentToolNo - 1;
                          if (currentToolNo > 1){
                              currentToolNo = numTools;
                              }
                              }
                 }
         */

        /*
        while (device.readable())
                {


                   c = device.getc();

                   if (c == 'M'){
                             // stage = 1;

                                 c = device.getc();
                                 if (c == '+'){

                                // tft.setTextColor(WHITE);
                    //  tft.setCursor(100, 100);
                      // tft.printf("%d", c);
                                 currentToolNo = currentToolNo +1;
                     if (currentToolNo > numTools){
                         currentToolNo = 1;
                          }
                          }

                          else if (c == '-'){
                            currentToolNo = currentToolNo - 1;
                             if (currentToolNo < 1){
                                 currentToolNo = numTools;
                                 }
                                 }

                       }
                       }

                    */



//myled = 1;

        if (t.read() > 1200) {             // timer can only hold 30 min, so reset after 20
            t.reset();
            lastBackButton = t.read_ms();
            lastDownButton = t.read_ms();
            lastEncoderButton = t.read_ms();
        }



        if (backButton == 0) { //Back button was pressed so back to default selection
            count = 0;
        }

// ************************* encoder button
        if (encoderButton == 0 && encoderPressed == 0 && (t.read_ms() > (lastEncoderButton + 200))) {
            encoderPressed = 1;
            encoderPressedTime = t.read_ms();
            }
      
              if (encoderButton == 0 && encoderPressed == 1 && (t.read_ms() < (encoderPressedTime + 20))) {
            count = count + 1;  //Reset count if PB pressed
            lastEncoderButton = t.read_ms();
            encoderPressed = 0;
            }
            
            if (encoderButton == 1 && encoderPressed == 1 && (t.read_ms() < (encoderPressedTime + 10))) {
            encoderPressed = 0;
            }   
            
            
            if (count > maxCount) {
                count = 0;
            }

            if (count > maxCount) {
                count = 0;
            }
        



// ******************************
/*
        if (encoderButton == 0) {
            if (t.read_ms() > (lastEncoderButton + 50)) { // from 200
                count = count + 1;  //Reset count if PB pressed
            }
            if (count > maxCount) {
                count = 0;
            }
            lastEncoderButton = t.read_ms();

            if (count > maxCount) {
                count = 0;
            }
        }
  */      
//************************************

//****************************************************************************************

        if (version == 0) { //Basic runs the servo direct from the display unit
            if (twitch == 0) {
                tw.stop();
                twitchStart = 0;
                twitchDirection = 0;
                servo1Pos = servo1Scale.from(n1Pos);
            }

            if (twitch > 0) {
                if (twitchStart == 0) {
                    tw.start();  // start timer for nozzle sweep
                    servo1Pos = servo1Scale.from(n1Pos);
                    lastTwitchMove = tw.read_ms(); // store time of last nozzle movement
                    minTwitch = servo1Pos; // store original servo postion for bottom of sweep
                    maxTwitch = servo1Pos + 1000; // 11.11mS per degree of sweep, 55 = 5 degrees of sweep. This should be a viariable set on the display.
                    twitchStart = 1;
                }
                if ((twitchStart == 1) && (tw.read_ms() > (lastTwitchMove + twReadMs))) {
                    if (twitchDirection == 0) { //going up
                        servo1Pos = servo1Pos + 100; // add variable amount of uS to the servo signal

                        tft.setCursor(130,120);
                        tft.setTextColor(RED);
                        tft.setTextSize(1);
                        tft.printf("%d", servo1Pos);


                        if (servo1Pos > maxServo) {
                            servo1Pos = maxServo;
                            twitchDirection = 1; //reverse direction
                        }
                        if (servo1Pos > maxTwitch) {
                            servo1Pos = maxTwitch;
                            twitchDirection = 1; //reverse direction
                        }
                        lastTwitchMove = tw.read_ms();
                    }

                    if (twitchDirection == 1) { // going down
                        servo1Pos = servo1Pos - 100; // add variable amount of Ms to the servo signal
                        if (servo1Pos < minServo) {
                            servo1Pos = minServo;
                            twitchDirection = 0; //reverse direction
                        }
                        if (servo1Pos < minTwitch) {
                            servo1Pos = minTwitch;
                            twitchDirection = 0; //reverse direction
                        }
                        lastTwitchMove = tw.read_ms();
                    }
                }
            }

            myServo.pulsewidth_us(servo1Pos);
        }


//********************** update display values **********************************************


        if (currentToolNo != lastToolNo) {
            /*
             tft.fillRect(103, 2, 55,25, BLACK);
             tft.setCursor(105, 4);
             */
            tft.setCursor(22, 28);
            tft.setTextColor(BLACK);
            tft.setTextSize(2);
            tft.printf("%d", lastToolNo);
            tft.setTextColor(WHITE);
            //tft.setTextSize(2);
            // tft.printf("T");
            tft.setCursor(22,28);
            tft.printf("%d", currentToolNo);

            tempLastAngle = 0;
            eeprom.read(currentToolNo, &tempLastAngle);
            lastAngle = (int)tempLastAngle;
            lastAngle = lastAngle - 90;                       // Not storing signed int, so signed value is 90 less than what was stored to memory.
            n1Pos = lastAngle;

            tempLastAngleN2 = 0;
            eeprom.read(currentToolNo+100, &tempLastAngleN2);
            int lastAngleN2 = (int)tempLastAngleN2;
            lastAngleN2 = lastAngleN2 - 90;              // Not storing signed int, so signed value is 45 less than what was stored to memory.
            n2Pos = lastAngleN2;

            if (count == 0) { // if knob is on N1 adjust and ATC changes tools, update enc value)
                Enc.Set(n1Pos);    // test for ATC following issue!
            }

            eeprom.write(currentToolAddress, currentToolNo);
            wait(0.1);
            tempLastTwitch = 0;
            eeprom.read(currentToolNo + 150, &tempLastTwitch); // pull up previous twitch setting.
            twitch = (int)tempLastTwitch;
            lastToolNo = currentToolNo;
        }


        if (n1Pos != lastN1Pos) {
            tft.setCursor(40, 4);
            tft.setTextColor(BLACK);
            tft.setTextSize(2);
            tft.printf("%d", lastN1Pos);
            tft.setCursor(40,4);
            tft.setTextColor(GREEN);
            tft.setTextSize(2);
            tft.printf("%d", n1Pos);
            eeprom.write(currentToolNo, n1Pos + 90);        // store new angle in eeprom, add 90 because its an unsigned value.
            //wait(0.1); // adjusted from 1
            dir=1;
            device.printf("N");
            device.printf("%d", n1Pos + 190); //send over RS485 add 190 so no negative values and always 3 digits.
            //device.printf("N245");  // TEST!!!
            // tft.setCursor(100, 50);
            //  tft.setTextSize(2);
            // tft.printf("%d", n1Pos + 145);
            wait(0.05);
            dir=0;

            //Enc.Set(n1Pos); // test!!

            lastN1Pos = n1Pos;
            syncFlag =1; // set the flag after lastN1Pos has run once to allow REV sync setting in count ==0 2019-09-11
        }

        if (n2Pos != lastN2Pos && numNoz == 2) {
            tft.setCursor(115, 4);
            tft.setTextColor(BLACK);
            tft.setTextSize(2);
            tft.printf("%d", lastN2Pos);
            tft.setCursor(115, 4);
            tft.setTextColor(GREEN);
            tft.setTextSize(2);
            tft.printf("%d", n2Pos);
            eeprom.write(currentToolNo +100, n2Pos + 90);        // store new angle in eeprom, add 90 because its an unsigned value.
            //wait(0.1); // adjusted from 1
            dir=1;
            device.printf("N");
            device.printf("%d", n2Pos + 390); //send over RS485 add 390 so no negative values and always 3 digits.
            //device.printf("N245");  // TEST!!!
            // tft.setCursor(100, 50);
            //  tft.setTextSize(2);
            // tft.printf("%d", n1Pos + 145);
            wait(0.05);
            dir=0;
            lastN2Pos = n2Pos;
        }


        if (numTools != lastNumTools) {
            tft.setCursor(133, 95);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            tft.printf("%d", lastNumTools);
            tft.setCursor(133,95);
            tft.setTextColor(WHITE);
            tft.setTextSize(1);
            tft.printf("%d", numTools);
            eeprom.write(numToolsAddress, numTools);        // store new angle in eeprom, add 45 because its an unsigned value.
            //wait(0.1); // adjusted from 1
            lastNumTools = numTools;
        }

        if (numNoz != lastNumNoz) {
            tft.setCursor(133, 110);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            tft.printf("%d", lastNumNoz);
            tft.setCursor(133,110);
            tft.setTextColor(WHITE);
            tft.setTextSize(1);
            tft.printf("%d", numNoz);
            eeprom.write(numNozAddress, numNoz);        // store new angle in eeprom, add 45 because its an unsigned value.
            //wait(0.1); // adjusted from 1

            if (numNoz == 2) {
                tft.setCursor(80, 4);
                tft.setTextColor(WHITE);
                tft.setTextSize(2);
                tft.printf("N2");
                tft.drawRect(78,2,74,18,WHITE);
            }
            if (numNoz == 1) {
                tft.setCursor(80, 4);
                tft.setTextColor(BLACK);
                tft.setTextSize(2);
                tft.printf("N2");
                tft.setCursor(115, 4);
                tft.printf("%d", n2Pos);
                tft.drawRect(78,2,74,18,BLACK);
            }
            lastNumNoz = numNoz;
        }


        if (twitch != lastTwitch) {
            tft.setCursor(52, 50);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            tft.printf("%d", lastTwitch);
            tft.setCursor(52, 50);
            tft.setTextColor(GREEN);
            tft.setTextSize(1);
            tft.printf("%d", twitch);
            dir=1;
            device.printf("W");
            device.printf("%d", twitch);
            wait(0.05);
            dir=0;
            eeprom.write(currentToolNo +150, twitch); // store new twitch setting
            lastN1Pos = 999; // trigger sending servo values to module
            lastN2Pos = 999;
            lastTwitch = twitch;
        }

        if (sync != lastSync) {   //
            tft.setCursor(52, 65);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            if (lastSync == 0) {
                tft.printf("OFF");
            }
            if (lastSync == 1) {
                tft.printf("ON");
            }

            tft.setCursor(52, 65);
            tft.setTextSize(1);
            if (sync == 0) {
                tft.setTextColor(WHITE);
                tft.printf("OFF");
            }
            if (sync == 1) {
                tft.setTextColor(GREEN);
                tft.printf("ON");
            }

            
            eeprom.write(syncAddress, sync); // store new twitch setting
            syncSpread = (n2Pos - n1Pos);

            lastSync = sync;

        }

        if (n1Dir != lastN1Dir) {   //
            tft.setCursor(132, 50);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            if (lastN1Dir == 0) {
                tft.printf("NOR");
            }
            if (lastN1Dir == 1) {
                tft.printf("REV");
            }
            tft.setCursor(132, 50);
            if (n1Dir == 0) {
                tft.setTextColor(WHITE);
                tft.printf("NOR");
            }
            if (n1Dir == 1) {
                tft.setTextColor(GREEN);
                tft.printf("REV");
            }
            eeprom.write(n1DirAddress, n1Dir); // store new twitch setting
            lastN1Dir = n1Dir;
            
            dir=1;
            device.printf("D1");
            device.printf("%d", n1Dir);
            wait(0.05);
            dir=0;
            
        }

        if (n2Dir != lastN2Dir) {   //
            tft.setCursor(132, 65);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            if (lastN2Dir == 0) {
                tft.printf("NOR");
            }
            if (lastN2Dir == 1) {
                tft.printf("REV");
            }
            tft.setCursor(132, 65);
            if (n2Dir == 0) {
                tft.setTextColor(WHITE);
                tft.printf("NOR");
            }
            if (n2Dir == 1) {
                tft.setTextColor(GREEN);
                tft.printf("REV");
            }
            eeprom.write(n2DirAddress, n2Dir); // store new twitch setting
            lastN2Dir = n2Dir;
            
            dir=1;
            device.printf("D2");
            device.printf("%d", n2Dir);
            wait(0.05);
            dir=0;
            
        }
        
        if (autoMode != lastAutoMode) {   //
            tft.setCursor(52, 80);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            if (lastAutoMode == 0) {
                tft.printf("OFF");
            }
            if (lastAutoMode == 1) {
                tft.printf("X7a");
            }
            if (lastAutoMode == 2) {
                tft.printf("Pul");
            }            
            
            tft.setCursor(52, 80);
            if (autoMode == 0) {
                tft.setTextColor(WHITE);
                tft.printf("OFF");
            }
            if (autoMode == 1) {
                tft.setTextColor(GREEN);
                tft.printf("X7a");
            }
                        if (autoMode == 2) {
                tft.setTextColor(GREEN);
                tft.printf("Pul");
            }
            eeprom.write(autoModeAddress, autoMode); // store new twitch setting
            lastAutoMode = autoMode;
            
            dir=1;
            device.printf("A");           //A for auto mode
            device.printf("%d", autoMode);  // send 0,1,2 etc.
            wait(0.05);
            dir=0;
            
        }       
        
         if (aux2Mode != lastAux2Mode) {   //
            tft.setCursor(52, 95);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            if (lastAux2Mode == 0) {
                tft.printf("OFF");
            }
            if (lastAux2Mode == 1) {
                tft.printf("TWP");
            }
            
            
            tft.setCursor(52, 95);
            if (aux2Mode == 0) {
                tft.setTextColor(WHITE);
                tft.printf("OFF");
            }
            if (aux2Mode == 1) {
                tft.setTextColor(GREEN);
                tft.printf("TWP");
            }

            eeprom.write(aux2ModeAddress, aux2Mode); // store new twitch setting
            lastAux2Mode = aux2Mode;
            
            dir=1;
            device.printf("I");           //I for input
            device.printf("%d", aux2Mode);  // send 0,1,2 etc.
            wait(0.05);
            dir=0;
            
        } 
        

        if (version != lastVersion) {   //
            tft.setCursor(132, 80);
            tft.setTextColor(BLACK);
            tft.setTextSize(1);
            if (lastVersion == 0) {
                tft.printf("BAS");
            }
            if (lastVersion == 1) {
                tft.printf("PRO");
            }
            tft.setCursor(132, 80);
            if (version == 0) {
                tft.setTextColor(WHITE);
                tft.setTextSize(1);
                tft.printf("BAS");
            }
            if (version == 1) {
                tft.setTextColor(RED);
                tft.printf("PRO");
            }
            eeprom.write(versionAddress, version); // store new twitch setting
            lastVersion = version;
        }

// ************* Rectangles for identifying active selection *****************************

        if (count != lastCount) {

            if (count ==0) {
                Enc.Set(n1Pos);
                lastN1Pos = n1Pos;     ////*******************************2019-09-11 WAS FIX FOR SYNC REV RST = 90
            }

            else if (count == 1) {
                Enc.Set(n2Pos);
            }

            else if (count == 2) {
                Enc.Set(currentToolNo);
            }

            else if (count == 3) {
                Enc.Set(twitch);
            }

            else if (count == 4) {
                Enc.Set(sync);
            }
            
                        else if (count == 5) {
                Enc.Set(autoMode);
            }
            
                                    else if (count == 6) {
                Enc.Set(aux2Mode);
            }

            else if (count == 8) {
                Enc.Set(n1Dir);
            }

            else if (count == 9) {
                Enc.Set(n2Dir);
            }

            else if (count == 10) {
                Enc.Set(version);
            }

            else if (count == 11) {
                Enc.Set(numTools);
            }

            else if (count == 12) {
                Enc.Set(numNoz);
            }



// clear old boxes (white or black)
            if (lastCount == 0) {
                tft.drawRect(2,2,74,18,WHITE);
            }

            else if ((lastCount == 1) && (numNoz == 2)) {
                tft.drawRect(78,2,74,18,WHITE);
            }

            else if (lastCount == 2) {
                tft.drawRect(20,26,28,18,BLACK);
            }

            else if (lastCount == 3) {
                tft.drawRect(50,48,20,12,BLACK);
            }

            else if (lastCount == 4) {
                tft.drawRect(50,63,20,12,BLACK);
            }

            else if (lastCount == 5) {
                tft.drawRect(50,78,20,12,BLACK);
            }

            else if (lastCount == 6) {
                tft.drawRect(50,93,20,12,BLACK);
            }

            else if (lastCount == 7) {
                tft.drawRect(50,108,20,12,BLACK);
            }

            else if (lastCount == 8) {
                tft.drawRect(130,48,20,12,BLACK);
            }

            else if (lastCount == 9) {
                tft.drawRect(130,63,20,12,BLACK);
            }

            else if (lastCount == 10) {
                tft.drawRect(130,78,20,12,BLACK);
            }

            else if (lastCount == 11) {
                tft.drawRect(130,93,20,12,BLACK);
            }

            else if (lastCount == 12) {
                tft.drawRect(130,108,20,12,BLACK);
            }

// Set new box

            if (count == 0) { // N1 adjust
                tft.drawRect(2,2,74,18,GREEN);
            }

            else if ((count == 1) && (numNoz == 2)) { // N2 adjust
                tft.drawRect(78,2,74,18,GREEN);
            }

            else if (count == 2) {
                tft.drawRect(20,26,28,18,GREEN);
            }

            else if (count == 3) {
                tft.drawRect(50,48,20,12,GREEN);
            }

            else if (count == 4) {
                tft.drawRect(50,63,20,12,GREEN);
            }

            else if (count == 5) {
                tft.drawRect(50,78,20,12,GREEN);
            }

            else if (count == 6) {
                tft.drawRect(50,93,20,12,GREEN);
            }

            else if (count == 7) {
                tft.drawRect(50,108,20,12,GREEN);
            }

            else if (count == 8) {
                tft.drawRect(130,48,20,12,GREEN);
            }

            else if (count == 9) {
                tft.drawRect(130,63,20,12,GREEN);
            }

            else if (count == 10) {
                tft.drawRect(130,78,20,12,GREEN);
            }

            else if (count == 11) {
                tft.drawRect(130,93,20,12,GREEN);
            }

            else if (count == 12) {
                tft.drawRect(130,108,20,12,GREEN);
            }

            lastCount = count;
        }





//****************** ENCODER ACTIONS ************************************************
        if (count == 0) {  // knob controls servo value

            if (n1Pos != Enc.Get()) {
                //n1Pos = Enc.Get(); 2019-09-12
                if (sync == 0 && n1Dir ==0) {           // n1 fwd
                    n1Pos = Enc.Get();
                }

                if (sync == 0 && n1Dir ==1) {           // n1 rev
                    n1Pos = n1Pos + (n1Pos - Enc.Get());
                    Enc.Set(n1Pos);
                }


                if (n1Pos > 90) {
                    n1Pos = 90;
                    Enc.Set(90);
                }

                if (n1Pos < -90) {
                    n1Pos = -90;
                    Enc.Set(-90);
                }

//***

                if (sync == 1 && n1Dir == 0 && n2Dir == 0) {   // PASS 2019-09-12
                    encoderMove = (Enc.Get() - n1Pos);  // save direction change, positive or negative
                    if (encoderMove > 0 && n1Pos < 90 && n2Pos <90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = Enc.Get();
                        n2Pos = n2Pos + encoderMove;
                        encoderMove =0;
                        //Enc.Set(n1Pos);
                    }

                    if (encoderMove < 0 && n1Pos > -90 && n2Pos >-90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = Enc.Get();
                        n2Pos = n2Pos + encoderMove;
                        encoderMove =0;
                        // Enc.Set(n1Pos);
                    }
                    Enc.Set(n1Pos);   // reset encoder so it doesnt store counts past +90/ -90

                }

                if (sync == 1 && n1Dir == 1 && n2Dir == 0) {
                    encoderMove = ( n1Pos - Enc.Get());  // save direction change, positive or negative
                    if (encoderMove > 0 && n1Pos > -90 && n2Pos <90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = (n1Pos + encoderMove);
                        Enc.Set(n1Pos);
                        n2Pos = (n2Pos - encoderMove);
                        encoderMove=0;
                    }

                    if (encoderMove < 0 && n1Pos < 90 && n2Pos > -90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = (n1Pos + encoderMove);
                        Enc.Set(n1Pos);
                        n2Pos = (n2Pos - encoderMove);
                        encoderMove=0;
                    }
                    Enc.Set(n1Pos);   // reset encoder so it doesnt store counts past +90/ -90

                }


                if (sync == 1 && n1Dir == 0 && n2Dir == 1) {
                    encoderMove = (Enc.Get() - n1Pos);  // save direction change, positive or negative
                    if (encoderMove < 0 && n1Pos > -90 && n2Pos <90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = (n1Pos + encoderMove);
                        Enc.Set(n1Pos);
                        n2Pos = (n2Pos - encoderMove);
                        encoderMove=0;
                    }

                    if (encoderMove > 0 && n1Pos < 90 && n2Pos > -90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = (n1Pos + encoderMove);
                        Enc.Set(n1Pos);
                        n2Pos = (n2Pos - encoderMove);
                        encoderMove=0;
                    }
                    Enc.Set(n1Pos);   // reset encoder so it doesnt store counts past +90/ -90
                }



                if (sync == 1 && n1Dir == 1 && n2Dir == 1) {
                    encoderMove = (Enc.Get() - n1Pos);  // save direction change, positive or negative
                    if (encoderMove > 0 && n1Pos > -90 && n2Pos >-90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = (n1Pos - encoderMove);
                        Enc.Set(n1Pos);
                        n2Pos = (n2Pos - encoderMove);
                        encoderMove=0;
                    }

                    if (encoderMove < 0 && n1Pos < 90 && n2Pos < 90) { // Move is positive // stop both nozzles once ONE reaches limit.
                        n1Pos = (n1Pos - encoderMove);
                        Enc.Set(n1Pos);
                        n2Pos = (n2Pos - encoderMove);
                        encoderMove=0;
                    }
                    Enc.Set(n1Pos);   // reset encoder so it doesnt store counts past +90/ -90
                }

            }
            if (n1Pos > 90) {
                n1Pos =90;
            }
            if (n1Pos < -90) {
                n1Pos = -90;
            }
            if (n2Pos > 90) {
                n2Pos =90;
            }
            if (n2Pos < -90) {
                n2Pos = -90;
            }
        }


//***************************
        if (count == 1) {  // knob controls servo value
        
                    if (n2Pos != Enc.Get()) {
        encoderMove = (Enc.Get() - n2Pos);  // save direction change, positive or negative
        
        if (n2Dir == 0 && encoderMove >0 && n2Pos < 90){        // normal direction
            n2Pos = n2Pos + encoderMove;
            encoderMove=0;
            }
          if (n2Dir == 0 && encoderMove <0 && n2Pos > -90){        // normal direction
            n2Pos = n2Pos + encoderMove;
            encoderMove=0;
            }          

        if (n2Dir == 1 && encoderMove <0 && n2Pos < 90){        // reverse direction
            n2Pos = n2Pos - encoderMove;
            encoderMove=0;
            }
          if (n2Dir == 1 && encoderMove >0 && n2Pos > -90){        // reverse direction
            n2Pos = n2Pos - encoderMove;
            encoderMove=0;
            } 
         Enc.Set(n2Pos);   // reset encoder so it doesnt store counts past +90/ -90   
         if (n2Pos > 90){
             n2Pos = 90;
             }
            if (n2Pos < -90){
             n2Pos = -90;
             }      
        }
        
        }
//****************************
        if (count == 2) {    //knob controls tool number

            currentToolNo = Enc.Get();
            if (currentToolNo > numTools) {
                currentToolNo = numTools;
            }
            if (currentToolNo < 1) {
                currentToolNo = 1;
                Enc.Set(1);
            }
        }
//****************************
        if (count == 3) { // Knob controls twitch setting
            twitch = Enc.Get();
            if (twitch < 0) {
                twitch = 0;
                Enc.Set(0);
            }
            if (twitch > 3) {
                twitch = 3;
                Enc.Set(3);
            }
        }
//****************************
        if (count == 4) { // Knob controls sync setting. 1=off, 2=sync, 3=rev
            sync = Enc.Get();
            if (sync < 0) {
                sync= 0;
                Enc.Set(0);
            }
            if (sync > 1) {
                sync = 1;
                Enc.Set(1);
            }
        }
        //****************************
          if (count == 5) { // Knob controls auto setting. 1=off, 2=sync, 3=rev
            autoMode = Enc.Get();
            if (autoMode < 0) {
                autoMode= 0;
                Enc.Set(0);
            }
            if (autoMode > 2) {
                autoMode = 2;
                Enc.Set(2);
            }
        }      

        //****************************
          if (count == 6) { // Knob controls auto setting. 1=off, 2=sync, 3=rev
            aux2Mode = Enc.Get();
            if (aux2Mode < 0) {
                aux2Mode= 0;
                Enc.Set(0);
            }
            if (aux2Mode > 1) {
                aux2Mode = 1;
                Enc.Set(1);
            }
        }          
        
        
        //**************************** 
        
        // 5,6,7 AUX?
        if (count == 8) {  // knob controls the direction of rotation for N1
            n1Dir = Enc.Get();

            if (n1Dir > 1) {
                n1Dir = 1;
                Enc.Set(1);
            }

            if (n1Dir < 0) {
                n1Dir =0;
                Enc.Set(0);
            }
        }
//****************************
        if (count == 9) {  // knob controls the direction of rotation for N2
            n2Dir = Enc.Get();

            if (n2Dir > 1) {
                n2Dir = 1;
                Enc.Set(1);
            }

            if (n2Dir < 0) {
                n2Dir =0;
                Enc.Set(0);
            }
        }
//****************************
        if (count == 10) {  // knob controls the version
            version = Enc.Get();

            if (version > 1) {
                version = 1;
                Enc.Set(1);
            }

            if (version < 0) {
                version =0;
                Enc.Set(0);
            }
        }
//****************************
        if (count == 11) {    //knob controls tool number
            numTools = Enc.Get();
            if (numTools > 50) {
                numTools = 50;
                Enc.Set(50);
            }
            if (numTools < 1) {
                numTools = 1;
                Enc.Set(1);
            }
        }
//****************************
        if (count == 12) {    //knob controls tool number
            numNoz = Enc.Get();
            if (numNoz> 2) {
                numNoz = 2;
                Enc.Set(2);
            }
            if (numNoz < 1) {
                numNoz = 1;
                Enc.Set(1);
            }
        }



//**************************** RS485 link ***************************************

        while (device.readable()) {
            c = device.getc();

            if (c == 'T') {    // Actual tool number sent over serial

                index = 1;
            }


            if (c == 'M') { // magazine + or - sent over serial
                index = 5;
            }
            
              if (c == 'X') { // magazine + or - sent over serial
                                                    tft.setCursor(50, 30);
            tft.setTextColor(RED);
            tft.setTextSize(1.5);
                tft.printf("TWITCH HOLD"); 
                index=0;
            }          
            
                  if (c == 'Y') { // magazine + or - sent over serial
                                                    tft.setCursor(50, 30);
            tft.setTextColor(BLACK);
            tft.setTextSize(1.5);
                tft.printf("TWITCH HOLD"); 
                index=0;
            }         
            

            if (index == 1) {
                c = device.getc();
                if (c == '1') {  // hundreds place to know we are sending 3 digits
                    index = 2;
                }
            }
            
            



            if (index == 2) { // tool number 10's column

                c = device.getc();

                if (c=='0') {
                    Tens = 0;
                    index = 4;

                }

                else if (c=='1') {
                    Tens = 1;
                    index = 4;

                }

                else if (c=='2') {
                    Tens = 2;
                    index = 4;

                }

                else if (c=='3') {
                    Tens = 3;
                    index = 4;

                }

                else if (c=='4') {
                    Tens = 4;
                    index = 4;
                }

                else if (c=='5') {   //max number of tools is 50
                    Tens = 5;
                    index = 4;
                }

            }
            

            

            if (index == 4) {  // tool number ones column

                c = device.getc();

                if (c=='0') {
                    Ones = 0;

                }

                else if (c=='1') {
                    Ones = 1;


                }

                else if (c=='2') {
                    Ones = 2;

                }

                else if (c=='3') {
                    Ones = 3;

                }

                else if (c=='4') {
                    Ones = 4;
                }

                else if (c=='5') {
                    Ones = 5;
                }

                else if (c=='6') {
                    Ones = 6;
                }

                else if (c=='7') {
                    Ones = 7;
                }

                else if (c=='8') {
                    Ones = 8;
                }

                else if (c=='9') {
                    Ones = 9;
                }

                else if (c=='0') {
                    Ones = 0;
                }



                serialToolNumber = ((Tens * 10) + Ones);
                
                count = 0; // 2019-09-23 to make sure the new tool isn't overwritten.

                currentToolNo = serialToolNumber; // update tool number

                index=0;

            }

            if (index == 5) {    // magazine monitoring



                c = device.getc();

                if (c == '+') {


                    currentToolNo = (currentToolNo +1);
                    if (currentToolNo > numTools) {
                        currentToolNo = 1;
                    }
                    index = 0;
                } else if (c == '-') {
                    /*
                                      tft.setTextColor(WHITE);
                    tft.setCursor(100, 100);
                    tft.printf("1");
                    */
                    currentToolNo = (currentToolNo -1);
                    if (currentToolNo < 1) {
                        currentToolNo = numTools;
                    }
                    index = 0;
                }

            }
        }

    }
}