Arduino slowing down

Good day all,

Is it possible for a Arduino Mega to slow down as you add more code?
I've got a Mega, with a 8 way relay board, 3.2 inch TFT(Non Touch) and a 4x4 keypad with a code which controls the on/off times of the relays as well as outputs some variables onto the screen.
I'm still trying to make the keypad work so that I can change the off time of the relay, but at the moment it seems like the timings of the relays, as well as the keypad push responses have really slowed down quite a bit.

The code which I have so far is as follow (I created a tab for each section, so apologies for the separate codes in the thread.

#include <UTFT.h>
#include <Keypad.h>
UTFT myGLCD(CTE32HR, 38, 39, 40, 41);
extern uint8_t BigFont[];
extern uint8_t Grotesk32x64[];
const byte Machine1 = A0; // I/O pin connected by the first relay
const byte Machine2 = A1;
const byte Machine3 = A2;
const byte Machine4 = A3;
const byte Machine5 = A4;
const byte Machine6 = A5;
const byte Machine7 = A6;
const byte Machine8 = A7;
unsigned long BlowerStartTime;
unsigned long BlowerStopTime;
bool BlowerIsRunning = false;
byte CurrentBlower = Machine1;
int onTime = 1 ; // seconds on
int offTime = 100 ; // seconds off
byte numbr[4];  // This will hold 4 bytes, and if global, will init to all zeros
byte indx;  //This will hold an index to the array. If global, it will init to 0
int enteredValue;  // this will hold the final value entered
int currentMenuItem = 0;
int lastState = 0;
int a = 4;
unsigned int blows = 0;
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 8, 9};
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
  for (int i = Machine1; i <= Machine8; i += 1)
  {
    pinMode(i, OUTPUT); //set digital I/O pin as output
  }
  Serial.begin(9600);
  myGLCD.InitLCD();
  myGLCD.setFont(Grotesk32x64);
  myGLCD.clrScr();
  myGLCD.setColor(VGA_BLUE);
  myGLCD.print("CHINCO FIRESIDE", CENTER, 100);
  myGLCD.print("TREATMENT", CENTER, 164);
  delay (3000);
  myGLCD.clrScr();
}

void loop()
{
  title();
  ManageBlowers();
  keyPad();
}
void ManageBlowers() {
  if (BlowerIsRunning)
  {
    if (millis() - BlowerStartTime > onTime * 1000UL)
    {
      StopBlower(CurrentBlower);
      CurrentBlower += 1;
      if (CurrentBlower > Machine8)
        CurrentBlower = Machine1;
    }
  }
  else
  {
    if (millis() - BlowerStopTime > offTime * 1000UL)
    {
      StartBlower(CurrentBlower);
    }
  }
}

void StopBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, LOW);
  BlowerIsRunning = false;
  BlowerStopTime = millis();
}

void StartBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, HIGH);
  blows ++;
  BlowerIsRunning = true;
  BlowerStartTime = millis();
}
void keyPad() {
  char key = kpd.getKey();
  char key1 = kpd.getKey();
  // set  the cursor to column 0, line 1
  // (note:  line 1 is the second row, since counting begins with 0):
  // Check for a valid key
  if (key)
  {
    // set the cursor to column 9, line 1
    //(note: line 1 is the second row, since counting begins with 0):
    //lcd.setCursor(9, 1);
    //Print the detected key
    myGLCD.setColor(VGA_RED);
    myGLCD.printNumI(key - 48, 207, 228);
    delay (5);
    myGLCD.printNumI(key1 - 48, 223, 228);
    delay (5);
  }
}
void title() {
  int activeDays = millis() / 864000000UL;
  int activeHours = millis() / 3600000UL;
  int powderUsed = (blows * 50) / 1000;
  myGLCD.setColor(VGA_BLUE);
  myGLCD.drawRect(0, 0, 479, 305);
  myGLCD.setColor(VGA_WHITE);
  myGLCD.setFont(BigFont);
  myGLCD.print("CHINCO FIRESIDE TREATMENT", CENTER, 2);
  myGLCD.print("Delay Between Blows :", 2, 48); // Delay time
  myGLCD.printNumI(offTime, 337, 48);
  myGLCD.print("s", 403, 48);
  myGLCD.print("Duration of Each Blow :", 2, 64); // Blow time
  myGLCD.printNumI(onTime, 368, 64);
  myGLCD.print("s", 402, 64);
  myGLCD.print("System Active For :", 2, 80); //Active Days
  myGLCD.printNumI(activeDays, 305, 80);
  myGLCD.print("Days", 355, 80);
  myGLCD.print("System Active For :", 2, 96); //Active Hours
  myGLCD.printNumI(activeHours, 305, 96);
  myGLCD.print("Hours", 355, 96);
  myGLCD.print("Number of Blows :", 2, 112); //Blows
  myGLCD.printNumI(blows, 274 , 112);
  myGLCD.print("KGs powder used :", 2, 128); //KGs used
  myGLCD.printNumI(powderUsed, 274, 128);
  myGLCD.print("Serial # 0001", RIGHT, 286); // Change on each new timer
  myGLCD.setColor(VGA_BLUE);
  myGLCD.print("CHANGE BLOW DELAY TIME", CENTER, 194);
  myGLCD.print("ENTER VALUE", CENTER, 210);
  myGLCD.print("PRESS # TO SAVE", CENTER, 248); 
}

