I have a 2.8" TFT screen and the sketch periodically freezes or hangs up. I have built an Arduino based Autopilot that steers a 40 foot sailboat and has done so for several years (YouTube Video https://www.youtube.com/watch?v=-nA6wo9PXls). There is a main Arduino MEGA 2560 for the Autopilot proper. The TFT is on a second MEGA 2560 with a keypad and is the handheld remote controller.
Data is sent from the main Autopilot Mega to the Remote Controller serially using Bill Porters Easy Transfer Library.
The Keypad is read by the MEGA in the remote with the standard keypad library then the remote sends the key value serially to the main Autopilot Mega.
When I run the sketch with the TFT print functions commented out the sketch runs for over 24 hours and there are no hangups. So the serial communications seem to be working and the Easy Transfer library works.
When the print functions are turned back on the TFT hangs up, It may run for hours but eventually hangs up. When the screen is working normally you can observe the screen refreshing. When it hangs up the refreshing stops and the keypad function does not work meaning the code is hung up somewhere.
Reducing the number of lines printed seems to reduce the frequency of the hangups. The TFT and MEGA are mounted in a water proof box. Current testing is without the box in a cool room. On the boat in the summer the frequency of hanging up seemed to be much more frequent when it was hot.
I would like to fix this but am open to other approaches, i. e. different screens.
I tried to attach the sketch but the forum said .INO files were not allowed. Here is a Dropbox link to the Sketch and a photo:
https://www.dropbox.com/sh/g82o1ci90xk3 ... uYAIa?dl=0
2.8" TFT Skecth hangs up freezes
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- Franklin97355
- Posts: 23911
- Joined: Mon Apr 21, 2008 2:33 pm
Re: 2.8" TFT Skecth hangs up freezes
Thanks we will look at it. In the future you should be able to copy and paste your code between
Code: Select all
tags using the </> button above the reply box.
- miju
- Posts: 4
- Joined: Tue May 19, 2015 3:30 am
Re: 2.8" TFT Skecth hangs up freezes
Hi, I have similar problem with my Adafruit 3.5" 320x480 Color TFT Touchscreen in SPI mode. In my project I tried use typical KeyPad 4x4 connected by 8 PIN in my Arduino MEGA. I use Keypad.h library and getKey() function to entry number from KeyPad. When I use the getKey() function, the display stops responding to all my calls. At the same time, the Serial communication is working properly.
My hardware:
http://www.arduino.cc/en/Main/ArduinoBoardMega2560
https://learn.adafruit.com/adafruit-3-5 ... g-and-test
http://www.learningaboutelectronics.com ... ircuit.php
Library source:
http://playground.arduino.cc/uploads/Code/keypad.zip
https://github.com/adafruit/Adafruit_HX ... master.zip
https://github.com/adafruit/Adafruit-GF ... master.zip
Below the code.
My hardware:
http://www.arduino.cc/en/Main/ArduinoBoardMega2560
https://learn.adafruit.com/adafruit-3-5 ... g-and-test
http://www.learningaboutelectronics.com ... ircuit.php
Library source:
http://playground.arduino.cc/uploads/Code/keypad.zip
https://github.com/adafruit/Adafruit_HX ... master.zip
https://github.com/adafruit/Adafruit-GF ... master.zip
Below the code.
Code: Select all
// SPI
#include <SPI.h>
// TFT
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
// These are 'flexible' lines that can be changed
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8 // RST can be set to -1 if you tie it to Arduino's reset
#include <Keypad.h>
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] = {53,51,49,47}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {45,43,41,39}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
char buff[11];
void setup(){
Serial.begin(9600);
tft.begin(HX8357D); // TFT Start
tft.setRotation(1); // TFT Rotation
tft.fillScreen(HX8357_BLACK); // TFT CLS
tft.setCursor(100,100); // Cursor Position
tft.setTextColor(HX8357_WHITE); // Text Color
tft.setTextSize(6); // Text Size
tft.println("Hello Test"); // Text Example TFT OK
for (int i=0 ; i < 11 ; i++) {
buff[ i ] = getKey();
Serial.print(buff[i]);
tft.println(buff[i]);
}
Serial.print("Serial Output is OK");
tft.println("TFT Output isn't OK"); // TFT Frozen
Serial.print("Serial Output is OK");
}
void loop()
{
}
char getKey()
{
char key = NO_KEY;
while ( key == NO_KEY ) {
key = keypad.getKey();
}
return( key );
}
void tekst()
{
tft.fillScreen(HX8357_BLUE);
tft.setCursor(180, 190);
tft.setTextColor(HX8357_WHITE);
tft.setTextSize(2);
tft.print("Hello Test");
}
- coyotewaits
- Posts: 12
- Joined: Mon Jan 20, 2014 12:47 pm
Re: 2.8" TFT Skecth hangs up freezes
I think my hanging up is an issue of power supply and spurious data on a long wire. I use a piece of CAT5E (4 twisted pair, 24 ga wire). I have added a 100 micro farad capacitor across the VCC and GND connections at the screen. This helps at least here at the desk. I will see how it does when I install it on the boat with longer wire in a electrically disturbed environment.
Assuming you can run Adafruit examples ok, I don't think your problem is a TFT problem. I think your program is hanging up in how you call key = keypad.getKey();
Here is a sketch that has an extensive keypad structure and prints to an LCD perhaps it will be helpful to solve your problem.
/***********************************
By Jack Edwards
Here is a simple code that test functionality of the LCD and keypad.
It uses the same pin assignments as the Autopilot.
It can be used to test that things are wired properly and running.
Read the code to see what the keys do.
Does not require the complexity that adding the IMU does.
It prints to the serial monitor at 57600 baud. You can test keypad operation without the LCD.
It can be used to experiment with.
*******************************************************/
/* @file EventSerialKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact [email protected]
||
|| @description
|| | Demonstrates using the KeypadEvent.
|| #
*/
/* EventKeypad and LCD is set up to use keypad to get input for Autopilot by Jack Edwards
it does the following
KEY TYPE ACTION
0 press - sets steering mode to 0 OFF
1 hold - sets steering mode to 1 COMPASS
2 hold - set steering mode to 2 GPS
3 none
4 press - decrease course b 10 deg
5 - none
6 press - increase course 10 deh
7 press - decrease course by 1 deg
8 none
9 press - increase course by 1 deg
* press/release - Left Rudder ON until released then rudder OFF
0 press - sets steering mode to 0 OFF
# press/release - Right Rudder ON until released then OFF
*/
#include <Keypad.h>
// LCD library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(41,43,45,47,49,51);
// Keypad Setup
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
//byte rowPins[ROWS] = {23,25,27,29,}; //connect to the row pinouts of the keypad
//byte colPins[COLS] = {31,33,35}; //connect to the column pinouts of the keypad
//byte rowPins[ROWS] = {42,32,34,38}; //connect to the row pinouts of the keypad JACK'S KEYPAD
//byte colPins[COLS] = {40,44,36}; //connect to the column pinouts of the keypad JACK'S KEYPAD
byte rowPins[ROWS] = {34,44,42,38}; //connect to the row pinouts of the keypad JACK'S KEYPAD
byte colPins[COLS] = {36,32,40}; //connect to the column pinouts of the keypad JACK'S KEYPAD
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char input;
int mode = 0;
String str_mode = "OFF";
float heading = 15;
float heading_to_steer;
void setup(){
Serial.begin(57600);
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
lcd.begin(20,4); // initialize LCD for 4 row 20 characters
lcd.setCursor(0,0);
}
void loop(){
// put if (sw1) here then if(!sw1) get key
char key = keypad.getKey();
if (key != NO_KEY) {
//lcd.print(key);
}
lcd.setCursor (0,3);
lcd.print(str_mode);
}
//take care of some special events
void keypadEvent(KeypadEvent key){
delay(20);
switch (keypad.getState()){
case PRESSED:
Serial.print("Key = "); Serial.println(key);
switch (key){
case '0':
mode = 0;
str_mode = "OFF";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("MODE = OFF");
break;
case '1':
mode = 1;
str_mode = "COMPASS";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("mode = compass");
heading_to_steer = heading;
lcd.setCursor(0,2);
lcd.print("HTS = ");
lcd.print(heading_to_steer);
break;
case '2':
mode = 2;
str_mode = "GPS";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("mode = GPS");
break;
case '3':
mode = 2;
str_mode = "TACK";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("mode = TACK");
break;
case '4':
str_mode = "Left 10";
heading_to_steer = heading_to_steer -10;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
case '5':
mode = 2;
str_mode = "Knob Steering";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
break;
case '6':
str_mode = "Right 10";
heading_to_steer = heading_to_steer +10;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
case '7':
str_mode = "Left 1";
heading_to_steer = heading_to_steer -1;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
case '8':
str_mode = "Switch Screens";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
break;
case '9':
str_mode = "Right 1";
heading_to_steer = heading_to_steer +1;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
} // end key pressed
break;
case RELEASED:
Serial.print("Key "); Serial.print(key); Serial.println(" Released");
switch (key){
case '*':
str_mode = "COMPASS";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key * Released");
lcd.setCursor(0,1);
lcd.print("RUDDER OFF");
break;
case '#':
str_mode = "Rudder Stop";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key # Released");
lcd.setCursor(0,1);
lcd.print("RUDDER OFF");
break;
} // end key released
break;
case HOLD:
Serial.print("Key "); Serial.print(key); Serial.println(" Held");
switch (key){
case '*':
str_mode = "Dodge Left";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("LEFT RUDDER ON");
break;
case '#':
str_mode = "Dodge Right";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("RIGHT RUDDER ON");
break;
} // end key HOLD
break;
} // end get keypad state (Pressed, Released or Hold)
} // end keypad event
Assuming you can run Adafruit examples ok, I don't think your problem is a TFT problem. I think your program is hanging up in how you call key = keypad.getKey();
Here is a sketch that has an extensive keypad structure and prints to an LCD perhaps it will be helpful to solve your problem.
/***********************************
By Jack Edwards
Here is a simple code that test functionality of the LCD and keypad.
It uses the same pin assignments as the Autopilot.
It can be used to test that things are wired properly and running.
Read the code to see what the keys do.
Does not require the complexity that adding the IMU does.
It prints to the serial monitor at 57600 baud. You can test keypad operation without the LCD.
It can be used to experiment with.
*******************************************************/
/* @file EventSerialKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact [email protected]
||
|| @description
|| | Demonstrates using the KeypadEvent.
|| #
*/
/* EventKeypad and LCD is set up to use keypad to get input for Autopilot by Jack Edwards
it does the following
KEY TYPE ACTION
0 press - sets steering mode to 0 OFF
1 hold - sets steering mode to 1 COMPASS
2 hold - set steering mode to 2 GPS
3 none
4 press - decrease course b 10 deg
5 - none
6 press - increase course 10 deh
7 press - decrease course by 1 deg
8 none
9 press - increase course by 1 deg
* press/release - Left Rudder ON until released then rudder OFF
0 press - sets steering mode to 0 OFF
# press/release - Right Rudder ON until released then OFF
*/
#include <Keypad.h>
// LCD library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(41,43,45,47,49,51);
// Keypad Setup
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
//byte rowPins[ROWS] = {23,25,27,29,}; //connect to the row pinouts of the keypad
//byte colPins[COLS] = {31,33,35}; //connect to the column pinouts of the keypad
//byte rowPins[ROWS] = {42,32,34,38}; //connect to the row pinouts of the keypad JACK'S KEYPAD
//byte colPins[COLS] = {40,44,36}; //connect to the column pinouts of the keypad JACK'S KEYPAD
byte rowPins[ROWS] = {34,44,42,38}; //connect to the row pinouts of the keypad JACK'S KEYPAD
byte colPins[COLS] = {36,32,40}; //connect to the column pinouts of the keypad JACK'S KEYPAD
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char input;
int mode = 0;
String str_mode = "OFF";
float heading = 15;
float heading_to_steer;
void setup(){
Serial.begin(57600);
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
lcd.begin(20,4); // initialize LCD for 4 row 20 characters
lcd.setCursor(0,0);
}
void loop(){
// put if (sw1) here then if(!sw1) get key
char key = keypad.getKey();
if (key != NO_KEY) {
//lcd.print(key);
}
lcd.setCursor (0,3);
lcd.print(str_mode);
}
//take care of some special events
void keypadEvent(KeypadEvent key){
delay(20);
switch (keypad.getState()){
case PRESSED:
Serial.print("Key = "); Serial.println(key);
switch (key){
case '0':
mode = 0;
str_mode = "OFF";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("MODE = OFF");
break;
case '1':
mode = 1;
str_mode = "COMPASS";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("mode = compass");
heading_to_steer = heading;
lcd.setCursor(0,2);
lcd.print("HTS = ");
lcd.print(heading_to_steer);
break;
case '2':
mode = 2;
str_mode = "GPS";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("mode = GPS");
break;
case '3':
mode = 2;
str_mode = "TACK";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("mode = TACK");
break;
case '4':
str_mode = "Left 10";
heading_to_steer = heading_to_steer -10;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
case '5':
mode = 2;
str_mode = "Knob Steering";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
break;
case '6':
str_mode = "Right 10";
heading_to_steer = heading_to_steer +10;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
case '7':
str_mode = "Left 1";
heading_to_steer = heading_to_steer -1;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
case '8':
str_mode = "Switch Screens";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
break;
case '9':
str_mode = "Right 1";
heading_to_steer = heading_to_steer +1;
if (heading_to_steer < 0) heading_to_steer = heading_to_steer +360;
if (heading_to_steer > 360) heading_to_steer = heading_to_steer -360;
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("HTS = ");
lcd.print( heading_to_steer);
break;
} // end key pressed
break;
case RELEASED:
Serial.print("Key "); Serial.print(key); Serial.println(" Released");
switch (key){
case '*':
str_mode = "COMPASS";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key * Released");
lcd.setCursor(0,1);
lcd.print("RUDDER OFF");
break;
case '#':
str_mode = "Rudder Stop";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key # Released");
lcd.setCursor(0,1);
lcd.print("RUDDER OFF");
break;
} // end key released
break;
case HOLD:
Serial.print("Key "); Serial.print(key); Serial.println(" Held");
switch (key){
case '*':
str_mode = "Dodge Left";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("LEFT RUDDER ON");
break;
case '#':
str_mode = "Dodge Right";
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Key = ");
lcd.print(key);
lcd.setCursor(0,1);
lcd.print("RIGHT RUDDER ON");
break;
} // end key HOLD
break;
} // end get keypad state (Pressed, Released or Hold)
} // end keypad event
- miju
- Posts: 4
- Joined: Tue May 19, 2015 3:30 am
Re: 2.8" TFT Skecth hangs up freezes
Thank you very much. The solution was to change the PIN . Conflict SPI ;-)
And your code and project was very interesting for me. I'm a sailor , too.
Regards
Michal
******************************
And your code and project was very interesting for me. I'm a sailor , too.
Regards
Michal
******************************
adafruit_support_rick wrote:You're using hardware SPI pins for the keypad. That's a conflict.Choose some different pins for the row pins. Hardware SPI on the Mega is on both the ICSP header and on pins 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS).Code: Select all
byte rowPins[ROWS] = {53,51,49,47}; //connect to the row pinouts of the keypad
Please be positive and constructive with your questions and comments.