The TFT takes a lot of CPU power. Arduinos are not designed to run screens sich as these.

But in this case STOP rewriting the screen every time you go through loop! Update the screen once a second.

Mark

holmes4:
The TFT takes a lot of CPU power. Arduinos are not designed to run screens sich as these.

But in this case STOP rewriting the screen every time you go through loop! Update the screen once a second.

Mark

Thanks Mark, this is my first project, so I'm learning as I go. Never thought about CPU capabilities.
I've now set the title page to be a "setup" which I want to call with the "A" button on my keypad. That way it wont be running permanently, but only when the user wants to see the page.

Now I just need to figure out how to use the keypad to assign the "A" button to that specific function, as well as use to the keypad to change the offTime value.

If you have any ideas, that would be great :slight_smile:

#include <UTFT.h>
#include <Keypad.h>
UTFT myGLCD(CTE32HR, 38, 39, 40, 41);
extern uint8_t BigFont[];
extern uint8_t Grotesk32x64[];
const byte Machine1 = A0; // I/O pin connected by the first relay
const byte Machine2 = A1;
const byte Machine3 = A2;
const byte Machine4 = A3;
const byte Machine5 = A4;
const byte Machine6 = A5;
const byte Machine7 = A6;
const byte Machine8 = A7;
unsigned long BlowerStartTime;
unsigned long BlowerStopTime;
bool BlowerIsRunning = false;
byte CurrentBlower = Machine1;
int onTime = 1 ; // seconds on
int offTime = 100 ; // seconds off
int activeDays = millis() / 864000000UL;
int activeHours = millis() / 3600000UL;
//byte numbr[4];  // This will hold 4 bytes, and if global, will init to all zeros
//byte indx;  //This will hold an index to the array. If global, it will init to 0
//int enteredValue;  // this will hold the final value entered
//int currentMenuItem = 0;
//int lastState = 0;
//int a = 4;
unsigned int blows = 0;
int powderUsed = (blows * 50) / 1000;
const byte numROWS = 4; // Four rows
const byte numCOLS = 4; // Four columns
char keymap[numROWS][numCOLS] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[numROWS] = {9, 8, 7, 6};
byte colPins[numCOLS] = {5, 4, 3, 2};
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numROWS, numCOLS );

void setup()
{
  for (int i = Machine1; i <= Machine8; i += 1)
  {
    pinMode(i, OUTPUT); //set digital I/O pin as output
  }
  Serial.begin(9600);
  myGLCD.InitLCD();
  myGLCD.setFont(Grotesk32x64);
  myGLCD.clrScr();
  myGLCD.setColor(VGA_BLUE);
  myGLCD.print("CHINCO FIRESIDE", CENTER, 100);
  myGLCD.print("TREATMENT", CENTER, 164);
  delay (3000);
  myGLCD.clrScr();
  myGLCD.setFont(BigFont);
  myGLCD.print("Press A to return to Stat Page", CENTER, 130);
  myGLCD.print("Serial # 0001", RIGHT, 286); // Change on each new timer

}

void title() {
  myGLCD.setColor(VGA_BLUE);
  myGLCD.drawRect(0, 0, 479, 305);
  myGLCD.setColor(VGA_WHITE);
  myGLCD.setFont(BigFont);
  myGLCD.print("CHINCO FIRESIDE TREATMENT", CENTER, 2);
  myGLCD.print("Delay Between Blows :", 2, 48); // Delay time
  myGLCD.printNumI(offTime, 337, 48);
  myGLCD.print("s", 403, 48);
  myGLCD.print("Duration of Each Blow :", 2, 64); // Blow time
  myGLCD.printNumI(onTime, 368, 64);
  myGLCD.print("s", 402, 64);
  myGLCD.print("System Active For :", 2, 80); //Active Days
  myGLCD.printNumI(activeDays, 305, 80);
  myGLCD.print("Days", 355, 80);
  myGLCD.print("System Active For :", 2, 96); //Active Hours
  myGLCD.printNumI(activeHours, 305, 96);
  myGLCD.print("Hours", 355, 96);
  myGLCD.print("Number of Blows :", 2, 112); //Blows
  myGLCD.printNumI(blows, 274 , 112);
  myGLCD.print("KGs powder used :", 2, 128); //KGs used
  myGLCD.printNumI(powderUsed, 274, 128);
  myGLCD.setColor(VGA_BLUE);
  myGLCD.print("CHANGE BLOW DELAY TIME", CENTER, 194);
  myGLCD.print("ENTER VALUE", CENTER, 210);
  myGLCD.print("PRESS # TO SAVE", CENTER, 248);
  delay (3000);
}


void loop()
{
//  title();
  ManageBlowers();
  keyPad();

}

If you turn the title() function into a state machine that only prints 1 line per state, possibly even less, you will get more run time for the blowers and keypad.

byte titleState; // default 0
........

void title() 
{
  switch ( titleState );
  {
    case 0 : init-begin
  int activeDays = millis() / 864000000UL;
  int activeHours = millis() / 3600000UL;
  int powderUsed = (blows * 50) / 1000;
  myGLCD.setColor(VGA_BLUE);
  myGLCD.drawRect(0, 0, 479, 305);
    titleState++;
    break;
    case 1 :
  myGLCD.setColor(VGA_WHITE);
  myGLCD.setFont(BigFont);
  myGLCD.print("CHINCO FIRESIDE TREATMENT", CENTER, 2);
    titleState++;
    break;
    case 2 :
  myGLCD.print("Delay Between Blows :", 2, 48); // Delay time

  // etc. Set state to 0 at end

This will also need any result to be printed that gets or might get changed while the printing is done to be copied and the copies printed.

You could try to only update parts of the screen if any parts don't change then do them once.

BTW, why aren't Machine1 to 8 an array Machine[0] to [7]?

Never ever write this

  myGLCD.printNumI(key - 48, 207, 228);

always write

  myGLCD.printNumI(key - '0', 207, 228);

So a test for key being the char 'A' would be ........

By the way never use relays see take your relay shield and have fun by hitting it with a big hammer

See the blink without delay example to see how to do a once a second update of the screen

Mark

holmes4:
Never ever write this

  myGLCD.printNumI(key - 48, 207, 228);

always write

  myGLCD.printNumI(key - '0', 207, 228);

So a test for key being the char 'A' would be ........

By the way never use relays see take your relay shield and have fun by hitting it with a big hammer

See the blink without delay example to see how to do a once a second update of the screen

Mark

Hi Mark,

  myGLCD.printNumI(key - 48, 207, 228);

The -48 is the only way I can get the output to be the correct number. For some reason it always adds 48 to the out put, even the "A", "B", "C", "D" buttons output a number. If I check it on the Serial monitor the output is correct, but not when it outputs to the screen. Any idea why it does that?

I'm having problems with the keypa, and I'm still stuck with the following,

  1. The +48 issue explained above.
  2. Using the keypad to change the offTime int the global variables.

I'm pretty much done with everything else, it's just these two that are kicking my backside!.

Cheers.

Because the ASCII value of the character '0' is actually 48. You don't need to memorize this, just subtract the character '0' from the value returned.

"A" "B" "C" have different numbers. Depending on the keypad library, you might need to check for strict equality if(key == 'A') or you may be just getting 10, 11, 12 when you subtract the '0'. Without looking it up, I don't know the ASCII characters following the digits.

www.asciitable.com for ASCII to hex/decimal conversion.

MorganS:
Because the ASCII value of the character '0' is actually 48. You don't need to memorize this, just subtract the character '0' from the value returned.

"A" "B" "C" have different numbers. Depending on the keypad library, you might need to check for strict equality if(key == 'A') or you may be just getting 10, 11, 12 when you subtract the '0'. Without looking it up, I don't know the ASCII characters following the digits.

Thanks for the explanation, makes sense now.